nested ng-repeat on table data in angularjs - angularjs

I have a scenario where I need to display a set of data in table using nested ng-repeat. Below is the data set :
var siteRegion = {'Site':[],'Region':[]};
so for each siteRegion I have multiple Site and multiple Regions, that means I have to use three ng-repeats.
I tried using ng-repeat-start and ng-repeat-end but since I am using xhtml 'ng-repeat-end' is expecting '=' character after it.
Table Code :
<table>
<thead>
<tr>
<th>Region</th>
<th>Site</th>
</tr>
</thead>
<tbody ng-repeat="siteRegionInfo in siteRegion">
<tr ng-repeat="siteList in siteRegionInfo.Site">
<td ng-repeat-start="regionList in siteRegionInfo.Region">{{regionList.LABEL}}</td><td ng-repeat-end ></td>
<td>{{siteList.LABEL}}</td>
</tr>
</tbody>
<table>
<thead>
<tr>
<th>Region</th>
<th>Site</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="sitePFInfo in supplierList.SupplierInfo.SiteDependentPF" ng-init="sitePFIndex = $index">
<td class="col-md-2">{{sitePFInfo.Region.LABEL}}</td>
<td class="col-md-2">{{sitePFInfo.Site.LABEL}}</td>
</tr>
<tr ng-repeat-end="ng-repeat-end"></tr>
</tbody>
</table>
Pushing the data via:
for(var j=0; j<selectedSite.length; j++){ sitePF.Site.push({'VALUE':selectedSite[j],'LABEL':$scope.sites[findInJson($scope.sites, "VALUE",selectedSite[j])].LABEL});
}
for(var i=0; i<response.data.results.length; i++){
sitePF.Region.push({'VALUE':response.data.results[i].VALUE,'LABEL':response.data.results[i].LABEL});
}

