I am trying to do the following in Vue.js
<table>
<tr v-for="item in messages">
<td><router-link to="'/user/' + item.id">{{ item.name }}</router-link></td>
</tr>
</table>
My messages property has an array of objects in it. Each object has an id property, which I want to be appended on to my to attribute. So if I had two items in the messages array with ids of 1 and 2, I would expect to get something like this:
<table>
<tr v-for="item in messages">
<td><router-link to="/user/1">{{ item.name }}</router-link></td>
</tr>
<tr v-for="item in messages">
<td><router-link to="/user/2">{{ item.name }}</router-link></td>
</tr>
</table>
I also tried putting doing {{ message.id }}, but that gives me an interpolation error. How can I get this to render the actual value for message.id in the "to" attribute? The item.name attribute renders as expected.
Just add v-bind: before to
<table>
<tr v-for="item in messages">
<td><router-link v-bind:to="'/user/' + item.id">{{ item.name }}</router-link></td>
</tr>
</table>
Without v-bind: you're literally using 'user' + item.id as value.
For more clarification check this docs section
Related
I am using vue.js library for front-end development.
I came a cross a scenario where my JavaScript method returns a list, which has objects, object's number of properties can change each time after method execution.
example my list can contain these type of objects in 2 different executions.
var obj = {
Name : "John",
2020-Jan: 1,
2020-Jul: 2
}var obj = {
Name: "John",
2020-Jan: 1,
2020-Jul: 2,
2021-Jan: 3,
2021-Jul: 4
}
Since Property name is dynamically changes is there any way to bind to HTML ?
<div >
<table>
<thead>
<tr>
<th v-for ="row in Result.Headers">
{{row}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in Result.Data ">
<td>
{{item.2020-Jan}} // Because don't know the number of properties until run time
</td> // No of <td/>'s can change on no of properties.
<td> // exactly don't know how many <td>'s needed there.
{{item.2020-Jul}}
</td> <td>
{{item.2021-Jan}}
</td>
</tr>
</tbody>
</table>
</div>
Is there way to bind these type of object to fronted in vue.js ?
You need to loop over the item's keys again. This will show all the values in the object
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="(value, key, index) in item">
{{value}}
</td>
</tr>
</tbody>
If you want to filter some of them, for instance check that the keys are valid dates you need to add a v-if and use Date.parse to check for this.
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="(value, key, index) in item" v-if="Date.parse(key) !== NaN">
{{value}}
</td>
</tr>
</tbody>
if u wana show all attr-> u can use this:
<ul v-for="item in Result ">
<li v-for="(value,key,index) in item">{{value}}</li>
</ul>
if u wana show all days u can use v-if and compute to complete youself fillter
<div id="app">
<ul v-for="item in Result" >
<li v-for="(value,key,index) in item" v-if="canShow(key)"> index:{{index}}------ key: {{key}} ------ value:{{value}} </li>
</ul>
</div>
<script>
var vue=new Vue({
el:'#app',
data:{
Result:[{
name: 'SkyManss',
2020-Jan: 1,
2020-Jul: 2
},{
name: 'SkyManss2',
2020-Jan: 1,
2020-Jul: 2,
2021-Jan: 3,
2021-Jul: 4
}]
},
computed:{
canShow(){
return function(skey){
return skey.indexOf('-') > -1;
}
}
}
});
</script>
after some research and some of your suggestions I came up with an answer.
<div>
<table>
<thead>
<tr>
<th v-for ="row in Result.Headers">
{{row}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="row in Result.Headers">
{{item[row]}}
</td>
</tr>
</tbody>
</table>
</div>
Javascript code
this.Result.Headers = Object.keys(result.data[0]);
this.Result.Data = result.data;
But this code only worked for the first time. second time data didn't get updated. So I updated JavaScript code to following code.
Vue.set(self.Result, 'Headers', []);
Vue.set(self.Result, 'Result', []);
this.Result.Headers = Object.keys(result.data[0]);
this.Result.Data = result.data;
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. That I got to know from following post.
vue.js is not updating the DOM after updating the array
Thank You All !!!
Empty row is being added while using header slot in v-data-table from vuetify2
Here's the codepen:
https://codepen.io/satishvarada/pen/rNBjMjE?editors=1010
Vue.component('pivot-table',{
data:()=>({
pivotData:[["2018",1470,1436,1445,0],["2019",1953,1824,0,0]],
pivotHeaders:[[{"value":"Month","colspan":1},{"value":"JAN","colspan":2},{"value":"FEB","colspan":2}],[{"value":"Year","colspan":1},{"value":"Count1","colspan":1},{"value":"Count2","colspan":1},{"value":"Count1","colspan":1},{"value":"Count2","colspan":1}]],
}),
template:
`<v-data-table disable-sort disable-filtering :headers="pivotHeaders" :items="pivotData">
<template v-slot:header="{ props: { headers } }"><thead class="v-data-table-header">
<tr v-for="header in headers" style="background-color:yellow;">
<th v-for="head in header" :colspan="head.colspan">{{head.value}}</th>
</tr></thead>
</template>
<template v-slot:body="{ items }">
<tbody>
<tr v-for="item_row in items"><template v-for="item in item_row">
<td>{{ item }}</td></template>
</tr></tbody></template></v-data-table>`
})
Unexpected row is added below the header. The number of cells in this empty row is as same the number of rows present in the header.
I think the issue is related to you data structure since v-data-table accepts arrays of objects as props not an array of arrays, but your use case could be achieved using v-simple-table component in as follows :
<v-simple-table>
<thead>
<tr v-for="header in pivotHeaders" style="background-color:yellow;">
<th v-for="head in header" :colspan="head.colspan">{{head.value}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item_row in pivotData">
<td v-for="item in item_row">{{ item }}</td>
</tr>
</tbody>
</v-simple-table>
<template v-for="item in job">
<tr>
<td v-for="i in item.stage" :style="getStyle(i.status.name)" title="[[ i.node.name ]]" >
<b>[[ i.node.name ]]</b>
</td>
</tr>
</template>
I am trying to set the title for each td - but instead the title is literally being set to [[ i.node.name ]] as string rather than the value.
note: [[ i.node.name ]] prints the value so I know it is correct, I must be using wrong syntax for the title though.
also side note: I'm using [[ ]] as delimiters in vue.js
You need to remove the brackets from your title and add a colon : in front of the title. Take a look at https://v2.vuejs.org/v2/guide/syntax.html#Attributes
<template v-for="item in job">
<tr>
<td v-for="i in item.stage" :style="getStyle(i.status.name)" :title="i.node.name" >
<b>[[ i.node.name ]]</b>
</td>
</tr>
</template>
I have an issue with angular, I want to use two nested ng-repeat in a data table where the first get the data, and the second get the name of field to be retrieved from the data (retrieved in the first ng-repeat)
here is what I tried to do with code :
<table md-table flex-order-gt-sm >
<thead md-head>
<tr md-row >
//1st : get the name of fields, not a problem
<th md-column ng-repeat="field in fields">{{item.name}}</th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="item in items">
<td md-cell ng-repeat="field in fields" >
//here is the problem I want to get the item that it's field name is field
{{item.{{field}} }}</td>
</tr>
</tbody>
</table>
for example if fields contain :{'a','b','c'}
and items contains {'a':'1','b':'2','c':'3'};
I want for example for the 1st iteration of {{item.{{field}} }} to return 1
Use toString() to retrieve the scope data in an scope object.
<tr md-row ng-repeat="item in items">
<td md-cell ng-repeat="field in fields" >
{{item[field.toString()]}}
</td>
</tr>
Here is the plunker
As an alternative you could also use a filter:
<td md-cell ng-repeat="field in fields | filter: { name: 'field' }">
</td>
You need to get fields collection according to item of items collection after
getFieldsByItem(item)
Then you can get field from fields collection
{{field}}
I have two JSON objects defined in a controller (NotificationsController). One with all the notifications and another one with only the ID of the newest notifications (last 3 days).
Format of object "notifications": (t_notifications)
[{"0":"1","1":"4","2":"14-APR-16","3":"ALERT 1","ID":"1","ID_USER":"4","DATE":"14-APR-16","NOTIFICATION":"ALERT 1!"},{"0":"2","1":"1","2":"07-APR-16","3":"ALERT 2!","ID":"2","ID_USER":"1","DATE":"07-APR-16","NOTIFICATION":"ALERT 2!"},{"0":"3","1":"1","2":"13-APR-16","3":"ALERT 3!","ID":"3","ID_USER":"1","DATE":"13-APR-16","NOTIFICATION":"ALERT 3!"}]
Format of object "newest notifications": (newest_notifications)
[{"0":"1","ID_NEWNOTIF":"1"},{"0":"3","ID_NEWNOTIF":"3"}]
I'm displaying all the notifications in a view like this:
<div class="panel-body" ng-controller="NotificationsCtrl">
<table datatable="ng" class="row-border hover">
<thead>
<tr>
<th><b>ID</b> </th>
<th><b>ID_USER</b> </th>
<th><b>DATE</b> </th>
<th><b>NOTIFICATION</b> </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in t_notifications" ng-class="{selected: data.ID == **TO COMPLETE**>
<td>{{ data.ID }}</td>
<td>{{ data.ID_USER }}</td>
<td>{{ data.DATE }}</td>
<td>{{ data.NOTIFICATION }}</td>
</tr>
</tbody>
</table>
</div>
I would like to know how it is possible to select in my table only the newest notifications - searching through the JSON object newest_notifications - with ng-class?
PS: "selected" is already defined with a blue background color.
Just use a strict filter
... ng-class="{'selected': (newest_notifications | filter : { ID_NEWNOTIF: data.ID } : true).length !== 0 }"
Fiddle - https://jsfiddle.net/dyxf5xqj/
You can use a expression against data.DATE. For example
<tr ng-repeat="data in t_notifications" ng-class="{selected: data.DATE > someDateInThePast}">