AngularJS: How to make this table with Ng-repeat? - javascript

Please, how can we make the table below with ng-repeat? I do not have permission to change the json structure, so I have to use exactly this way.
My json:
$scope.carCollection = {
'Toyota': [
{
'model': 'Corolla',
'price': '20.000,00',
'tag': ['a', 'b']
},{
'name': 'Hilux',
'price': '31.000,00',
'tag': ['b', 'c']
}
],
'Honda': [
{
'model': 'Civic',
'price': '18.000,00',
'tag': ['c']
}
]
};
And this is the html table:
<table>
<tr>
<td>Producer</td>
<td>Model</td>
<td>Price</td>
<td>Tags</td>
</tr>
<tr>
<td>Toyota</td>
<td>Corolla</td>
<td>20.000,00</td>
<td>a b</td>
</tr>
<tr>
<td>Toyota</td>
<td>Hilux</td>
<td>31.000,00</td>
<td>b c</td>
</tr>
<tr>
<td>Honda</td>
<td>Civic</td>
<td>18.000,00</td>
<td>c</td>
</tr>
</table>
Thanks!!!

You can find the ng-repeat documentation
https://docs.angularjs.org/api/ng/directive/ngRepeat
$scope.friends =
[{name:'John', phone:'555-1212', age:10},
{name:'Mary', phone:'555-9876', age:19},
{name:'Mike', phone:'555-4321', age:21},
{name:'Adam', phone:'555-5678', age:35},
{name:'Julie', phone:'555-8765', age:29}];
<div ng-controller="ExampleController">
<table class="friend">
<tr>
<th>Name</th>
<th>Phone Number</th>
<th>Age</th>
</tr>
<tr ng-repeat="friend in friends">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>
</table>

