I would like to highlight the score if it is equal to 100.
By this I can do this by using if (item.score == 100) return
'style-1';
I would like to highlight the names if they have the same name.
You can see that in json desserts, they have the same name "Frozen"
twice. I want to highlight both of them.
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods: {
customRowClass(item) {
if (item.score == 100) return 'style-1';
// How to highlight duplicate names?
// if (item.name == item.name) return 'style-2';
},
},
data () {
return {
headers: [],
desserts: [
{
name: "Frozen",
score: 66,
},
{
name: "Tom",
score: 100,
},
{
name: "Eclair",
score: 100,
},
{
name: "Frozen",
score: 89,
},
]
}
},
})
.style-1 {
background-color: rgb(215, 215, 44) !important;
}
.style-2 {
background-color: rgb(114, 114, 67) !important;
}
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/vuetify#2.3.4/dist/vuetify.min.css'>
<script src='https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js'></script>
<script src='https://cdn.jsdelivr.net/npm/vuetify#2.3.4/dist/vuetify.min.js'></script>
<div id="app">
<v-data-table
:headers="headers"
:items="desserts"
:item-class="customRowClass"
>
<template #item="{ item }">
<tr :class="customRowClass(item)">
<td>{{ item.name }}</td>
<td>{{ item.score }}</td>
</tr>
</template>
</v-data-table>
</div>
You can use the Array#Filter function and check if there is more than 1 items that check the condition.
this.desserts.filter(x => x.name === item.name).length > 1
Finally, you can order your if to put the most important hilight at the top of the function
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods: {
customRowClass(item) {
if (item.score == 100) return 'style-1';
if (this.desserts.filter(x => x.name === item.name).length > 1) return "style-2"
},
},
data () {
return {
headers: [],
desserts: [
{
name: "Frozen",
score: 66,
},
{
name: "Tom",
score: 100,
},
{
name: "Eclair",
score: 100,
},
{
name: "Frozen",
score: 89,
},
]
}
},
})
.style-1 {
background-color: rgb(215, 215, 44) !important;
}
.style-2 {
background-color: rgb(114, 114, 67) !important;
}
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/vuetify#2.3.4/dist/vuetify.min.css'>
<script src='https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js'></script>
<script src='https://cdn.jsdelivr.net/npm/vuetify#2.3.4/dist/vuetify.min.js'></script>
<div id="app">
<v-data-table
:headers="headers"
:items="desserts"
:item-class="customRowClass"
>
<template #item="{ item }">
<tr :class="customRowClass(item)">
<td>{{ item.name }}</td>
<td>{{ item.score }}</td>
</tr>
</template>
</v-data-table>
</div>
Related
I have a list of users. Click on a specific user the user edit form is populated but the only way I can get a value in the input is by putting the return in the
<input v-model="this.cl.data.USER_RLTNP_SCTY_ACCS_GRP.User_Name" ref=User_Name>
if I do
<input v-model="User_Name "v-bind:value="this.cl.data.USER_RLTNP_SCTY_ACCS_GRP.User_Name">
Nothing appears in the input.
If I use the v-model="this.cl.data....." the value of the user_name is in the input I'm not sure how the value is passed to my updateUser() function because normally I would use username = this.User_Name
Using apollo and Graphgl for the querying
<template>
<div>
<v-text-field label="User Name" ref="User_Name" v-model="User_Name" v-bind:value="this.cl.data.USER_RLTNP_SCTY_ACCS_GRP[0].User_Name" id="" placeholder="User Name"></v-text-field>
<v-btn v-on:click="editUser()">Edit</v-btn>
</div>
</template>
<script>
import gql from graphql-tag import { SCTY_ACCS_GRP, SCTY_ACCS_GRP_USER }
from './gqlqueries'
export default {
data: () => ({
users: [],
cl: '',
user_form: false,
user_name: ''
}),
methods: {
editForm: async function(userid){
this.cl = await this.$apollo.query({query : SCTY_ACCS_GRP_USER, variables: {id : userid}})
this.user_form = true
console.log(this.cl)
alert(this.cl.data.USER_RLTNP_SCTY_ACCS_GRP[0].User_Name)
},
editUser(){
this.user_name = this.User_Name
alert(this.user_name)
}
},
mounted: async function() {
this.users = await this.$apollo.query({ query: SCTY_ACCS_GRP })
// console.log(this.users.data.USER_RLTNP_SCTY_ACCS_GRP)
} }
</script>
I would assume the <input v-bind:value="this.cl.data...."> Would populate once The editForm() function is triggered. So how do I get the value of the User_Name when the editUser button is clicked
You could try list rendering.
A little example :
https://jsfiddle.net/L4xu9r5g/7/
var mapp = new Vue({
el: "#app",
data: {
currentuserinfo : undefined,
users: [
{ name: "John Doe", id : 12},
{ name: "Black Jack", id : 932},
{ name: "White Jack", id: 342}
],
userinfo:
[
{ userid: 12, favcolor: 'green', age : 23},
{ userid: 932, favcolor: 'red', age : 11},
{ userid: 342, favcolor: 'blue', age : 12}
]
},
methods:
{
selectuser : function(id)
{
//your query here
this.currentuserinfo = this.userinfo.filter(u => u.userid ==id)[0];
}
}
})
td, th
{
padding: 5px;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<tbody>
<tr>
<th>Name</th>
<th>Select User</th>
</tr>
<tr v-for="user in users" :key="user.id">
<td>{{user.name}}</td>
<td><button #click="selectuser(user.id)">Select User</button></td>
</tr>
</tbody>
</table>
<div v-if="currentuserinfo === undefined">
Please select a user
</div>
<div v-if="currentuserinfo != undefined">
<span>Favourite color : {{currentuserinfo.favcolor}}</span><br/>
<span>Age : {{currentuserinfo.age}}</span><br/>
</div>
</div>
I am trying to write small app that change style depend on key in v-for loop. I can't figure out how to change style.
I want to colorize one as blue, two as green, three as red.
<div id="app">
<table>
<template v-for="(v,k) in tableData">
<tr v-bind:class="background-color: {{k}}">
{{v}}
</tr>
</template>
</table>
</div>
code:
new Vue({
el: '#app',
data: {
tableData:
{
"one": "I am one",
"two": "I am two",
"three": "I am three",
}
}
})
Here is my code https://jsfiddle.net/pevLgf0b/
it's seems that I should use computed property, but I can't understand how to do it in right way.
demo: https://jsfiddle.net/jacobgoh101/y295qd04/
you can use method to get different color dynamically
<script src="https://unpkg.com/vue"></script>
<div id="app">
<table>
<template v-for="(v,k) in tableData">
<tr v-bind:style="style(k)">
<td>
{{v}}
</td>
</tr>
</template>
</table>
</div>
new Vue({
el: '#app',
data: {
tableData: {
"one": "I am one",
"two": "I am two",
"three": "I am three",
}
},
methods: {
style(k) {
switch (k) {
case 'one':
return {
backgroundColor: 'red'
}
case 'two':
return {
backgroundColor: 'green'
}
case 'three':
return {
backgroundColor: 'blue'
}
}
}
}
})
You can add one more data object for colors.
https://jsfiddle.net/pevLgf0b/
new Vue({
el: '#app',
data: {
tableData:
{
"one": "I am one",
"two": "I am two",
"three": "I am three",
},
colorData:{
"one" : "blue",
"two" : "green",
"three" : "red",
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<table>
<template v-for="(v,k) in tableData">
<tr v-bind:style="{ 'background-color': colorData[k] }">
<td>{{v}} </td>
</tr>
</template>
</table>
</div>
In my case this work perfectly,
I've bind class based on the key. I have created a function which will return appropriate class based on the value and the style is applied.
Try this:
<template>
<table>
<template v-for="(v,k) in tableData">
<tr v-bind:class="applyStyle(k)">
<td>{{v}}</td>
</tr>
</template>
</table>
</template>
<script>
export default {
data() {
return {
tableData: {
one: "I am one",
two: "I am two",
three: "I am three"
}
}
},
methods: {
applyStyle(value) {
if (value == "one") {
return "applyRed";
}
if (value == "two") {
return "applyGreen";
}
if (value == "three") {
return "applyBlue";
}
}
}
};
</script>
<style>
.applyRed {
background-color: red;
}
.applyGreen {
background-color: green;
}
.applyBlue {
background-color: blue;
}
</style>
The function "change sort" executed on header item click does not trigger watch, which fetches updated data from server. On the other hand, if I try to execute fetchRecords method at the end of changeSort method, watch gets triggered multiple times
I need to use Vuetify datatables with server side pagination and sorting, and templates for header and items. I implemented code similarly to Vuetify examples: "Paginate and sort server-side" and "Slot: items and headers" from documentation https://vuetifyjs.com/en/components/data-tables#api.
<template>
<v-card class="table-container">
<v-card-title>
<v-text-field
v-model="searchField"
#blur="fetchRecords()"
#keyup.enter="fetchRecords()"
/>
</v-card-title>
<v-data-table
:headers="headers"
:items="applications.applications"
:loading="paginationLoading"
:pagination.sync="pagination"
:total-items="pagination.totalItems"
no-data-text="No results"
>
<template v-slot:headers="props">
<tr>
<th colspan="4">Dane kandydata</th>
<th colspan="4">Dane polecającego</th>
<th colspan="2">Inne</th>
</tr>
<tr>
<th
v-for="header in props.headers"
:key="header.value"
:class="['column',
header.sortable !== false ? 'sortable' : '' ,
pagination.descending ? 'desc' : 'asc',
header.value === pagination.sortBy ? 'active' : '']"
#click="changeSort(header.value, header.sortable)"
>
{{ header.text }}
<v-icon v-if="header.sortable !== false" small>fas fa-sort-up</v-icon>
</th>
</tr>
</template>
<template v-slot:items="props">
<td>{{ props.item.candidateName }}</td>
<td>{{ props.item.candidateSurname }}</td>
<td>{{ props.item.candidateEmail }}</td>
<td>{{ props.item.candidatePhone }}</td>
<td>{{ props.item.referrerName }}</td>
<td>{{ props.item.referrerSurname }}</td>
<td>{{ props.item.referrerEmail }}</td>
<td>{{ props.item.referrerPhone }}</td>
<td class="text-md-center">
<div>
<v-icon>check_circle_outline</v-icon>
</div>
</td>
<td class="text-md-center">
<div>
<v-icon>check_circle_outline</v-icon>
</div>
</td>
</template>
<v-alert v-slot:no-results :value="true" color="error" icon="warning">
Your search for "{{ searchField }}" found no results.
</v-alert>
</v-data-table>
</v-card>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
data () {
return {
announcementId: '',
announcementTitle: '',
searchField: '',
headers: [
{ text: 'Imię', value: 'candidateName' },
{ text: 'Nazwisko', value: 'candidateSurname' },
{ text: 'Email', value: 'candidateEmail', sortable: false },
{ text: 'Telefon', value: 'candidatePhone' },
{ text: 'Imię', value: 'referrerName' },
{ text: 'Nazwisko', value: 'referrerSurname' },
{ text: 'Email', value: 'referrerEmail', sortable: false },
{ text: 'Telefon', value: 'referrerPhone' },
{ text: 'Status', value: 'processed' },
{ text: 'Akcje', value: 'actions', sortable: false },
],
pagination: {
page: 1,
rowsPerPage: 10,
totalItems: 10,
sortBy: '',
descending: false,
},
paginationLoading: false
}
},
computed: {
...mapState([
'applications',
])
},
watch: {
pagination: {
handler(newVal, oldVal){
if(newVal != oldVal){
this.fetchRecords()
}
},
deep: true
}
},
methods: {
...mapActions([
'getApplications',
]),
fetchRecords () {
this.paginationLoading = true
this.getApplications({
announcementId: this.announcementId,
pagination: this.pagination,
search: this.searchField
})
.then(
response => {
this.paginationLoading = false
if(this.pagination.totalItems != response.totalItems) this.pagination.totalItems = response.totalItems
}
)
.catch(
err => {
console.log(err);
}
)
},
changeSort (columnValue, sortable) {
if(sortable === false){
return
}
if (this.pagination.sortBy === columnValue) {
this.pagination.descending = !this.pagination.descending
console.log(this.pagination.descending);
} else {
this.pagination.sortBy = columnValue
this.pagination.descending = false
}
},
editTableItem(item){
console.log(item);
},
onClearSearch() {
this.searchField = ''
this.fetchRecords()
},
}
}
</script>
You should create new object when changing pagination object. Here I use ES6 syntax:
changeSort (columnValue, sortable) {
if(sortable === false){
return
}
if (this.pagination.sortBy === columnValue) {
this.pagination = {
...this.pagination,
descending: !this.pagination.descending
}
console.log(this.pagination.descending);
} else {
this.pagination = {
...this.pagination,
sortBy: columnValue,
descending: false
}
}
}
I am trying to select checkboxes based on some condition.
Select all checkboxes (select all checkboxes)
select all unread (select all unread where data array has status of
unread)
select all read (select all read where data array has status of read)
I am able to select all checkboxes on checkbox click,but unable to select it with links
I also need to fetch the ids of selected checkboxes,so i can perform action against these selected checkboxes.
Can you guys please have a look at this.
new Vue({
el: "#app",
data: {
selected: [],
messages: [{
id: 1,
text: "Learn JavaScript",
status: 'read'
},
{
id: 2,
text: "Learn Vue",
status: 'unread'
},
{
id: 3,
text: "Play around in JSFiddle",
status: 'read'
},
{
id: 4,
text: "Build something awesome",
status: 'unread'
}
]
},
methods: {
},
computed: {
selectAll: {
get: function() {
return this.messages ? this.selected.length == this.messages.length : false;
},
set: function(value) {
var selected = [];
if (value) {
this.messages.forEach(function(item) {
selected.push(item.id);
});
}
this.selected = selected;
}
}
},
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<h2>Message App:</h2>
<table class="table">
All,
Read,
Unread,
<thead>
<tr>
<th><input type="checkbox" v-model="selectAll"></th>
<th>Status</th>
<th>Message</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in messages">
<td><input type="checkbox" v-model="selected" :value="item.id"></td>
<td>{{ item.status }}</td>
<td>{{ item.text }}</td>
</tr>
</tbody>
</table>
</div>
You might want to use click event on a element:
All,
and in javascript code:
methods: {
selectAllHandler() {
if (this.selected.length) {
this.selected = []
} else {
this.selected = this.messages.map(item => item.id);
}
}
}
Your Javascript:
new Vue({
el: "#app",
data: {
selected: [],
messages: [{
id: 1,
text: "Learn JavaScript",
status: 'read'
},
{
id: 2,
text: "Learn Vue",
status: 'unread'
},
{
id: 3,
text: "Play around in JSFiddle",
status: 'read'
},
{
id: 4,
text: "Build something awesome",
status: 'unread'
}
]
},
methods: {
selectAll() {
this.selected = this.messages.map((message) => message.id);
}
}
})
Your HTML:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<h2>Message App:</h2>
<table class="table">
All,
Read,
Unread,
<thead>
<tr>
<th><input type="checkbox" v-model="selectAll"></th>
<th>Status</th>
<th>Message</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in messages">
<td><input type="checkbox" v-model="selected" :value="item.id"></td>
<td>{{ item.status }}</td>
<td>{{ item.text }}</td>
</tr>
</tbody>
I want to make pagination for my table but, when I run, my data does not appear anything. I am confused my code which is wrong perhaps here anyone can help me.
var newVue = new Vue({
el: '#app',
data: {
items: [
{ name: "item #1" }, { name: "item #2" }, { name: "item #3" }, { name: "item #4" },
{ name: "item #5" }, { name: "item #6" }, { name: "item #7" }, { name: "item #8" },
{ name: "item #9" }, { name: "item #10" }, { name: "item #11" }, { name: "item #12" }
],
start: 0,
limit: 2,
pagination: null,
total: 12
},
computed: {
filtered: function(){
return this.items.slice(0, this.limit)
}
},
mounted: function() {
this.limit = parseInt(this.pagination);
},
watch: {
pagination: function() {
this.limit = parseInt(this.pagination);
if(this.limit != this.start && this.start > 0)
this.start = parseInt(this.pagination);
this.limit = this.start + parseInt(this.pagination);
}
},
methods: {
paginate: function(direction) {
if(direction === 'next') {
this.start += parseInt(this.pagination);
this.limit += parseInt(this.pagination);
}
else if(direction === 'back') {
this.limit -= parseInt(this.pagination);
this.start -= parseInt(this.pagination);
}
},
},
filters: {
paginate: function(array, start, limit) {
return array.slice(start, limit);
}
}
});
.pager button {
background: #fff;
border: 1px solid #ddd;
border-radius: 15px;
color: #337AB7;
padding: 7px 13px;
text-align: center;
}
.pager button:hover {
background: #eee;
cursor: pointer;
outline: none;
}
.pager button:disabled {
background: #eee;
color: #bbb;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css" rel="stylesheet"/>
<div id="app">
<table class="table table-striped table-advance table-table-hover table-bordered">
<thead>
<th>Item</th>
</thead>
<tbody>
<tr v-for="item in filtered | paginate">
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-md-12 center">
<ul class="pager">
<li>
<button #click="paginate('previous')" :disabled="start <= 0">
Previous
</button>
</li>
<li>
<button #click="paginate('next')" :disabled="limit >= total">
Next
</button>
</li>
</ul>
</div>
</div>
</div>
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js"></script>
There are few problems with your code, after removing those your code works as can be seen here in fiiddle.
You dont need | paginate with v-for as filtered is computed property which will give you paginated result
<tbody>
<tr v-for="item in filtered | paginate">
<td>{{ item.name }}</td>
</tr>
</tbody>
in filtered you needed to pass correct params in slice method.
computed: {
filtered: function(){
return this.items.slice(this.start, this.limit)
}
},`