My page is about showing data table from user on shift indicator.
My dashboard.component.html
<table class="table">
<thead>
<tr>
<th *ngFor="let col of tablePresetColumns">
{{col.content}}
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tablePresetData ">
<td *ngFor="let cell of row"> {{cell.content}}</td>
<td *ngFor="let cell of row">
<span class ="dot" [ngClass]="{
'dot-yellow' : cell.content == 'Busy',
'dot-green' : cell.content == 'Idle',
'dot-red' : cell.content == 'Overload'}">
</span>
</td>
</tr>
</tbody>
</table>
My example data :
tablePresetColumns = [{ id: 1, content: "Username" }];
tablePresetData = [
[{ id: 1, content: "Adiet Adiet" }, { id: 2, content: "Idle" }],
[{ id: 1, content: "Andri Irawan" }, { id: 2, content: "Idle" }],
[{ id: 1, content: "Ari Prabudi" }, { id: 2, content: "Idle" }]
];
How should i do to :
removes the status in the page that I want to display, so it just
appear username and color indicator
I've tried to change *ngFor into this (with index 1) :
<td *ngFor="let cell of row"> {{cell.content[1]}}
but it didn't works at all
Try
<td> {{row[0].content}}</td>
instead of
<td *ngFor="let cell of row"> {{cell.content[1]}}
How about this
<table class="table">
<thead>
<tr>
<th *ngFor="let col of tablePresetColumns">{{col.content}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tablePresetData">
<ng-container *ngFor="let cell of row, let i = index">
<td *ngIf="i == 0">{{cell.content}}</td>
<td *ngIf="i == 0">
<span
[ngClass]="{
'dot-yellow' : row[1].content == 'Busy',
'dot-green' : row[1].content == 'Idle',
'dot-red' : row[1].content == 'Overload'}"
>
</span>
</td>
</ng-container>
</tr>
</tbody>
</table>
See here for a live example: https://codesandbox.io/s/7y2r69992j
Note
I think your data structure is a but awkward and un-semantic. It would be better, if your data would look like this:
tablePresetColumns = ["Username", "Status"];
tablePresetData = [
{username: "Adiet Adiet", status: "Idle"},
{username: "Andri Irawan", status: "Busy" },
{username: "Ari Prabudi", status: "Overload" }
];
So you could show the table like this
<table class="table">
<thead>
<tr>
<th *ngFor="let col of tablePresetColumns">{{col}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tablePresetData">
<td>{{ row.username }}</td>
<td>
<span [ngClass]="{
'dot-yellow' : row.status == 'Busy',
'dot-green' : row.status == 'Idle',
'dot-red' : row.status == 'Overload'
}">
</span>
</td>
</tr>
</tbody>
</table>
Much easier to read and maintain.
Also a live example: https://codesandbox.io/s/o27pv052z
You need to use .map on tablePresetData and have some changes on object structure
angular code here:
tablePresetColumns: any = [
{thTitle:"id", thWidth:'30px'},
{thTitle:"Username", thWidth:'160px'},
{thTitle:"Status", thWidth:'100px'},
{thTitle:"", thWidth:'60px'}
];
tablePresetData: any = [
{ id: 1, Username: "Adiet Adiet", status: "Idle" },
{ id: 2, Username: "Andri Irawan", status: "Overload" },
{ id: 3, Username: "Ari Prabudi", status: "Busy" }
];
constructor() {}
ngOnInit() {
this.tablePresetData.map((item: any) => {
if (item.status === "Busy") {
item["className"] = "dot-yellow";
}
if (item.status === "Idle") {
item["className"] = "dot-green";
}
if (item.status === "Overload") {
item["className"] = "dot-red";
}
});
console.log("this.tablePresetData", this.tablePresetData);
}
Html code
<table>
<thead>
<tr>
<th
*ngFor="let tableHd of tablePresetColumns"
[width]="tableHd.thWidth" >
{{tableHd.thTitle}}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let tableCol of tablePresetData">
<td>{{tableCol.id}}</td>
<td>{{tableCol.Username}}</td>
<td>{{tableCol.status}}</td>
<td>
<span [ngClass]='tableCol.className' class="circle"></span>
</td>
</tr>
</tbody>
</table>
CSS Class -
.circle{border-radius: 10px; display: inline-block; height: 10px; width: 10px; }
.dot-yellow{background-color: yellow;}
.dot-green{background-color:green;}
.dot-red{background-color:red;}
Related
I have a table built in Angular 8. I am not using Material UI.
I want to reorder the columns in the table using JSON. Is there any way that could be done?
My Angular table code is like below:
<table>
<thead class="thead-light">
<tr>
<th *ngFor="let data of tableHeaders">
{{ data.value }}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of transactions ">
<td>{{ data.firstName }}</td>
<td>{{ data.regNo }}</td>
<td>{{ data.course }}</td>
</tr>
</tbody>
</table>
My tableheader json:
this.tableHeaders = [
{
"id": 'first_name',
"value":"Name",
},
{
"id": 'reg_no',
"value":"Reg No"
},
{
"id": 'course_name',
"value":"Course"
},
]
While I am able to change the order of the table headers by setting an id and sorting the array - tableHeaders, but how do I do the same for the td?
Any help would be appreciated.
You need to modify header and content's key to make it relate together something like
Full example: Stackblitz
.ts
this.tableHeaders = [
{
"id": 'first_name',
"value":"Name",
"key": "firstName"
},
{
"id": 'reg_no',
"value":"Reg No",
"key":"regNo"
},
{
"id": 'course_name',
"value":"Course",
"key": "course"
},
]
.html
<table>
<thead class="thead-light">
<tr>
<th *ngFor="let data of tableHeaders">
{{ data.value }}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of transactions">
<td *ngFor="let header of tableHeaders">
{{ data[header.key] }}
</td>
</tr>
</tbody>
</table>
I have table:
<table class="table table-condensed">
<thead>
<tr>
<th>id</th>
<th>task</th>
<th>date</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tasks">
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.id}}</td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.text}}<button v-if="showBatton">Test</button></td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.date_current}}</td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"><button v-if="showBatton">Test</button></td>
</tr>
</tbody>
</table>
As intended, the button should appear on the line on which the mouse is hovering.
But now it appears on all visible lines.
Script:
data:{
showBatton:false,
},
showButtonFunction(){
// this.title="dsds2"
console.log("test")
this.showBatton=true;
},
hideButtonFunction(){
this.showBatton=false;
}
How to implement it?
You can do this with css only:
// CSS
tr button {
display: none;
}
tr:hover button {
display: inline-block;
}
// HTML
<tr v-for="row in tasks">
<td span>{{row.id}}</td>
<td span>{{row.text}}<button>Test</button></td>
<td span>{{row.date_current}}</td>
<td span><button>Test</button></td>
</tr>
You can do it Using VueJS Also Like:
<div id="app">
<table class="table table-condensed">
<thead>
<tr>
<th>id</th>
<th>task</th>
<th>date</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tasks" #mouseover="showButtonFunction(row.id)" #mouseleave="hideButtonFunction" :key="row.id">
<td>{{row.id}}</td>
<td>{{row.text}}<button v-show="buttonIndex === row.id">Test</button></td>
<td>{{row.date_current}}</td>
<td><button v-show="buttonIndex === row.id">Test</button></td>
</tr>
</tbody>
</table>
</div>
JS Code:
var vue = new Vue({
el: '#app',
data:{
buttonIndex: false,
tasks: [
{
id: 1,
text: "Hello",
date_current: new Date()
},
{
id: 2,
text: "Hello2",
date_current: new Date()
},
{
id: 3,
text: "Hello3",
date_current: new Date()
}
]
},
methods:{
showButtonFunction(id){
// this.title="dsds2"
this.buttonIndex=id;
},
hideButtonFunction(){
this.buttonIndex=false;
}
}
})
Check this Link :)
Plunker sample
How to hide table column if all json value is null for any property
using angular js
index.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.isArray = angular.isArray;
$scope.data = [{
"Id": null,
"Title": "US",
"Description": "English - United States",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}, {
"Id": null,
"Title": "MX",
"Description": "test",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}, {
"Id": null,
"Title": "SE",
"Description": "Swedish - Sweden",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}]
$scope.cols = Object.keys($scope.data[0]);
$scope.notSorted = function(obj) {
if (!obj) {
return [];
}
return Object.keys(obj);
}
});
index.html
<table border=1 style="margin-top: 0px !important;">
<thead>
<tr>
<th ng-repeat="(k,v) in data[0]">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)">
<table ng-if="isArr" border=1>
<thead>
<tr>
<td>
<button ng-click="expanded = !expanded" expand>
<span ng-bind="expanded ? '-' : '+'"></span>
</button>
</td>
</tr>
<tr>
<th ng-repeat="(sh, sv) in value[0]">{{sh}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sub in value" ng-show="expanded">
<td ng-repeat="(sk, sv) in sub">{{sv}}</td>
</tr>
</tbody>
</table>
<span ng-if="!isArr">{{value}}</span>
</td>
</tr>
</tbody>
</table>
You can filter out columns that have only null values with:
JavaScript
$scope.cols = Object.keys($scope.data[0]).filter(function(col) {
return $scope.data.some(function(item) {
return item[col] !== null;
});
});
and check in template if this column should be rendered:
HTML
<table border=1 style="margin-top: 0px !important;">
<thead>
<tr>
<!-- Iterate over non-null columns -->
<th ng-repeat="col in cols">{{col}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<!-- Use ngIf to hide redundant column -->
<td ng-if="cols.indexOf(prop)>=0" ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" >
...
Plunker
http://plnkr.co/edit/PIbfvX6xvX5eUhYtRBWS?p=preview
So the id is null for every element in the array, then do
<th ng-repeat="(k,v) in data[0]" ng-show="v">{{k}}</th>
and
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" ng-show="value">
plnkr: http://plnkr.co/edit/rra778?p=preview
You need to make use of the cols property you defined in your $scope, but you also need to make sure its correct and responsive. You do that like this:
var colsFromData = function(data) {
var activeCols = {};
data.forEach(function(o) {
Object.keys(o).forEach(function(k) {
if(null == o[k])
return;
activeCols[k] = 1;
})
});
return Object.keys(activeCols);
}
$scope.cols = colsFromData($scope.data);
$scope.$watchCollection('data', colsFromData);
Then in your template, to use the now correct cols array:
...
<thead>
<tr>
<th ng-repeat="k in cols">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" ng-if="cols.indexOf(prop) >= 0">
...
And the updated plunker
I want to generate table contents using json object. I am using ng-repeat to insert multiple rows in a table. But I have to generate table like the following.
--------------
ID | subjects
--------------
| S1
1 | S2
| S3
--------------
| S4
2 | S5
| S6
--------------
my angular code is:
<tr ng-repeat = "user in users">
<td>{{user.id}}</td>
<td>{{user.subject}}</td>
</tr>
my json object is :
user:[
{id:1 ,
subjects:[
{id:1 , name:"eng"}
{id:2 , name:"phy"}
]
},
{id:2 ,
subjects:[
{id:1 , name:"eng"}
{id:3 , name:"math"}
]
}
]
I want to generate html table like this
<table>
<tr>
<td >ID</td>
<td>Sub</td>
</tr>
<tr>
<td rowspan="3">1</td>
<td>S1</td>
</tr>
<tr>
<td>S2</td>
</tr>
<tr>
<td>S3</td>
</tr>
how to insert multiple rows in one column using angular
Use ng-repeat-start and ng-repeat-end. For example:
<tr ng-repeat-start="user in users">
<td rowspan="{{user.subjects.length+1}}">{{user.id}}</td>
</tr>
<tr ng-repeat-end ng-repeat="subject in user.subjects">
<td>S{{subject.id}}</td>
</tr>
Here is a full example:
var app = angular.module('MyApp', []);
app.controller('MyController', function ($scope) {
var users = [{
id: 1,
subjects: [{
id: 1,
name: "eng"
}, {
id: 2,
name: "phy"
}]
}, {
id: 2,
subjects: [{
id: 1,
name: "eng"
}, {
id: 3,
name: "math"
}, {
id: 4,
name: "hist"
},
{
id: 5,
name: "geog"
}]
}];
$scope.users = users;
});
table { border-collapse: collapse; }
td { border: 1px solid Black; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="MyApp" ng-controller="MyController">
<thead>
<tr>
<td>ID</td>
<td>Subjects</td>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="user in users">
<td rowspan="{{user.subjects.length+1}}">{{user.id}}</td>
</tr>
<tr ng-repeat-end ng-repeat="subject in user.subjects">
<td>S{{subject.id}}</td>
</tr>
</tbody>
</table>
Also, working fiddle here: http://jsfiddle.net/donal/r51d5fw5/17/
An alternative version, using nested ng-repeat, can be implemented using a div to display the nested subject information:
<tr ng-repeat="user in users">
<td>{{user.id}}</td>
<td>
<div ng-repeat="subject in user.subjects">S{{subject.id}}</div>
</td>
</tr>
rowspan will do everything you need. Follow this link:
w3schools This is one of the best resources for web development.
Using div u can also do
<div ng-repeat = "user in users">
<div> {{user.id}} </div>
<div ng-repeat = "user1 in users.subjects">
{{user1.id}} : {{user1.name}}
<div>
</div>
Donal's answer is good.
But I edited to show beautiful table:
<table class="table table-bordered table-hover table-height m-b-xs">
<thead>
<tr>
<td>ID</td>
<td>Subjects</td>
<td>name</td>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="user in users">
<td rowspan="{{user.subjects.length}}">key {{user.id}}</td>
<td>S{{ user.subjects[0].id }}</td>
<td>{{ user.subjects[0].name }}</td>
</tr>
<tr ng-repeat-end ng-repeat="subject in user.subjects.slice(1)">
<td>S{{subject.id}}</td>
<td>{{subject.name}}</td>
</tr>
</tbody>
I want to generate html table using angular.I have a json object and i used ng-repeat to add multiple rows. But my table structure is different.
I want to generate table structure like this:
<table>
<tr>
<td >ID</td>
<td>Sub</td>
</tr>
<tr>
<td rowspan="3">1</td>
<td>S1</td>
</tr>
<tr>
<td>S2</td>
</tr>
<tr>
<td>S3</td>
</tr>
</table>
--------------
ID | subjects
--------------
| S1
--------
1 | S2
--------
| S3
--------------
| S4
--------
2 | S5
--------
| S6
--------------
user:[
{id:1 ,
subjects:[
{id:1 , name:"eng"}
{id:2 , name:"phy"}
]
},
{ id:2 ,
subjects:[
{id:1 , name:"eng"}
{id:3 , name:"math"}
]
}
]
my angular code is:
<tr ng-repeat = "user in users">
<td>{{user.id}}</td>
<td>{{user.subject}}</td>
</tr>
I want to know how to generate table structure like above
You need to use ng-repeat-start and ng-repeat-end. For example:
var app = angular.module('MyApp', []);
app.controller('MyController', function ($scope) {
var users = [{
id: 1,
subjects: [{
id: 1,
name: "eng"
}, {
id: 2,
name: "phy"
}]
}, {
id: 2,
subjects: [{
id: 1,
name: "eng"
}, {
id: 3,
name: "math"
}]
}];
$scope.users = users;
});
table { border-collapse: collapse; }
td { border: 1px solid Black; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="MyApp" ng-controller="MyController">
<thead>
<tr>
<td>ID</td>
<td>Subjects</td>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="user in users">
<td rowspan="{{user.subjects.length+1}}">{{user.id}}</td>
</tr>
<tr ng-repeat-end ng-repeat="subject in user.subjects">
<td>S{{subject.id}}</td>
</tr>
</tbody>
</table>
Also, working fiddle here: http://jsfiddle.net/donal/r51d5fw5/17/
Similar to the nested structure of your object, you can nest your ng-repeats like this...
<tr ng-repeat = "user in users">
<td>{{user.id}}</td>
<td ng-repeat="subject in user.subjects">{{subject.name}}</td>
</tr>
I split your JSON and push it into two $scope variable, like the below:
angular.forEach($scope.user, function(user) {
$scope.userDetails.push({
userId: user.id,
});
angular.forEach(user.subjects, function(subject) {
$scope.subjectDetails.push({
userId: user.id,
subjectName: subject.name
});
});
});
In the HTML, I am using filter to filter by user's id.
<table>
<thead>
<tr>
<th style="width: 50px">ID</th>
<th style="width: 75px">Subjects</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in userDetails">
<td><span ng-bind="user.userId"></span>
</td>
<td>
<table>
<tr ng-repeat="sub in subjectDetails | filter: {userId: user.userId}">
<td>
<div ng-bind="sub.subjectName"></div>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
This is also one of the way to achieve this.
Sample Plunker
Here, I'm assuming that you want each user in users (in your JSON object) in one table, so you can do something as follows:
<table ng-repeat="user in users">
<tr>
<td>{{user.id}}</td>
<td>Subjects</td>
</tr>
<tr ng-repeat="subject in user.subjects">
<td>{{subject.id}}</td>
<td>{{subject.name}}</td>
</tr>
</table>
Adjust the html accordingly based on your needs, but this is the basic idea :)
Hope this helps!
add users object in $scope.
$scope.users=[
{id:1 ,
subjects:[
{id:1 , name:"eng"}
{id:2 , name:"phy"}
]
},
{ id:2 ,
subjects:[
{id:1 , name:"eng"}
{id:3 , name:"math"}
]
}
]
Here is the html.
<table border="1">
<tr>
<th> ID </th>
<th> subjects </th>
</tr>
<tr ng-repeat="user in users">
<td>{{user.id}}</td>
<td><table>
<tr ng-repeat="subject in user.subjects">
<td>{{subject.name}}</td>
</tr>
</table></td>
</tr>
</table>
Here is the plunker