I am creating a table from a Array of JSONObject. And want to enable sorting on column header click. My code is as below.
<table>
<tr ng-repeat-start="record in records | orderBy:columnToOrder:reverse" ng-if="$first">
<td>S.No</td><td ng-repeat="(key,value) in record " ng-click="columnToOrder=key;reverse=!reverse">{{key}}</td>
</tr>
<tr ng-repeat-end >
<td>{{$index+1}}</td><td ng-repeat="(key,value) in record ">{{value}}</td>
</tr>
</table>
My data lookg like
[
{ Count="85923", Property Name="Name 1"},
{ Count="85933", Property Name="Name 2"},
{ Count="85953", Property Name="Name 3"},
{ Count="85973", Property Name="Name 4"}
]
But this code is not working. No error is shown too. Please help me enabling this functionality.
Instead of using the inline, define a method for ordering and use that method during click, since if the variables are defined in inline, the variables are created in the child scope and it would not be available for the parent ng-repeat-start scope.
Controller
$scope.order =function(key) {
$scope.columnToOrder=key;
$scope.reverse= !$scope.reverse
};
HTML
<table>
<tr ng-repeat-start="record in records | orderBy:columnToOrder:reverse" ng-if="$first">
<td>S.No</td><td ng-repeat="(key,value) in record " ng-click="order(key)">{{key}}</td>
</tr>
<tr ng-repeat-end>
<td>{{$index+1}}</td><td ng-repeat="(key,value) in record">{{value}}</td>
</tr>
</table>
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 !!!
I want to create 3 rows based on the columnList which contains 3 types of values i.e caption, shortCaption and columnName.
[{
caption : "First Name",
shortCaption: "FN",
columnName : "FIRST_NAME"
},{
caption : "Last Name",
shortCaption: "LN",
columnName : "LAST_NAME"
}
]
Currently i am generating table cell by iterating columnList with ng-repeat inside each row, here i am using ng-repeat three times which can be cause slowness, Is it possible to use ng-repeat only once at a time and generate all three rows, i also tried to use ng-repeat-start and ng-repeat-end but failed to get the output.
<tr>
<th ng-repeat="column in columnList">
{{column.caption}}
</th>
</tr>
<tr>
<th ng-repeat="column in columnList">
{{column.shortCaption}}
</th>
</tr>
<tr>
<th ng-repeat="column in columnList">
{{column.columnName}}
</th>
</tr>
http://plnkr.co/n0XKuwxOY8e1zjLfYwFI
template.html
<tr ng-repeat="column in columnList">
<td ng-repeat="key in getKeys()" ng-bind="::column[key]"></td>
</tr>
Controller.js
$scope.getKeys = function() {
return ['caption', 'shortCaption', 'columnName'];
}
This uses the ng-repeat twice. If you are sure about the keys of the objects in your column list, you can eliminate the 2nd ng-repeat - but the performance improvement will be negligible unless you have more than 500+ rows.
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 want to apply angular filter for selected object field. I have list of statuses ["waiting", "conform", "rac"], when I select a status it should give information of persons in the table which have that status.
For example if some person ticket conform, then when we select status = conform then only person shown should have conform ticket. Similarly for waiting and rac
Please see the demo and code. It is not working. Please help..
Please see the demo
HTML
<div class="col-md-12">
<table>
<thead>
<tr>Name</tr>
<tr>Status</tr>
</thead>
<tbody >
<tr ng-repeat="person in list| filter: status">
<td>{{person.name}}</td>
<td>{{person.status}}</td>
</tr>
</tbody>
</table>
</div>
Controller:
$scope.status_list=["waiting", "conform", "rac"];
$scope.list = [
{ 'name': 'A',
'status':'waiting'
},
{ 'name': 'B',
'status':'conform'
},
{ 'name': 'C',
'status':'rac'
}
]
Be specific to apply filter over status property rather than directly using filter which will work as contains filter (use compactor set to true for getting exact match). By having contains filter you will get person in list which will have name any one of string which you are searching for status
<tr ng-repeat="person in list| filter: { status: status}: true">
<td>{{person.name}}</td>
<td>{{person.status}}</td>
</tr>
Correct typo of ng-repead to ng-repeat
Demo here
<tr ng-repeat="person in list| filter: status">
You had spelled repeat wrong
I have a directive that creates a list, I'm trying to get the column sorting to work, so I created another directive for sorting the columns.
I get this error in the console while I'm trying to set up an orderby filter on that list:
http://errors.angularjs.org/1.2.0rc1/$injector/unpr?p0=orderbyFilterProvider
here's my plunker: http://plnkr.co/edit/SiBDuylEv1LUCuWCv5Ep?p=preview
here's where the orderby is:
<table>
<tr>
<th ng-repeat="column in columns">
<sort-by onsort="onSort" sortdir=filterCriteria.sortDir sortedby=filterCriteria.sortedBy sortvalue="{{column.value}}">{{column.title}}</sort-by>
</th>
</tr>
<tr ng-repeat="item in set | orderby:sortBy:reverse" ng-class="getClass(item)" ng-click="selectItem(item,$event,$index)" ng-dblclick="details(item)">
<td ng-repeat="column in columns">{{item[column.value]}}</td>
</tr>
</table>