setting id of tr while using ng-repeat - angularjs

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>

Related

ng-repeat deosn't the data from JSON object in the HTML Template

I am trying to render a json as a table in a HTML Template using angularjs ng-repeat element. The script file passes the JSON object, but the ng-repeat wont render the contents of JSON.
I followed the steps from this tutorial link.
https://codepen.io/salva341/pen/aYKmvG
html template section where ng-repeat doesn't render properly
<div ng-controller="WorkflowShowCntrl">
<table class="table striped">
<thead>
<th>Job Name</th>
<th>Job Id</th>
<th>Start Time</th>
<th>Status</th>
</thead>
<tbody>
<tr ng-repeat="ttm in records.response" >
<td>{{ttm.name}} </td>
<td>{{ttm.status}} </td>
<td>{{ttm.name}} </td>
<td>{{ttm.name}} </td>
</tr>
</tbody>
</table>
</div>
app.js
angularjs 1.6.6
$http.get("/api/data-depot/currentjob/list")
.then(function(response) {
$scope.records = {"response":response.data}
$scope.parseItem = function(string)
{
var newString = string.replace(/['\']/g,'');
var jsonFormated = JSON.parse(newString);
return jsonFormated.Message;
}
});
Google chrome inspector : Section inspection screenshot
I have used an angularjs add-on inspector for chrome.
It looks like ttm is the array you want to display for. So I believe your ng-repeat should be more like:
<tr ng-repeat="record in ttm" >
<td>{{record.name}} </td>
<td>{{record.status}} </td>
<td>{{record.name}} </td>
<td>{{record.name}} </td>
ttm being the array, and record being a made-up name for each item in that array.
See: https://www.w3schools.com/angular/ng_ng-repeat.asp
As per your code, your are referencing wrong array name in your HTML binding.
Try this
<div ng-controller="WorkflowShowCntrl">
<table class="table striped">
<thead>
<th>Job Name</th>
<th>Job Id</th>
<th>Start Time</th>
<th>Status</th>
</thead>
<tbody>
<tr ng-repeat="item in records.response.ttm" >
<td>{{item.name}} </td>
<td>{{item.status}} </td>
<td>{{item.name}} </td>
<td>{{item.name}} </td>
</tr>
</tbody>
</table>
</div>
Finally I was was able to achieve what I wanted.
I added ng-bind element to display the data on the html template. That is weird. No of the scope variable gets displayed on the html template without ng-bind element. This investigating that is strange this is happening.
I would like to thank #Thaier Alkhateeb for their valuable comment.
Revised code snippet
<tbody ng-repeat="data in records.response ">
<tr ng-repeat="ttm in data">
<td ng-bind="ttm.name"> </td>
<td ng-bind="ttm.appId"> </td>
<td ng-bind="ttm.created"> </td>
<td ng-bind="ttm.status"> </td>
</tr>
</tbody>

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>

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.

Showing "No data available in table" on sorting and searching data

Below is my table's html code -
<table id="srchTable" style="width:100%; font-size:0.85em;"">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Salary</th>
</tr>
</thead>
<tr ng-repeat="jsonSearchData in searchData">
<td><a id="link1" href="" ng-click="openPopUp()">{{jsonSearchData.Name}}</a></td>
<td>{{jsonSearchData.Age}}</td>
<td>{{jsonSearchData.Salary}}</td>
</tr>
</table>
This is js code for table -
$('#srchTable').dataTable();
I am populating table from json result. Below is the json -
[{
"Name":"Sam",
"Age":"25",
"Salary":"$25000"
},
{
"Name":"Phillip",
"Age":"25",
"Salary":"$30000"
}]
Now when I am clicking on sort icons table is showing No data available in table message. And same thing is happeing when I am trying to search in data table.I tried below code but it didn't worked.
$('#srchTable').dataTable({
"ordering":true,
"searching": true
});
Please help.
In this case jquery is executed before angular render the data .
You don't need to use jquery here. Angular provides filters
and sorting options .
example :
<input type="search" ng-model="query">
<table id="srchTable" style="width:100%; font-size:0.85em;"">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Salary</th>
</tr>
</thead>
<tr ng-repeat="jsonSearchData in searchData | filter : query | orderBy : 'name'">
<td><a id="link1" href="" ng-click="openPopUp()">{{jsonSearchData.Name}} </a></td>
<td>{{jsonSearchData.Age}}</td>
<td>{{jsonSearchData.Salary}}</td>
</tr>
</table>
Be sure to wrap your data rows in <tbody></tbody>.
<table id="srchTable" style="width:100%; font-size:0.85em;"">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Salary</th>
</tr>
</thead>
<tbody><!-- start after </thead> Be sure not to include in loop -->
<tr ng-repeat="jsonSearchData in searchData">
<td><a id="link1" href="" ng-click="openPopUp()">{{jsonSearchData.Name}}</a></td>
<td>{{jsonSearchData.Age}}</td>
<td>{{jsonSearchData.Salary}}</td>
</tr>
</tbody><!-- end after loop -->
</table>

AngularJS ng-include finished

I'm loading a large amount of data using ng-include.
I'd like to know if there is a way to know when a template is "rendered", because sometimes it seems like it's been "frozen", because I want to do a "loading screen" or something.
Thx.
Here's the code
controller code:
$scope.layout = {
current: 'single-table.html'
};
$scope.layout.get = function() {
return $scope.layout.current;
};
templates:
main.html
<div class="btn-group">
<button ng-click="layout.current = 'single-table.html'">Single</button>
<button ng-click="layout.current = 'multiple-table.html'">Multiple</button>
</div>
<div ng-include="layout.get()"></div>
single-table.html
<table class="table table-bordered">
<thead>
<th ng-repeat="column in columns">{{ column.title }}</th>
</thead>
<tbody>
<tr ng-repeat="record in records">
<td ng-repeat="field in record.fields"
ng-controller="FieldController"
ng-class="getClass()">
{{ field.display }}
</td>
</tr>
</tbody>
</table>
multiple-table.html
<table class="table table-bordered" ng-repeat="record in records">
<tbody>
<tr ng-repeat="field in record.fields">
<th>{{ columns[$index].title }}</th>
<td ng-controller="FieldController" ng-class="getClass()">
{{ field.display }}
</td>
</tr>
</tbody>
</table>
EDIT
I'm using version 1.2.0
One solution (probably not the best) is doing this (no ng-include)
<table class="table table-bordered" ng-show="layout.current == 'single-table.html'">
<thead>
<th ng-repeat="column in columns">{{ column.title }}</th>
</thead>
<tbody>
<tr ng-repeat="record in records">
<td ng-repeat="field in record.fields"
ng-controller="FieldController"
ng-class="getClass()">
<span lud-run="{{ field.ng_directive }}"></span>
</td>
</tr>
</tbody>
</table>
<table class="table table-bordered" ng-repeat="record in records" ng-show="layout.current == 'multiple-table.html'">
<tbody>
<tr ng-repeat="field in record.fields">
<th>{{ columns[$index].title }}</th>
<td ng-controller="FieldController" ng-class="getClass()">
<span lud-run="{{ field.ng_directive }}"></span>
</td>
</tr>
</tbody>
</table>
I have only 20 records, but (is not in the code), each cells loads a custom directive depends on the data type (string, date, datetime, image...). This "solution" I think runs the same data twice (ng-show, not ng-if), but when a switch the layout mode there is no "lag".
You can use the onload hook on ng-include to update a variable when the include has finished rendering. If you set it to true on clicking your button, then revert it back to false in onload, you should be able to leverage it to temporarily display a loading screen.

Resources