How to display dynamic tables in AngularJS? - 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.

Related

Angular js ng-repeat dynamic headers , avoid a column

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

angularJS table array

I'm using angularJS to create an table. But it didn't works so great atm.. here my problem.
Code:
appGenerator.controller('customersCtrl', function ($scope) {
$scope.names = [
{"Name": "EMAIL", "StringValue": "dsa#dsada", "Type": "C"},
{"Name": "DESC", "StringValue": "Test","Type": "C"}
];
});
HTML:
<table class="table">
<tr ng-repeat="tableItem in names">
<td ng-repeat="item in tableItem">{{item}}</td>
</tr>
</table>
At the moment I get the whole Item. But I want the the "StringValue".
I tested
<td ng-repeat="item in tableItem">{{item.StringValue}}</td>
But it doesn't works. I don't get any output. What I'm doing wrong?
You should do it like the following;
<table class="table">
<tr ng-repeat="tableItem in names">
<td>{{ tableItem.name }}</td>
<td>{{ tableItem.StringValue }}</td>
<td>{{ tableItem.Type }}</td>
</tr>
</table>
You already iterated the names. Then you should use the object.
Your second ng-repeat is on object's {"key": "value"} pair so ng-repeat should be as follows:
<table class="table">
<tr ng-repeat="tableItem in names">
<td ng-repeat="(key, value) in tableItem">{{key}} {{value}}</td>
</tr>
</table>
Please refer: How can I iterate over the keys, value in ng-repeat in angular

AngularJS search on button click

I have a form where I want the user to be able to enter in search terms into textboxes, and then click a button to search the list. Is it possible to do something like this with ng-repeat and a button click? I'm really new to Angular, and I'm unsure if I can use it for this type of functionality. I have a little bit of code:
HTML
<div>
<input ng-model="filterSearch.address" />
<input ng-model="filterSearch.city" />
<button ng-click="">Search</button>
<table>
<thead>
<tr>
<th>
Address
</th>
<th>
City
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="search in vm.searches | filter: filterSearch">
<td>
{{ search.address }}
</td>
<td>
{{ search.city }}
</td>
</tr>
</tbody>
</table>
Controller:
(function () {
'use strict'
angular
.module('crm.ma')
.controller('AdvancedSearchCtrl', AdvancedSearchCtrl);
function AdvancedSearchCtrl() {
var vm = this;
vm.searches = [
{
"address": "202 This St",
"city": "Columbus"
},
{
"address": "205 That St",
"city": "Dayton"
}
];
}
})();
If anyone could point me in the right direction that would be great. Thanks.
Updated code:
<div>
<input ng-model="searchModel.address" />
<input ng-model="searchModel.city" />
<button ng-click="filterSearch = searchModel">Search</button>
<table>
<thead>
<tr>
<th>
Address
</th>
<th>
City
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="search in vm.searches | filter:{'address': filterSearch.address, 'city': filterSearch.city}">
<td>
{{ search.address }}
</td>
<td>
{{ search.city }}
</td>
</tr>
</tbody>
</table>
You can specify fields to search on like:
<tr ng-repeat="search in vm.searches | filter:{'address': filterSearch.address, 'city': filterSearch.city">
<td>
{{ search.address }}
</td>
<td>
{{ search.city }}
</td>
</tr>
And if you need the on-click to trigger the search, you can just use something like:
ng-click="filterSearch = searchModel"
And change your inputs to use the searchModel variable.

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>

Nested interpolation

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>

Resources