You can format your data into your controller before render it in your view. Moreover, in my example you will see the :: bindings.
This is the one-time binding, it will stop recalculating the expression once they are stable, so you can improve your page loading by reducing numbers of watchers.
Controller
(function(){
function Controller($scope) {
$scope.carCollection = {
'Toyota': [
{
'model': 'Corolla',
'price': '20.000,00',
'tag': ['a', 'b']
},{
'model': 'Hilux',
'price': '31.000,00',
'tag': ['b', 'c']
}
],
'Honda': [
{
'model': 'Civic',
'price': '18.000,00',
'tag': ['c']
}
]
};
//To format our data
function format(data){
//Return a flatten array
return [].concat.apply([], Object.keys(data).map(function(key){
//Map our data object
return data[key].map(function(elm){
//Add brand property with the current key
elm.brand = key;
//Join tag array value
elm.tag = elm.tag.join(' ');
return elm;
});
}));
}
//Apply our format function
$scope.carCollection = format($scope.carCollection);
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
Then, you will get a flat array, so you just can iterate over it.
HTML
<body ng-app='app' ng-controller='ctrl'>
<table>
<tr>
<td>Producer</td>
<td>Model</td>
<td>Price</td>
<td>Tags</td>
</tr>
<tr ng-repeat="item in ::carCollection">
<td>{{::item.brand}}</td>
<td>{{::item.model}}</td>
<td>{{::item.price}}</td>
<td>{{::item.tag}}</td>
</tr>
</table>
</body>
You can see the Working Plunker

Related

How to remove default order of ng-repeat

How do I stop default sorting inside the ng-repeat for dynamic table data ?
Currently I am getting below order:
Addr | CustomerId | Name
but what I want is below ordering:
CustomerId | Name | Addr
Any Help would me much appreciated.
JS:
app.controller('MyController', function ($scope) {
$scope.Customers = [
{ CustomerId: 1, Name: "John Hammond", Addr:'India'
},
{
CustomerId: 2, Name: "Mudassar Khan", Addr:'India'
},
{
CustomerId: 3, Name: "Suzanne Mathews", Addr:'India'
},
{
CustomerId: 4, Name: "Robert Schidner", Addr: 'India'
}
];
});
HTML:
<table>
<tr >
<th ng-repeat="(key,value) in Customers[0]">{{key}}</th>
</tr>
<tbody ng-repeat="c in Customers">
<tr>
</tr>
</tbody>
</table>
Try this below way. I hope this below snippet result is showing what you want.
angular.module("aaa",[]).controller('MyController', function ($scope) {
$scope.Customers = [
{ CustomerId: 1, Name: "John Hammond", Addr:'India'
},
{
CustomerId: 2, Name: "Mudassar Khan", Addr:'India'
},
{
CustomerId: 3, Name: "Suzanne Mathews", Addr:'India'
},
{
CustomerId: 4, Name: "Robert Schidner", Addr: 'India'
}
];
$scope.keys = Object.keys($scope.Customers[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="aaa" ng-controller="MyController">
<table>
<tr>
<th ng-repeat="key in keys">
{{key}}
</th>
</tr>
<tbody ng-repeat="c in Customers">
<tr>
<td ng-repeat="key in keys">{{c[key]}}</td>
</tr>
</tbody>
</table>
</div>
So objects in JS are inherently unordered. What you can do is just hard code the keys in the header if that will be fixed for that particular table and then print the values in the respective order.
Something like this:
<table>
<tr >
<th>CustomerId</th>
<th>Name</th>
<th>Addr</th>
</tr>
<tbody>
<tr ng-repeat="c in Customers">
<td>{{CustomerId}}</td>
<td>{{Name}}</td>
<td>{{c.Addr}}</td>
</tr>
</tbody>
</table>
Note: I put the ng-repeat on the tr which is probably what you need. I dont think you should put it on the tbody.
Do you mean the sort order of the data or the display order of the columns?
The accepted answer displays the data by the order of the columns as specified, but if you want the data itself sorted then just add a filter to the data like this:
<tbody ng-repeat="c in Customers|orderBy:['CustomerId','Name','Addr']">
This sorts the actual data in the list by the fields specified.

filter just 2 out of 3 columns angularjs

<table>
<tr>
<th>Primary Key</th>
<th>descriptionShort</th>
<th>descriptionLong</th>
</tr>
<tr ng-repeat="terReason in data | filter :({descriptionLong:searchTerm}||{descriptionShort:searchTerm} )">
<td>terReason.primaryKey</td>
<td>terReason.descriptionShort</td>
<td>terReason.descriptionLong</td>
</tr>
</table>
I have this table. How can i make that the filter works only on descriptionLong or descriptionShort and not in primaryKey.
At this time the filter works only on descriptionLong.
DATA sceernshot
I suppose this is what you want:
<input ng-model="searchTerm">
<table>
<tr>
<th>Primary Key</th>
<th>descriptionShort</th>
<th>descriptionLong</th>
</tr>
<tr ng-repeat="terReason in data | filter : myFilter">
<td>{{ terReason.primaryKey }}</td>
<td>{{ terReason.descriptionShort }}</td>
<td>{{ terReason.descriptionLong }}</td>
</tr>
</table>
JS:
$scope.data = [
{
primaryKey: 0,
descriptionShort: 'descriptionShort ZERO',
descriptionLong: 'descriptionLong descriptionLong descriptionLong ZERO'
},
{
primaryKey: 1,
descriptionShort: 'descriptionShort ONE',
descriptionLong: 'descriptionLong descriptionLong descriptionLong ONE'
},
{
primaryKey: 2,
descriptionShort: 'descriptionShort TWO',
descriptionLong: 'descriptionLong descriptionLong descriptionLong TWO'
},
{
primaryKey: 3,
descriptionShort: 'descriptionShort THREE',
descriptionLong: 'descriptionLong descriptionLong descriptionLong THREE'
}
];
$scope.myFilter = function myFilter (value) {
return !$scope.searchTerm || Object.keys(value).some(function (key) {
return key !== 'primaryKey' && value[key].search($scope.searchTerm) !== -1;
});
}
pluner: http://plnkr.co/edit/VMcs064WWbGraULyXQTU?p=preview
try to search by 0 or 1 - nothing displayed, it is not searching by primary key.
<tr ng-repeat="terReason in data | filter :filter1 | filter :filter2 ">
<td>terReason.primaryKey</td>
<td>terReason.descriptionShort</td>
<td>terReason.descriptionLong</td>
</tr>
Why not use multiple filters?

Display data in a table by grouping them horizontally

I have some data that has the following format:
[name:'Name1', speed:'Val1', color:'Val2']
[name:'Name2', speed:'Val4', color:'Val5']
[name:'Name3', speed:'Val6', color:'Val7']
That I want to display in a table like this:
|Name1|Name2|Name3|
______|_____|______
speed |Val1 |Val4 |Val6
color |Val2 |Val5 |Val7
What I tried to do is group my data like this in the controller:
$scope.data = {
speeds: [{
...
},{
...
},{
...
}],
colors: [{
...
},{
...
},{
...
}],
};
But I am not sure what to put inside the empty areas, because all values there represent the values of the 'val1' variable for all Names (Accounts), and my tests until now keep failing.
You can imagine this as some sort of a comparisons matrix, that is used in order to see the all the values of the same variable across different accounts.
How can I represent the data in my model in order for me to successfully display them in a table as explained?
Edit
My difficulty lies in the fact that you create a table by going from row to row, so my html looks something like this:
<table md-data-table class="md-primary" md-progress="deferred">
<thead>
<tr>
<th ng-repeat="header in headers">
{{header.value}}
</th>
</tr>
</thead>
<tbody>
<tr md-auto-select ng-repeat="field in data">
<td ng-repeat="var in field">{{var.value}}</td>
</tr>
</tbody>
</table>
So as you can see I have a loop for each row, and a loop for each value of each row. This would be easier if I wanted to display the data horizontally, but I want the data vertically. So if we where talking about cars, we would have the car models as headers, and their respective characteristics(speed, color, etc) in each row.
If this is your basic structure:
var cols = [{name:'Name1', val1:'Val1', val2:'Val2'},
{name:'Name2', val1:'Val4', val2:'Val5'},
{name:'Name3', val1:'Val6', val2:'Val7'}];
This code
$scope.table = cols.reduce(function(rows, col) {
rows.headers.push({ value: col.name });
rows.data[0].push({ value: col.speed });
rows.data[1].push({ value: col.color });
return rows;
}, {headers:[], data:[[], []]});
will give you this structure for $scope.table:
$scope.table = {
headers : [{
value : "Name1"
}, {
value : "Name2"
}, {
value : "Name3"
}
],
data : [
[{
value : 'val1'
}, {
value : 'val4'
}, {
value : 'val6'
}
],
[{
value : 'val2'
}, {
value : 'val5'
}, {
value : 'val17'
}
]
]
};
<table md-data-table class="md-primary" md-progress="deferred">
<thead>
<tr>
<th ng-repeat="header in table.headers">
{{header.value}}
</th>
</tr>
</thead>
<tbody>
<tr md-auto-select ng-repeat="field in table.data">
<td ng-repeat="var in field">{{var.value}}</td>
</tr>
</tbody>
</table>
You could try this:
HTML
<table ng-app="myTable" ng-controller="myTableCtrl">
<thead>
<tr>
<th ng-repeat="car in cars">{{car.name}}</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="car in cars">{{car.speed}}</td>
</tr>
<tr>
<td ng-repeat="car in cars">{{car.color}}</td>
</tr>
</tbody>
</table>
JS
angular.module("myTable",[])
.controller("myTableCtrl", function($scope) {
$scope.cars = [
{
name:'Name1',
speed:'Val1',
color:'Val2'
},
{
name:'Name2',
speed:'Val4',
color:'Val5'
},
{
name:'Name3',
speed:'Val6',
color:'Val7'
}
]
});
https://jsfiddle.net/ABr/ms91jezr/

Change array of json to a table in angularjs

My json looks like this :
[{"Name":["A","B","C","D","E","F"], "Age":["20","30","40","50","55","60"], "Gender":["M","M","F","M","Unknown","Unknown"]}]
I want a table in angularjs similar to this
Name Age Gender
A 20 M
B 30 M
C 40 F
I could see many example when my json is similar to this :
[
{Name: "A", Age: "20", Gender: "M"},
{Name: "Bag", Age: "30", Gender: "F"},
{Name: "Pen", Age: "40", Gender: "F"}
];
But I don't know how to proceed with my json. Could anyone help with this?
Assuming your property arrays all have the same number of elements (and are properly arranged) you could use the $index of ng-repeat.
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="name in obj.Name">
<td>{{name}}</td>
<td>{{obj.Age[$index]}}</td>
<td>{{obj.Gender[$index]}}</td>
</tr>
</tbody>
</table>
Alternatively (using the same assumption that the data is well-formed), you can just use javascript to consolidate the three separate lists into a single list of person objects. Then you can proceed like the other examples you've seen.
Javascript might look something like this:
$scope.people = [];
obj.Name.forEach(function(name, index) {
people.push(
{
Name: name,
Gender: obj.Gender[index],
Age: obj.Age[index]
});
});
Then a simple ng-repeat on the new people array will work.
...
<tbody>
<tr ng-repeat="person in people">
<td>{{person.Name}}</td>
<td>{{person.Age}}</td>
<td>{{person.Gender}}</td>
</tr>
</tbody>
Try something.
<div ng-repeat="user in users.Name">
Name : {{user}} Age : users.Age[$index] Gender : users.Gender[$index]
</div>
I assume your object is sequenced and arranged
Use lodash _.zip function to arrange them in array, and _.map to convert it to json objects using custom function:
var rows = _.zip(users.Name, users.Age, users.Gender); // [["A",20,"M"],...]
$scope.users =
_.map(rows, function(row) {
return {Name: row[0], Age: row[1], Gender: row[2]}
});
and then iterate them getting values:
<table ng-controller="UsersTableController">
<thead>
<th>NAME</th>
<th>AGE</th>
<th>GENDER</th>
</thead>
<tbody>
<tr ng-repeat="user in users">
<td>{{user.Name}}</td>
<td>{{user.Age}}</td>
<td>{{user.Gender}}</td>
</tr>
</tbody>
</table>
reference: https://lodash.com/docs#zip , https://lodash.com/docs#map

How to populate data in table element?

I am trying to display table data within Angular framework
In my html
<table class='table'>
<tr>
<th ng-repeat='test in tests'>{{test.name}}</th> // it shows correctly...
</tr>
<tr ng-repeat=''> //not sure what to do here...
<td>Item</td><td>Item</td><td>Item</td><td>Item</td>
</tr>
</table>
controller
.controller('BoxCtrl', ['$scope', function ($scope) {
$scope.tests = [
{'name':'header1',
'items':
[
{'name':'Item 1', 'link':'1'},
{'name':'Item 2', 'link':'2'},
{'name':'Item 3', 'link':'3'}
]
},
{'name':'header2',
'items':
[
{'name':'Item 1', 'link':'i1'},
{'name':'Item 2', 'link':'i2'}
]
},
{'name':'header3',
'items':
[
{'name':'Item 1', 'link':'i1'},
{'name':'Item 2', 'link':'i2'}
]
},
{'name':'header4',
'items':
[
{'name':'Item 1', 'link':'I1'},
{'name':'Item 2', 'link':'I2'},
{'name':'Item 3', 'link':'I3'}
]
}
];
}]);
I have no problem display data in TH but not sure how to apply hg-repeat in the tr and td. Can anyone give me a hint for this? Thanks a lot!
You can do something like this:
Example:
<div ng-app="App" ng-controller="ctrl" >
<table class='table'>
<tr>
<th ng-repeat='test in tests'>{{test.name}}</th>
</tr>
<tr ng-repeat='itemsColl in tests'>
<td ng-repeat="item in itemsColl.itemsRow">{{item.name}}</td>
</tr>
</table>
</div>
live Example: http://jsfiddle.net/choroshin/4mD86/
also in this stackoverflow answer you can find more information on dynamic table creation

Categories