How to display array in table using ng-repeat - angularjs

Unlike other JSON data , I have simple arrays of two.
$scope.land = [ elephant, tiger, zebra ];
$scope.water = [ fish , octopus, crab];
I want to put up the array in table using ng-repeat. I tried this but data is not showing in proper format.
<table class="table table-dark">
<thead>
<tr>
<th scope="col">LAND</th>
<th scope="col">WATER</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="l in land track by $index">
<td>{{l}}</td>
<td>fish</td>
</tr>
</tbody>
</table>
EDIT:-
err in data showing vertical in table
enter image description here
new data :-
$scope.land = [ 'tiger in zoo', 'tiger in jungle', 'zebra'];
$scope.water = [ 'fish in pond'];

I think you are trying to display elements of two arrays next to each other (correct me if i'm wrong).
Here is a simple way to do that :
angular.module('myApp', [])
.controller('TestCtrl', function ($scope) {
$scope.land = [ 'tiger in zoo', 'tiger in jungle', 'zebra'];
$scope.water = [ 'fish in pond'];
$scope.combined = [];
var maxLength = ($scope.land.length > $scope.water.length) ? $scope.land.length : $scope.water.length;
//length is to be determined
for(var index = 0; index < maxLength ; index++) {
$scope.combined.push({
land: ($scope.land[index]) ? $scope.land[index] : '',
water: ($scope.water[index]) ? $scope.water[index] : ''
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="TestCtrl">
<table class="table table-dark">
<thead>
<tr>
<th scope="col">LAND</th>
<th scope="col">WATER</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in combined">
<td>{{item.land}}</td>
<td>{{item.water}}</td>
</tr>
</tbody>
</table>
</div>

Related

How to collapse and hide in ng-repeat over table?

So I have a table where I need to show parent deals and on ng-show(clicking parent deal) I want to show child deals.
<table class="table table-hover">
<thead class="thead-dark">
<tr>
<th scope="col">Name</th>
<th scope="col">No_Of_Orders</th>
<th scope="col">Size</th>
<th scope="col">Book_Size</th>
<th scope="col">Remarks</th>
<th scope="col">Price_Guidance</th>
<th scope="col">CONTROL</th>
<th scope="col">Status</th>
<th scope="col">Current_Cut_Off</th>
<th scope="col">Tenor</th>
<th scope="col">Book</th>
<th scope="col">ORDCOLUMN</th>
<th scope="col">PKEY</th>
<th scope="col">Save</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="parentDeal in parentDeals track by $index" ng-click="childShow(parentDeal.PKEY)">
<td>{{parentDeal.Name}}</td>
<td>{{parentDeal.No_Of_Orders}}</td>
<td>{{parentDeal.Size}}</td>
<td>{{parentDeal.Book_Size}}</td>
<td>{{parentDeal.Remarks}}</td>
<td>{{parentDeal.Price_Guidance}}</td>
<td>{{parentDeal.CONTROL}}</td>
<td>{{parentDeal.Status}}</td>
<td>{{parentDeal.Current_Cut_Off}}</td>
<td>{{parentDeal.Tenor}}</td>
<td>{{parentDeal.Book}}</td>
<td>{{parentDeal.ORDCOLUMN}}</td>
<td>{{parentDeal.PKEY}}</td>
<td>{{parentDeal.Save}}</td>
<tr ng-repeat="childDeal in childDeals track by $index" ng-show = "childRowShow_{{childDeal.PKEY}}">
<td>{{childDeal.Name}}</td>
<td>{{childDeal.No_Of_Orders}}</td>
<td>{{childDeal.Size}}</td>
<td>{{childDeal.Book_Size}}</td>
<td>{{childDeal.Remarks}}</td>
<td>{{childDeal.Price_Guidance}}</td>
<td>{{childDeal.CONTROL}}</td>
<td>{{childDeal.Status}}</td>
<td>{{childDeal.Current_Cut_Off}}</td>
<td>{{childDeal.Tenor}}</td>
<td>{{childDeal.Book}}</td>
<td>{{childDeal.ORDCOLUMN}}</td>
<td>{{childDeal.PKEY}}</td>
<td>{{childDeal.Save}}</td>
</tr>
</tr>
</tbody>
</table>
This is the basic data:-
$scope.allDeals = [
{
"ORDCOLUMN":"2017-11-17T05:00:00.000000000Z",
"CONTROL":"N",
"PKEY":"UD0000000000720",
"Name":"rajat10 10:19",
"Tenor":"0Y",
"Size":0,
"Price_Guidance":"43%",
"Remarks":"-",
"Book_Size":20,
"Status":"Open",
"No_Of_Orders":2,
"Current_Cut_Off":2.3,
"Book":"Book#ReOffer",
"Save":"Edit"
},
{
"ORDCOLUMN":"2017-11-17T05:00:00.000000000Z",
"CONTROL":"Y",
"PKEY":"UD0000000000720",
"Name":"rajat10 10:19",
"Tenor":"Multi ...",
"Size":0,
"Price_Guidance":"-",
"Remarks":"-",
"Book_Size":20,
"Status":" Open",
"No_Of_Orders":2,
"Current_Cut_Off":2.3,
"Book":"Book#ReOffer",
"Save":"Edit"
},
{
"ORDCOLUMN":"2017-11-17T05:00:00.000000000Z",
"CONTROL":"N",
"PKEY":"UD0000000000720",
"Name":"rajat10 10:19",
"Tenor":"Perp",
"Size":0,
"Price_Guidance":"19%",
"Remarks":"-",
"Book_Size":0,
"Status":"Open",
"No_Of_Orders":2,
"Current_Cut_Off":2.3,
"Book":"Book#ReOffer",
"Save":"Edit"
}
....and so on
]
So, this data can be grouped by PKEY and parent object has control - "Y", child object has control - "N". Note:- There can be objects where there is only parent deal with no child deals.
In my app.js:-
$scope.parentDeals = $scope.allDeals.filter(function (item,index) {
return item.CONTROL == "Y";
});
$scope.childDeals = [];
$scope.childShow = function (PKEY) {
if($scope["childRowShow_"+PKEY]){
$scope["childRowShow_"+PKEY] = false;
}
else{
$scope.childDeals = $scope.allDeals.filter(function (item,index) {
if(item.PKEY == PKEY && item.CONTROL == "N"){
return item;
}
});
$scope["childRowShow_"+PKEY] = true;
}
};
Here, I am making two arrays:- parentDeals and childDeals.
Right now, I am applying ng-repeat on the separate row so, child deals are showing after all parent deals. Is there any way I can show them below the respective parent deals or can apply a different solution?
Yes, with ng-repeat-start and ng-repeat-end, we can explicitly specify the starting and ending for ng-repeat. So, instead of using the ng-repeat directive on one single DOM element, we can specify the ng-repeat-start and ng-repeat-end on any two DOM elements.
For eg.
<div ng-app="app">
<table ng-controller="TestController">
<tr ng-repeat-start="d in data">
<td><strong>{{d.name}}</strong></td>
</tr>
<tr ng-repeat-end>
<td>{{ d.info }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('app', []);
app.controller('TestController', function ($scope) {
$scope.data = [{
name: 'ABC',
info: 'Bangalore'
}, {
name: 'XYZ',
info: 'Mumbai'
}];
});
</script>

How to populate a table with AngularJS

I have a table:
<h4>Table of Results</h4>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Value</th>
<th scope="col">Sub-Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in results>
<td>{{object.field1}}</td>
<td>{{object.field2}}</td>
<td>{{object.field3}}</td>
</tr>
</tbody>
</table>
And I have a controller:
angular.module('app', [])
.controller("Ctrl",['$scope', function ($scope) {
$scope.BtnIndex;
$scope.results = [];
$scope.selectBtn = function (index, model1, model2) {
if (index == $scope.BtnIndex)
$scope.BtnIndex = -1;
else {
$scope.newItem = {
field1 : model2.name,
field2 : model2.val,
field3 : model1.name
}
$scope.results.push($scope.newItem);
}
};
I can't work out why the table is not populating with the data. I have checked the console and it is showing the data, as I expected, but it just isn't populating the table.
I'm expecting the answer to be right in front of me, but I can't see it.
You are not binding the results variable to the scope
Please change
results = [];
to this
$scope.results = [];
Here's the official information from Angular themselves
Scope is the glue between application controller and the view. During the template linking phase the directives set up $watch expressions on the scope. The $watch allows the directives to be notified of property changes, which allows the directive to render the updated value to the DOM.
This works - Plunker
JS
$scope.results = [];
$scope.selectBtn = function (index, model1, model2) {
if (index == $scope.BtnIndex)
$scope.BtnIndex = -1;
else {
$scope.newItem = {
field1 : index,
field2 : model1,
field3 : model2
}
$scope.results.push($scope.newItem);
}
}
Markup
<body ng-controller="MainCtrl">
<button ng-click='selectBtn("hello", "world", "today")'>Press me</button>
<h4>Table of Results</h4>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Value</th>
<th scope="col">Sub-Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in results">
<td>{{object.field1}}</td>
<td>{{object.field2}}</td>
<td>{{object.field3}}</td>
</tr>
</tbody>
</table>
</body>
It's not possible to see how you are calling $scope.selectBtn in your markup so I've created a simple example from your question.

angular angular-table dynamic header name

I use angular and angular-table to display multiple tables on the same page.
I need to create dynamic table with dynamic header and dynamic content.
Plunkr her
This is a working example with non dynamic header but I don't find how to make dynamic
The controller :
angular.module('plunker', ['ui.bootstrap',"angular-table","angular-tabs"]);
function ListCtrl($scope, $dialog) {
$scope.cols= ['index','name','email'];
$scope.list = [
{ index: 1, name: "Kristin Hill", email: "kristin#hill.com" },
{ index: 2, name: "Valerie Francis", email: "valerie#francis.com" },
...
];
$scope.config = {
itemsPerPage: 5,
fillLastPage: true
};
}
HTML
<!-- this work -->
<table class="table table-striped" at-table at-paginated at-list="list" at-config="config">
<thead></thead>
<tbody>
<tr>
<td at-implicit at-sortable at-attribute="name"></td>
<td at-implicit at-sortable at-attribute="name"></td>
<td at-implicit at-sortable at-attribute="email"></td>
</tr>
</tbody>
</table>
<!-- this fail ... -->
<table class="table table-striped" at-table at-paginated at-list="list" at-config="config">
<thead></thead>
<tbody>
<tr>
<td ng-repeat='col in cols' at-implicit at-sortable at-attribute="{{col}}"></td>
</tr>
</tbody>
</table>
I am missing some think or it is not possible with this module ?
Did you know another module where you can have dynamic header and pagination ? ( i try also ngTable but have some bug issu with data not being displayed )
Through the below code, you can generate dynamic header
<table class="table table-hover table-striped">
<tbody>
<tr class="accordion-toggle tblHeader">
<th ng-repeat="(key, val) in columns">{{key}}</th>
</tr>
<tr ng-repeat="row in rows">
<td ng-if="!$last" ng-repeat="col in key(row)" ng-init="val=row[col]">
{{val}}
</td>
</tr>
</tbody>
</table>
Angular Script
var app = angular.module('myApp', []);
app.controller('myControl', function ($scope, $http) {
$http.get('http://jsonplaceholder.typicode.com/todos').success(function (data) {
$scope.columns = data[0];
$scope.rows = data;
}).error(function (data, status) {
});
$scope.key = function (obj) {
if (!obj) return [];
return Object.keys(obj);
}
});

How to use ng-repeat for array in array using single ng-repeat

I got a json of table which has columns and rows as below
$scope.table = {
Columns: [{Header:"22-Jul-15",SubHeaders: ["10:33 AM"]}
, {Header:"21-Jul-15",SubHeaders: ["03:40 AM"]}
, {Header:"17-Jul-15",SubHeaders: ["01:05 PM", "12:06 PM"]}]
, Rows:[{Items:[{Value:1},{Value:5},{Value:8},{Value:""}]}
,{Items:[{Value:2},{Value:6},{Value:9},{Value:""}]}
,{Items:[{Value:3},{Value:7},{Value:10},{Value:15}]}]
} //end of table
I want to display Columns.SubHeaders as Sub header row of a table.
Here what I tried, but did not work
<table class="table table-stripped table-bordered">
<thead>
<tr>
<th ng-repeat="col in table.Columns" colspan="{{col.SubHeaders.length}}">{{col.Header}}</th>
</tr>
<tr>
<td class="center text-black" ng-repeat="head in table.Columns[0].SubHeaders">{{head}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in table.Rows">
<td ng-repeat="item in row.Items">
{{item.Value}}
</td>
</tr>
</tbody>
</table>
I used head in table.Columns[0].SubHeaders just to show it is working for hard-coded index value.
How can I achieve this using single ng-repeat? I can use two ng-repeats but it will lead to unnecessary html markup.
Here is the complete fiddle
I created this fiddler (forked from yours):
https://jsfiddle.net/b50hvzef/1/
The idea is to join the subheaders as they are they actual columns:
<td class="center text-black" ng-repeat="head in subHeaders">{{head}}</td>
and the code looks like this:
var app = angular.module("app",[]);
app.controller("MyController", function ($scope, $http) {
$scope.table = {
Columns: [{Header:"22-Jul-15",SubHeaders: ["10:33 AM"]}
, {Header:"21-Jul-15",SubHeaders: ["03:40 AM"]}
, {Header:"17-Jul-15",SubHeaders: ["01:05 PM", "12:06 PM"]}]
,Rows:[{Items:[{Value:1},{Value:5},{Value:8}]}
,{Items:[{Value:2},{Value:6},{Value:9}]}
,{Items:[{Value:3},{Value:7},{Value:10}]}]
};
var subHeaders = [];
$scope.table.Columns.forEach(function(col) {
col.SubHeaders.forEach(function(subHeader) {
subHeaders.push(subHeader);
});
});
$scope.subHeaders = subHeaders;
});
Note that there is still a mismatch between columns and data. But it's up to you how to solve it.
Hope this helps.

Dynamically setting new ng-model when pushing model to array

Can't figure out how to dynamically add a new model whenever a new row is added to the page. For example, the input select box ng-model= infos.rigBonusInfo.rigName is used for all select box I've added to the page. I would like to have a different model attached to a each select inputs. I tried using ng-model= infos.rigBonusInfo.rigName[rigBonus] but it doesn't work for the rates as the same model gets attachedto each rate field.
Pretty much what I want to do is to bind a new model whenever a new row gets pushed into the array.
Currently, I have a nested table which is the following:
<div class="col-lg-5">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Rig</th>
<th>Rig Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="rig in rigs">
<td>{{ $index + 1 }}</td>
<td>{{ rig.name }}</td>
</tr>
</tbody>
</table>
</div>
<div class="col-lg-2"></div>
<div class="col-lg-5">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Bonus Name</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="bonus in create.rigBonusRates">
<td>{{ bonus.rateName }}</td>
<td>{{ bonus.rate }}</td>
</tr>
</tbody>
</table>
</div>
<table>
<thead>
<tr>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="rigDate in rigDateList track by $index">
<td><input ui-date="datepickerOptions" ng-model="date" /></td>
<td>
<table>
<thead>
<tr>
<th>Rig</th>
<th>Rate1</th>
<th></th>
<th>Rate2</th>
<th></th>
<th>Rate3</th>
<th></th>
<th>Rate4</th>
<th></th>
<th>Comments</th>
</tr>
</thead>
<tr ng-repeat="rigBonus in rigBonusList track by $index">
<td><select ng-options="rig as rigs.indexOf(rig) + 1 for rig in rigs" ng-model="infos.rigBonusInfo.rigName[rigBonus]" ></select></td>
#for (var i = 1; i < 5; i++)
{
<td><select ng-options="rigBonus.rateName for rigBonus in create.rigBonusRates" ng-model="infos.rigBonusInfo.rate#(#i)"></select></td>
<td><input type="text" ng-disabled="infos.rigBonusInfo.rate#(#i).rateName != 'Special' " ng-model=infos.rigBonusInfo.rate#(#i).rate /></td>
}
<td><input ng-model="info.rigBonusInfo.comments" /></td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<div>
<button type="button" ng-click="add()">Add</button>
<button type="button" ng-click="addDate()">Add Date</button>
</div>
My current controller has the following:
angular.module('RigBonus').controller('rigCreateController', ['$scope', '$http', 'PayPeriodService', 'RigLegendService',
function ($scope, $http, PayPeriodService, RigLegendService, RigBonusRateService) {
$scope.rigs = RigLegendService.getRigLegend();
$scope.datepickerOptions = {
orientation: 'top',
startDate: PayPeriodService.getStartDate(),
endDate: PayPeriodService.getEndDate()
};
$http({ method: 'GET', url: '/Home/CreateData' }).success(function (data) {
$scope.create = data;
$scope.infos = {
rigBonusInfo: {
rigName: $scope.rigs[0],
rate1: $scope.create.rigBonusRates[0],
rate2: $scope.create.rigBonusRates[0],
rate3: $scope.create.rigBonusRates[0],
rate4: $scope.create.rigBonusRates[0],
comment: ""
}
};
$scope.add = function () {
$scope.rigBonusList.push();
};
$scope.addDate = function(){
$scope.rigDateList.push("");
};
});
$scope.rigBonusList = [$scope.rigBonusInfo];
$scope.rigDateList = [];
$scope.submit = function () {
$http.post('/Home/Create', {model: "testing"} );
};
}]);
I figured out my issue. My problem was that I was not sure how to generate a new object when a new row of controls are added. Think I should have put something on fiddleJS to help people visualize it better. As a static model was used ($scope.infos) as ng-model, the same model was used for two different controls which I don't want. I want all my controls to be unique.
The fix was to create the object I had in mind which is the following:
$scope.rigDateList = [{
date: "",
rigBonusList: [{}]
}];
So it is an array of objects where the object contains a date and another array of objects.
When I want to push new objects to the inside array which I didn't know I could just create objects like this at the time. I was trying to figure out a way to dynamically create new models ng-model could by declaring them in the controller. I use the following function:
$scope.rigDateList[$scope.rigListIndex].rigBonusList.push({
rigName: "",
rate1: "",
rate2: "",
rate3: "",
comments: ""
});
I also didn't know that I could use elements inside the array from ng-repeat. In the following case, it is rigBonus that I could have used as a model instead of infos model.
<tr ng-repeat="rigBonus in rigDate.rigBonusList track by $index">
<td><select ng-options="rig as rigs.indexOf(rig) + 1 for rig in rigs" ng-model="rigBonus.rigName"></select></td>
and when I want to push to the outside array I use the following:
$scope.rigDateList.push({
date: "",
rigBonusList: [""]
});
$scope.rigListIndex = $scope.rigListIndex + 1;
I use an index to keep track of which object I'm in.
A more closest question and answer is that:
Ng-repeat with dynamic ng-model on input not working
please, take a look.

Resources