Nested interpolation - angularjs

I return an array of people from the database eg,
[
{
id: 1,
name: 'Jim',
address: "123 Test Street",
phone: "999999999"
},
{
id: 2,
name: 'Tom',
address: "123 Test Street",
phone: "888888888"
},
{
id: 3,
name: 'Harry',
address: "123 Test Street",
phone: "012345678"
}
]
my API allows me to select a partial person by setting the fields parameter
eg for this example,
&fields=id,name,address,phone
full url for this example,
?q=&fields=id,name,address,phone&id=1,2,3
I want to be able to dynamically generate a table based on the fields selected.
Something like this,
<table>
<thead>
<tr>
<th ng-repeat="field in fields">[[ field.text ]]</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in people">
<td ng-repeat="field in fields">[[ person.[[ field.id ]] ]]</td>
</tr>
</tbody>
</table>
How can I interpolate the field.id so i can use to it select the key in person.
Edit, I have changed the interpolation characters to [[ & ]].

This line
<td ng-repeat="field in fields">[[ person.[[ field.id ]] ]]</td>
should be
<td ng-repeat="field in fields">[[ person[field.id] ]]</td>

If working with newer versions of Angular, using curly brackets with the nested interpolation in square brackets will do the trick.
<table id="dynamicTable" class="table table-hover" cellspacing="0">
<thead>
<tr>
<th *ngFor="let col of Columns">{{col.column_name}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of Table">
<td *ngFor="let col of Columns">{{row[[col.column_name]]}}</td>
</tr>
</tbody>
</table>

Related

Filter one way binding - inline filter

So I have this
<input type="text" ng-model="search" class="form-control">
And
<tr ng-repeat="city in cities | filter: search">
<td>{{city.description}}</td>
<td>{{(countries | filter : {id:city.idCountry}:true)[0].description}}</td>
</tr>
I have a table and I use the syntax above to display a property (description) which is in a different array of objects (countries), because they have a foreign key relation in the DB. I want to be able to filter by this property (description in countries) existent in this foreign object. I don't know how to accomplish this.
So far I can only filter by properties that are inside the city object.
Example:
city = {
id: 55,
code: "C4589",
description: "NYC",
idCountry: 35
}
country = {
id: 15,
description: "US"
}
The generated HTML is
<input type="text" ng-model="searchF" class="form-control">
<table>
<thead>
<tr>
<th>Description</th>
<th>Code</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ng-binding">Dallas</td>
<td class="ng-binding">C458</td>
<td class="ng-binding">US</td>
</tr>
<tr>
<td class="ng-binding">NYC</td>
<td class="ng-binding">N4596</td>
<td class="ng-binding">US</td>
</tr>
</tbody>
</table>

nested ng-repeat on table data in 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>

ngtable custom filter of $index instead of filtering from dataset

<table ng-table="demo.tableParams" class="table table-condensed table-bordered table-striped">
<tr ng-repeat="row in $data">
<td data-title="'Name'" filter="{name: 'text'}">{{$index}}</td>
<td data-title="'Age'" filter="{age: 'number'}">{{row.age}}</td>
<td data-title="'Money'">{{row.money}}</td>
<td data-title="'Country'" filter="{ country: 'select'}" filter-data="demo.countries">{{row.country}}</td>
</tr>
</table>
</div>
I have {{$index}} to print out the index number. I understand that i can filter easily using filter={age: 'number'} however i cannot do the same for $index as it is not part of the dataset from the JS.
I want to be able to filter $index via a input box instead of automatically filtering upon loading the page.
I don't think you can filter on $index. But you can simply extend you dataset before rendering the table.
Controller
$scope.data = [{
name: 'greg',
age:29,
money: 100.10
}, {
name: 'bob',
age:30,
money: 250.00
}];
for(var i = 0; i < $scope.data.length; i++) {
$scope.data[i].index = i;
}
$scope.table = new NgTableParams({ }, {
dataset: $scope.data
});
View:
<table ng-table="table" class="table table-condensed table-bordered table-striped">
<tr ng-repeat="row in $data">
<td data-title="'Index'" filter="{index: 'number'}">{{row.index}}</td>
<td data-title="'Name'" filter="{name: 'text'}">{{row.name}}</td>
<td data-title="'Age'" filter="{age: 'number'}">{{row.age}}</td>
<td data-title="'Money'" filter="{money: 'number'}">{{row.money}}</td>
</tr> </table>

Angular, ng-repeat and rowspan on the same td

Given this data:
this.stuff = [
[{title: 'col1', rowspan: 1},{title: 'col2', rowspan: 2}],
[{title: 'col3', rowspan: 1}]
];
How does one generate the following with ng-repeat:
<table border="1">
<tr>
<td rowspan="1">col1</td>
<td rowspan="2">col2</td>
</tr>
<tr>
<td rowspan="1">col3</td>
</tr>
</table>
You could use the following:
<table border="1">
<tr ng-repeat="item in stuff">
<td ng-repeat="obj in item" rowspan="{{ obj.rowspan }}">{{ obj.title }}</td>
</tr>
</table>

how to create a nested grid in ngtable?

I am trying to create a nested grid in my ngtable like this:
<table ng-table="tableParams" class="table">
<tr ng-repeat="user in $data">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
<td data-title="'kids'">
<table ng-table="nestedtableParams" class="table">
<tr ng-repeat="nesteduser in $nesteddata">
<td data-title="'Name'">{{nesteduser.name}}</td>
<td data-title="'Age'">{{nesteduser.age}}</td>
</tr>
</table>
</td>
</tr>
</table>
question is: why is the nested data not displaying? here is a plunkr:
http://plnkr.co/edit/dKTtU89f7z6nQptgEZxN?p=preview
Got this working by adding the data to the $scope: (partial example code)
$scope.nesteddata = [{
name: "Kid Moroni",
age: 50
}, {
name: "Kid Tiancum",
age: 43
}, {
name: "Kid Jacob",
age: 27
}, {
name: "Kid Nephi",
age: 29
}, {
name: "Kid Enos",
age: 34
}];
And then, in the controller functions, refer to these $scope variables:
$scope.nestedtableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: $scope.nesteddata.length, // length of data
getData: function($defer, params) {
$defer.resolve($scope.nesteddata.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
Finally in the markup I left out the $ prefix, since this data is now in the scope:
<table ng-table="tableParams" class="table">
<tr ng-repeat="user in data">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
<td>
<table ng-table="nestedtableParams" class="table">
<tr ng-repeat="user in nesteddata">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
</tr>
</table>
</td>
</tr>
</table>
Working Plunker (Although I doubt that it makes sense to nest grids like this)

Resources