As the following example proves, if you are just worried that XHTML does not allow no value attributes like ng-repeat-end you can fix that setting the no value attribute to its own name.
In this case ng-repeat-end="ng-repeat-end"
(Notice: the sample below is not written to be a full XHTML compliant sample, it just serves to prove that Angularjs will just ignore the ng-repeat-end attribute value)
angular.module("exampleApp", []).controller("exampleController", function($scope){
$scope.exampleList = [
{colA: "value 1.1", colB: "value 1.2", colC: "value 1.3" },
{colA: "value 2.1", colB: "value 2.2", colC: "value 2.3" },
{colA: "value 3.1", colB: "value 3.2", colC: "value 3.3" }
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="exampleApp" ng-controller="exampleController">
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tr ng-repeat-start="item in exampleList">
<td>{{item.colA}}</td>
<td>{{item.colB}}</td>
<td>{{item.colC}}</td>
</tr >
<tr ng-repeat-end="ng-repeat-end"></tr>
</table>

Related

Multiple (Two) ng-repeats on DataTable in AngularJS

Now I know this is a very common topic but I'm not getting any solutions from the SO questions that I saw till now. I'm currently working on a page that has a DataTable whose data is coming from the controller and by using ng-repeat. However, the case here is that I have to use two ng-repeats on the table.
The JSON is as below:
{
"mainData": [
{
"goal": "ValueOne",
"array": [
{
"LowerKeyOne": "LowerValueOne",
"LowerKeyTwo": "LowerValueOne",
"LowerKeyThree": "LowerValueOne"
},
{
"LowerKeyOne": "LowerValueTwo",
"LowerKeyTwo": "LowerValueTwo",
"LowerKeyThree": "LowerValueTwo"
}
]
},
{
"goal": "ValueTwo",
"array": [
{
"LowerKeyOne": "LowerValueThree",
"LowerKeyTwo": "LowerValueThree",
"LowerKeyThree": "LowerValueThree"
},
{
"LowerKeyOne": "LowerValueFour",
"LowerKeyTwo": "LowerValueFour",
"LowerKeyThree": "LowerValueFour"
}
]
}
]
}
The HTML is as below:
<div class="ibox-content table-responsive">
<div ng-repeat="data in mainData">
<div ng-repeat="cond in data.array">
<table datatable="ng" dt-options="dtOptions" class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr class="table-tr-th">
<th>Header</th>
<th>Other Header</th>
<th>Another Header</th>
<th>Extra Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{data.goal}}</td>
<td>{{cond.LowerKeyOne}}</td>
<td>{{cond.LowerKeyTwo}}</td>
<td>{{cond.LowerKeyThree}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
I've used many different options, like e.g -
Adding ng-repeat="(key, value) in JSONObject" ng-if="key=='mainData'" in <tbody>
Two ng-repeats, one in <tbody> and one in <tr> after <tbody>
Adding <div> tags before <table> and also tried adding before <tbody> (before <tbody> as it was suggested in one of the SO answers on the same topic)
The last option resulted me in the following error -
Error: Expected expression in form of "item in collection[ track
by id]" but got "{0}"
Also tried using limitTo:1 filter, but no resulted no success.
Any helpful comment is welcome. Thanks!
Do you need something like this?
JSFiddle demo
<table ng-repeat="data in data.mainData | limitTo: 1">
<thead>
<tr>
<th>Header</th>
<th>Other header</th>
<th>Another header</th>
<th>Extra header</th>
</tr>
</thead>
<tbody ng-repeat="data in data.mainData track by #index">
<tr ng-repeat="d in data.array">
<td>{{data.goal}}</td>
<td>{{d.LowerKeyOne}}</td>
<td>{{d.LowerKeyTwo}}</td>
<td>{{d.LowerKeyThree}}</td>
</tr>
</tbody>
</table>
Including the specific part of your needs for your comment and answer.
#Mistalis's answer is almost correct, but in my case I had to make a few changes to get the solution and hence have posted this answer.
The solution is -
<table ng-repeat="data in data.mainData | limitTo: 1">
<thead>
<tr>
<th>Header</th>
<th>Other header</th>
<th>Another header</th>
<th>Extra header</th>
</tr>
</thead>
<tbody ng-repeat="data in data.mainData track by #index">
<tr ng-repeat="d in data.array">
<td>{{data.goal}}</td>
<td>{{d.LowerKeyOne}}</td>
<td>{{d.LowerKeyTwo}}</td>
<td>{{d.LowerKeyThree}}</td>
</tr>
</tbody>
</table>
Not yet sure as to why had to write ng-repeat="data in mainData" twice.

Angular create table from objects

From a Rest Api I am getting the following:
{
"headers": ["h1", "h2"],
"body": [{"h1": "a1", "h2":"a2"},
{"h1": "b1", "h2":"b2"},
... ]
}
Now I would like to transform this one into an (orderable table) with angular. I tried:
<table class="table table-striped">
<thead>
<tr>
<th ng-repeat="header in data.headers">{{ header }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="line in data.body">
<td ng-repeat="(key, val) in line">{{ val | date : "dd.MM.yy" }}</td>
</tr>
</tbody>
</table>
Of course it does not work, as objects do not have a key order in javascript.
Is there a simple way to sort the line by headers?
You can do this very simple:
<tr ng-repeat="line in data.body">
<td ng-repeat="header in data.headers">{{ line[header] | date : "dd.MM.yy" }}</td>
</tr>

How to clone and print data in angular

I have a table which prints data from a JSON. Every row have an delete option.
I want to print the deleted data into a new table. I have managed to print data in console but unable to add it into view.
Below is the code:
Controller
$scope.deletedItems = [];
var counter = 0
$scope.removeRow = function (idx) {
console.log(idx);
$scope.TTNdata.splice(idx, 1);
var deletedArray = $scope.TTNdata.slice(idx, 1);
//console.log(deletedArray);
$scope.deletedItems.push(deletedArray);
console.log($scope.deletedItems);
counter++;
$('#counter').html(counter);
};
View:
<table id="deleted-rows" class="">
<thead>
<th>Sr. No</th>
<th>ID</th>
<th>First Name</th>
<th>Second Name</th>
<th>Gender</th>
<th>Email</th>
<th>Image</th>
<th>Remove</th>
</thead>
<tbody>
<tr ng-repeat="item in deletedItems | orderBy:'id'">
<td>{{$index+1}}</td>
<td>{{item.id}} </td>
<td>{{item.first_name}}</td>
<td>{{item.last_name}}</td>
<td>{{item.gender}}</td>
<td>{{item.email}}</td>
<td><img src="{{item.photo}}" alt="{{item.first_name}} {{item.last_name}} photo"></td>
<td class=""> <span style="cursor:pointer" ng-click="removeRow($index)" title="Remove Record" class="glyphicon glyphicon-remove"></span></td>
</tr>
</tbody>
</table>
<table class="table bordered">
<thead>
<tr>
<th>Sr. No</th>
<th>ID</th>
<th>First Name</th>
<th>Second Name</th>
<th>Gender</th>
<th>Email</th>
<th>Image</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in TTNdata | filter:bindtext | orderBy:'id'">
<td>{{$index+1}}</td>
<td>{{data.id}} </td>
<td>{{data.first_name}}</td>
<td>{{data.last_name}}</td>
<td>{{data.gender}}</td>
<td>{{data.email}}</td>
<td><img src="{{data.photo}}" alt="{{data.first_name}} {{data.last_name}} photo"></td>
<td class=""> <span style="cursor:pointer" ng-click="removeRow($index)" title="Remove Record" class="glyphicon glyphicon-remove"></span></td>
</tr>
</tbody>
</table>
Data is printing in console but not in table, every time i click remove it will generate a blank row in deleted table
What I am doing wrong?
Code on github https://github.com/sahilpopli/learningAngular.git
slice returns array, so try $scope.deletedItems.push(deletedArray[0]);
Or try to concatenate the arrays by doing so: $scope.deletedItems = $scope.deletedItems.concat(deletedArray);
A possible thing that you may need to think is that if you going to have paged tables, removing the object from a list with that index could not be a good thing.
My solution to your problem would be this(using the id instead of index). This is just scratch demonstrating a possible way to achieve what is your desire.
Code
angular.module('App', [])
.controller('MyCtrl', ['$scope', function($scope) {
$scope.List = [{
Id: 1,
Name: 'Name1'
}, {
Id: 2,
Name: 'Name2'
}, {
Id: 3,
Name: 'Name3'
}];
$scope.newList = [];
var remove = function(itemId) {
var indexS = $scope.List.filter(function(item, index) {
return item.Id == itemId;
});
if (indexS.length == 1)
$scope.newList.push($scope.List.splice($scope.List.indexOf(indexS[0]), 1)[0])
};
$scope.removeMe = remove;
}]);
Markup
<body ng-app="App" ng-controller="MyCtrl">
<table>
<thead>
<th> Id </th>
<th> Name </th>
</thead>
<tbody>
<tr ng-repeat="item in List">
<td >{{item.Id}}</td>
<td >{{item.Name}}</td>
<td ng-click="removeMe(item.Id)">removeme</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th> Id </th>
<th> Name </th>
</thead>
<tbody>
<tr ng-repeat="item in newList">
<td >{{item.Id}}</td>
<td >{{item.Name}}</td>
</tr>
</tbody>
</table>
Plunker

ng-repeat ($last) element with ng-if

var dataList = [{Id:1,Name: "xyz",Select: true},
{Id:2,Name: "PQR",Select : false }];
var headerList = [{"ID","Name","null"}]
i got this value from server side i can not make any changes in this array list.
My html code is
<table class= "table table-bordered">
<thead>
<tr ng-repeat="header in headerList">
<td ng-if="!$last">
{{header}}
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in dataList">
<td ng-repeat="value in data" ng-if="!$last">
{{value}}
</td>
</tr>
</tbody>
</table>
I don't want to generate "Select" column. code works propely , but when bordered class applies on table one blank column is display i.e "Select"
so that how can i remove this blank column in html DOM ?
You might want to write
<thead>
<tr>
<td ng-if="!$last" ng-repeat="header in headerList">
{{header}}
</td>
</tr>
</thead>
instead of this
<thead>
<tr ng-repeat="header in headerList">
<td ng-if="!$last">
{{header}}
</td>
</tr>
</thead>

setting id of tr while using ng-repeat

I have the following code for generating the table with angularjs dynamically which works fine:
<div class="col-lg-10 col-sm-10 col-xs-10">
<table class="table table-hover">
<thead>
<tr>
<th>item</th>
<th>price</th>
<th>number</th>
<th>edit</th>
</tr>
</thead>
<tbody ng-controller="table">
<tr ng-repeat="x in typesHash ">
<td>{{x.name}}</td>
<td>{{x.price}}</td>
<td>{{x.unit}}</td>
<td>edit</td>
</tr>
<tr>
</tr>
</tbody>
and here is js code:
var app=angular.module('app',[]);
app.controller('table',function($scope){
$scope.typesHash=[
{name : 'lemon', price : 100,unit:2.5 },
{name : 'meat', price : 200,unit:3.3 }];
});
and here is the code fiddle link which works fine:
fiddle
now the problem is I want to assume id for tr as follow: id="tr"+x.name
for example : id="trlemon"
but I do not know how to set it. If I was producing this table with jquery I could easily do that but now with angularjs seems a little bit tricky can anyone help?
You can just use the typical Angular expression {{..}}:
<tr id="tr{{x.name}}" ng-repeat="x in typesHash ">
</tr>

Resources