Angular js ng-repeat dynamic headers , avoid a column - angularjs

On click of a button I get the following Response from Node JS .
[{
"_id": "590998cca8ac14d0c075282c",
"CompID": "0001388D",
"CompName": "ONE"
},
{
"_id": "590998cca8ac14d0c075282qc",
"CompID": "0001388D2",
"CompName": "TWO"
},
{
"_id": "590998cca8ac14d0c07528qq2c",
"CompID": "0001388D23",
"CompName": "Three"
}
]
I am printing this information using Angular JS table ng - repeat
This is my code
My question is , is it possible to skip _id field while printing ??
This is my code
<div ng-app="myapp" ng-controller="FirstCtrl">
<table border="1">
<tr>
<th ng-repeat="(key, val) in collectioninfo[0]">{{ key }}</th>
</tr>
<tr ng-repeat="row in collectioninfo">
<td ng-repeat="column in row">
{{ column }}
</td>
</tr>
</table>
</div>
JSFiddle

you can try with ng-if to avoid showing some elments in ng-repeat.
var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function($scope) {
$scope.collectioninfo = [{
"_id": "590998cca8ac14d0c075282c",
"CompID": "0001388D",
"CompName": "ONE"
},
{
"_id": "590998cca8ac14d0c075282qc",
"CompID": "0001388D2",
"CompName": "TWO"
},
{
"_id": "590998cca8ac14d0c07528qq2c",
"CompID": "0001388D23",
"CompName": "Three"
}
]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myapp" ng-controller="FirstCtrl">
<table border="1">
<tr>
<th ng-repeat="(key, val) in collectioninfo[0]" ng-if="key !== '_id'">{{ key }}</th>
</tr>
<tr ng-repeat="row in collectioninfo">
<td ng-repeat="(key2, val2) in row" ng-if="key2 !== '_id'">
{{ val2 }}
</td>
</tr>
</table>
</div>

Check the jsfiddle here
<table border="1">
<tr>
<th ng-repeat="(key, val) in collectioninfo[0]" ng-show="key != '_id'">{{ key }}</th>
</tr>
<tr ng-repeat="row in collectioninfo">
<td ng-repeat="column in row" ng-hide="column === row._id">
{{ column }}
</td>
</tr>
</table>
I have added a check for the key '_id'.

after you get the response in your angular controller do this :
$scope.datas = [];
//lines of code
.then(function success(response) {
$scope.collectionInfo=response.data.collectionInfo;
for(var i=0;i<$scope.collectionInfo.length;i++){
$scope.index=i;
$scope.datas.push($scope.collectionInfo[i]);
}
//lines of code
});
And on the html page do this :
<div id="DisplayCollection">
<table ng-repeat="x in collectionInfo">
<tr>
<th>
CompID
</th>
<th>
CompName
</th>
</tr>
<tr ng-repeat="y in x track by $index">
<td>{{y.compID[$index]}}</td>
<td>{{y.compName[$index]}}</td>
</tr>
</table>
Given that you have sent the data in form of an array: collectionInfo

Related

How to update the number of columns in an angular table

I want to change the number of columns on modifying a boolean variable.
Check my example (in plnkr):
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('myCtrl', function($scope, $log) {
$scope.debug = {};
$scope.fields = [{
header: "first",
hideField: !$scope.debug.flag
},
{
header: "second"
},
{
header: "third"
},
{
header: "fourth"
},
];
$scope.entries = [{
first: "hello1",
second: "hello2",
third: "hello3",
fourth: "hello4"
}, ]
$scope.myBool = true;
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="myCtrl">
<button id="testButton" class='btn btn-danger' ng-click='debug.flag = !debug.flag'><i class="glyphicon glyphicon-hand-right"></i> refreshFields! debug.flag = {{!!debug.flag}}</button>
<hr>
<h2 class="label label-info">table 1 with property.hideField = true</h2>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields" ng-if="!property.hideField">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields" ng-if="!property.hideField">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
<h4 class="label label-info">table 2 with ng-if => property.hideField = false</h4>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields" ng-if="property.hideField">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields" ng-if="property.hideField">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
<h2 class="label label-info">table 3 without ng-if</h2>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
How to reproduce it:
Click on the red button and the flag will toggle from false to true.
Expected behavior:
Table 1 starts with 3 columns. It should show four after clicking.
Table 2 starts with 1 column. It should show 0 columns after clicking.
Table 3 is just a control table with all the data.
Your heading would become visible if you modified the value of its hideField property. But you're not doing that. You're modifying the value of $scope.debug.flag.
The fact that hideField was initialized with the value of $scope.debug.flag won't magically change hideField every time you change $scope.debug.flag.
Just like if you do
var a = 1;
var b = a;
a = 42;
The value of b will still be 1. Not 42.
Changing the value of $scope.debug.flag won't change the value of hideField. Because, it has already been initialized at the time of controller load. The workaround you can apply here is bind that hideField to a method and evaluate that in your ng-if. Sample below.
JS:
$scope.fields = [{
header: "first",
hideField: function() {
return !$scope.debug.flag;
}
}, {
header: "second"
}, {
header: "third"
}, {
header: "fourth"
}, ];
HTML:
<h2 class="label label-info">table 1 with property.hideField = true</h2>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields" ng-if="!property.hideField()">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields" ng-if="!property.hideField()">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
This is not a clean solution though. But, still will solve your problem.

Display complex json in Angularjs

I would like to display complex json with bollean values, strings and even with arrays. How can I do that?
$scope.options = {
"option_1" : "some string",
"option_2" : true,
"option_3" : [1.123456789, 0.123548912, -7.156248965],
"option_4" : null,
"option_5" : [1234.45678, 75.142012]
}
I use something like this : but I have problem with arrays :
<ul ng-repeat="(key, value) in options">
<li>{{key}}</li>
<span>{{value}}</span>
</ul>
I would like display something like table with keys like headings and values under appropriate keys like this :
option_1 option_2 option_3 ...
some string true 1.123456789
0.123548912
-7.156248965
It should be like this.
app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.isArray = angular.isArray;
$scope.options = {
"option_1": "some string",
"option_2": true,
"option_3": [1.123456789, 0.123548912, -7.156248965],
"option_4": null,
"option_5": [1234.45678, 75.142012]
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th ng-repeat="(key, value) in options">
{{ key }}
</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="(key, value) in options">
{{isArray(value) ? '': value}}
<table ng-if="isArray(value)">
<tr ng-repeat="v in value">
<td>
{{v}}
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</div>

Angular: ng-repeat displaying order in a table

I have an specific requirement where the json data comes like this:
[{Id : "a", Name : "John", age : 50},
{Id : "b", Name : "Bob", age : 40}]
I want to show it in a table using ng-repeat, but in a way where headers come in the first column, as below:
<table>
<tr>
<td>Id</td>
<td>a</td>
<td>b</td>
</tr>
<tr>
<td>Name</td>
<td>John</td>
<td>Bob</td>
</tr>
<tr>
<td>Age</td>
<td>50</td>
<td>40</td>
</tr>
</table>
Is there a way to achieve this using angularjs?
Thanks
Provided you have a controller:
angular.module('MyApp', [])
.controller('MyController', function($scope) {
$scope.data = [
{Id : "a", Name : "John", age : 50},
{Id : "b", Name : "Bob", age : 40}
];
});
Your markup would then be as follows. If the data isn't going to change after it is displayed:
<table>
<tr>
<td>Id</td>
<td ng-repeat="item in ::data">{{::item.Id}}</td>
</tr>
<tr>
<td>Name</td>
<td ng-repeat="item in ::data">{{::item.Name}}</td>
</tr>
<tr>
<td>Age</td>
<td ng-repeat="item in ::data">{{::item.age}}</td>
</tr>
</table>
If the data is going to change after it is displayed, and you want the view to update accordingly, then:
<table>
<tr>
<td>Id</td>
<td ng-repeat="item in data track by $index">{{item.Id}}</td>
</tr>
<tr>
<td>Name</td>
<td ng-repeat="item in data track by $index">{{item.Name}}</td>
</tr>
<tr>
<td>Age</td>
<td ng-repeat="item in data track by $index">{{item.age}}</td>
</tr>
</table>
You can convert your array in an object, then you can use nested ng-repeats in view, as below:
(function() {
"use strict";
angular.module('app', [])
.controller('mainCtrl', function($scope) {
var array = [
{
"Id":"a",
"Name":"John",
"age":50
},
{
"Id":"b",
"Name":"Bob",
"age":40
}
];
// If you're sure that the properties are always these:
$scope.mainObj = {
"Id": [],
"Name": [],
"age": []
};
// If you're unsure what are the properties:
/*
$scope.mainObj = {};
Object.keys(array[0]).forEach(function(value) {
$scope.mainObj[value] = [];
});
*/
// Iterates over its properties and fills the arrays
Object.keys($scope.mainObj).forEach(function(key) {
array.map(function(value) {
$scope.mainObj[key].push(value[key]);
})
});
});
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<table>
<tr ng-repeat="(key, values) in mainObj track by $index">
<td ng-bind="key"></td>
<td ng-repeat="value in values track by $index" ng-bind="value"></td>
</tr>
</table>
</body>
</html>
I hope it helps!

How to display dynamic tables in AngularJS?

I was trying to make a dynamic table that depending how the JSON is made it loads all the data accordingly. So far I have this:
HTML responsible for creating the table:
<div class="container" ng-controller="QuotationsController as vm">
<h2>Quotations</h2>
<p>
Create Quotation
</p>
<table class="table">
<tr ng-repeat="Quotation in vm.Quotations">
<th ng-repeat="(key,val) in Quotation"> {{ key }} </th>
</tr>
<tr ng-repeat="Quotation in vm.Quotations">
<td ng-repeat="(key,val) in Quotation"> {{ val }}</td>
<td>
Edit |
Details |
Delete
</td>
</tr>
</table>
Controller:
(function () {
"use strict";
angular
.module("PPM")
.controller("QuotationsController", ["QuotationsService", QuotationsController]);
function QuotationsController(QuotationsService) {
var vm = this;
vm.Quotations = [
{
"ID": 1,
"Description": "Leaf Rake",
"Name": "GDN-0011",
},
{
"ID" : 2,
"Description": "Garden Cart",
"Name": "GDN-0023",
},
{
"ID": 5,
"Description": "Hammer",
"Name": "TBX-0048",
},
{
"ID": 8,
"Description": "Saw",
"Name": "TBX-0022",
},
{
"ID": 10,
"Description": "Video Game Controller",
"Name": "GMG-0042",
}
];
}
})();
(I have hard-coded the data in the controller for testing purposes only. I will later delete this and make calls to a Web API.)
This gives me the following result:
I don't want the table headers to be repeated for each Quotation that exists. I just want to display it once, but I don't know how to acess the properties without ng-repeat. How can I do this?
Either have your controller loop through the first result or have the html do it. Either way.
Html way
<div class="container" ng-controller="QuotationsController as vm">
<h2>Quotations</h2>
<p>
Create Quotation
</p>
<table class="table">
<tr >
<th ng-repeat="(key,val) in vm.Quotations[0] ">
{{ key }}
</th>
</tr>
<tr ng-repeat="Quotation in vm.Quotations">
<td ng-repeat="(key,val) in Quotation">
{{ val }}
</td>
<td>
Edit | Details | Delete
</td>
</tr>
</table>
You have multiple headers because you used ng-repeat on <tr> element containing <th> elements. Remove ng-repeat.
<table class="table">
<tr>
<th ng-repeat="(key,val) in vm.Quotation[0]"> {{ key }} </th>
</tr>
<tr ng-repeat="Quotation in vm.Quotations">
<td ng-repeat="(key,val) in Quotation"> {{ val }}</td>
<td>
Edit |
Details |
Delete
</td>
</tr>
</table>
Something like that should work.
You probably would like to add ng-if in case there is 0 elements.

angularjs ng-repeat show all list objects

I have this app which lets users create own events and others to register to those events. When creating event you can have as many questions as you like and you can name the questions as you wish. Those will be asked in the registration. App will fetch the names of the questions from the fields and record them in to the entries.
I am having problems to display a table of people that are going to attend. My app is handling one list:
var events = [{
Title: 'Summer Festival',
Date: '12.7.2015',
Location: 'Moon',
Description: Fillertxt,
url: "www.something.com",
MaxEntries: 10,
fields: [{
id: 'choice1',
name: "Gender"
}, {
id: 'choice1',
name: "Address"
}],
entries: []
},
Fields have all the questions and when I add an entry and print it it will show {"Gender":"rr","Address":"rr"} in this case.
The problem is that because I cannot foresee the names of those fields I cannot use ng-repeat and then just say <td>{{event.Gender}}<td>because it might as well be {{event.lifesmeaning}}. So how can i display a nice table with the registration info. Can I fetch those names from the fields somehow? I tried nested ng-repeat but didn't got it to work.
Here is also part of the registration page:
<div class="col-md-4">
<form>
<div class="border-box">
<center>
<h2 class="big">Participate:</h2>
<div data-ng-hide="!listFull()">The registration for this event is full.</div>
<div class="form-group" data-ng-hide="listFull()">
<label for="eventInput">Name</label>
<input style="width: 200px;" type="text" class="form-control" id="eventInput" data-ng-model="newEntry.name">
</div>
<div data-ng-repeat="field in event.fields" data-ng-hide="listFull()">
<div class="form-group">
<label for="{{$index + 1}}">{{field.name}}</label>
<input style="width: 200px;" type="text" class="form-control" id="{{$index + 1}}" data-ng-model="newEntry[field.name]">
</div>
</div>
<button style="width: 100px;" data-ng-click="addEntry()" class="btn btn-primary" data-ng-hide="listFull()">Save</button>
</center>
<br/>
</div>
</form>
<div class="border-box2">
<h2 class="big" align="center">Who is comming:</h2>
<p align="center">{{event.MaxEntries}} can participate.</p>
<table>
<tbody>
<tr data-ng-repeat="entry in event.entries">
<th>{{entry}}</th>
</tr>
</tbody>
</table>
<br/>
<br/>
</div>
</div>
If people are still stumbling upon this post...
1. Simple list of objects
So if you have a list/object of objects that will be populated dynamically, like such:
var list = [
{key1: 'value1'},
{key2: 'value2'}
]
And more key, value pairs will be added going forward (possibly with a push to the list).
In this case, the table body would be constructed as so
<tbody>
<tr ng-repeat="obj in sobjs">
<td ng-repeat="(key, value) in obj">
{{key}}
</td>
<td ng-repeat="(key, value) in obj">
{{value}}
</td>
</tr>
</tbody>
2. That was simple. Instead if you have a more complex structure as so:
var list = [
{'key1': [
{
'skey1':'sval11',
'skey2':'sval12'
},
{
'skey1': 'sval11a',
'skey2': 'sval11b'
}
]},
{'key2': [
{
'skey1':'sval21',
'skey2':'sval22'
},
{
'skey1': 'sval21a',
'skey2': 'sval21b'
}
]}
]
In this case the table body will be constructed as so:
<tbody>
<tr ng-repeat="obj in lobjs">
<td ng-repeat="(key, value) in obj">
{{key}}
</td>
<td ng-repeat="(key, value) in obj">
<table class="table table-bordered">
<thead>
<tr>
<th>
Sub-value 1
</th>
<th>
Sub-value 2
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sobj in value">
<td>
{{sobj.skey1}}
</td>
<td>
{{sobj.skey2}}
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
Plunker working code: https://plnkr.co/edit/r4naGBaYAufhD073oXdw?p=preview
Code snippet with the same code below
function Ctrl($scope) {
$scope.sobjs = [{
'key1': 'value1'
}, {
'key2': 'value2'
}]
$scope.lobjs = [{
'key1': [{
'skey1': 'sval11',
'skey2': 'sval12'
}, {
'skey1': 'sval11a',
'skey2': 'sval11b'
}]
}, {
'key2': [{
'skey1': 'sval21',
'skey2': 'sval22'
}, {
'skey1': 'sval21a',
'skey2': 'sval21b'
}]
}]
}
<!DOCTYPE html>
<html ng-app="">
<head>
<link data-require="bootstrap-css#3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script data-require="angular.js#1.2.7" data-semver="1.2.7" src="https://code.angularjs.org/1.2.7/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="Ctrl">
<h2>Simple List of Objects</h2>
<table class="table table-bordered">
<thead>
<tr>
<th>
Key
</th>
<th>
Value
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="obj in sobjs">
<td ng-repeat="(key, value) in obj">
{{key}}
</td>
<td ng-repeat="(key, value) in obj">
{{value}}
</td>
</tr>
</tbody>
</table>
<h2>List of Objects with a list of objects as values for each key</h2>
<table class="table table-bordered">
<thead>
<tr>
<th>
Key
</th>
<th>
Value
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="obj in lobjs">
<td ng-repeat="(key, value) in obj">
{{key}}
</td>
<td ng-repeat="(key, value) in obj">
<table class="table table-bordered">
<thead>
<tr>
<th>
Sub-value 1
</th>
<th>
Sub-value 2
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sobj in value">
<td>
{{sobj.skey1}}
</td>
<td>
{{sobj.skey2}}
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Write an array of arrays and keep both field and value as element of array. Something like this :
var sample = [ [ sampleField, sampleValue ], [ anotherSampleField , anotherSampleValue ] ];
Now you can iterate using ng-repeat as :
<li ng-repeat = "index in sample"> index[0] : index[1]</li>

Resources