I have a JSON array like this:
[
{
"students": {
"Student1": {
"number": "15",
"books": {
"Mystery": [
"Book1",
"Book2"
]
}
},
"Student2": {
"number": "12",
"books": {
"Romance": [
"Book1"
],
"Adventure": [
"Book1",
"Book2"
]
}
},
"Student3": {
"number": "116",
"books": {
}
}
},
"class": "7th Grade",
"school": "High School 1"
}
]
I want to display this data as a table on an Angular1 page in the following manner:
How can I make it so that the columns resize with each other, and how can I have nested ng-repeats as needed?
I tried to have nested tables inside the student, student-number, and books columns, and a table within the table in the books column, but the alignment was always off, and I couldn't get a default value of "No Books" to show up if the "books" field was empty.
Here's a Plunkr of what I've tried so far.
One of possible solutions is to combine several tables(based on $scope.base, $scope.students, $scope.books arrays, that calculated in controller) into one virtual, desired table via float:left(to ensure they located in one row). Docking of rows is provided by setting of their style:height, which depends on number of their children. Direct solution will be very complicated due to complicated html markup of table with rowspan attributes. Also I added second item(items.push(items[0])), to demonstrate, that solution works at case of several items.
angular.module('app', [])
.controller('MyController', ['$scope', function($scope) {
var items = [
{
"students": {
"Student1": {
"number": "15",
"books": {
"Mystery": [
"Book1",
"Book2"
]
}
},
"Student2": {
"number": "12",
"books": {
"Romance": [
"Book1"
],
"Adventure": [
"Book1",
"Book2"
]
}
},
"Student3": {
"number": "116",
"books": {
}
},
"class": "7th Grade",
"school": "High School 1"
}
}
];
items.push(items[0]);
$scope.base = [];
$scope.students = [];
$scope.books = [];
for(var item of items){
var temp = $scope.books.length;
for(var student in item.students){
if(['class', 'school'].indexOf(student) == -1){
var studentV = item.students[student];
$scope.students.push({name:student, number: studentV.number, w: Object.keys(studentV.books).length || 1});
for(var book in studentV.books)
$scope.books.push((book + ':' + JSON.stringify(studentV.books[book])).replace(/"/g, ''));
if(Object.keys(studentV.books).length == 0)
$scope.books.push('No books');
}
}
$scope.base.push({cl: item.students.class, school: item.students.school, w: $scope.books.length - temp});
}
}]);
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
table.left, table.left th, table.left td {
border-right: 0px
}
tr {
text-align:center
}
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app='app' ng-controller="MyController">
<table style='float:left;border-right:0' class='left'>
<thead>
<tr>
<th>School</th>
<th>Class</th>
</tr>
</thead>
<tbody>
<tr ng-repeat='item in base' style='height:{{item.w*30}}px'>
<td>{{item.school}}</td>
<td>{{item.cl}}</td>
</tr>
</tbody>
</table>
<table style='float:left' class='left'>
<thead>
<tr>
<th>Student</th>
<th>Student-number</th>
</tr>
</thead>
<tbody>
<tr ng-repeat='item in students' style='height:{{item.w*30}}px'>
<td>{{item.name}}</td>
<td>{{item.number}}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Books</th>
</tr>
</thead>
<tbody>
<tr ng-repeat='item in books track by $index' style='height:30px'>
<td>{{item}}</td>
</tr>
</tbody>
</table>
</div>
I chose to create hidden nested tables to show more information upon click.
Related
FWIW the HTML angular code is being used in Node-RED in a "template" node.
I have an object composed of circuit boards identified by serial numbers. Each circuit board has two channels that each have their own outputs.
These numbers may change though, for example, some circuit boards in the future will have more channels or I will add another circuit board to the system. So I need the table to be created presumably using nested loops to traverse the message object and pull out whatever information is there at the time.
I successfully used ng-repeat to build individual tables for each circuit board by ng-repeating over the channels of each board. But I would prefer if I had one master table of every single circuit board with every channel so that I can sort that table based on the status of setpoint value for example.
Here is my object:
{ "serialNum": {
"1a": {
"channel": {
"0": {
"status": "running",
"value" : 100.0,
"setpoint": 200.0
},
"1": {
"status": "running",
"value" : 100.1,
"setpoint": 200.1
}
}
},
"2a": {
"channel": {
"0": {
"status": "running",
"value" : 200.0,
"setpoint": 300.0
},
"1": {
"status": "running",
"value" : 200.1,
"setpoint": 300.1
}
}
},
"3a": {
"channel": {
"0": {
"status": "stopped",
"value" : 300.0,
"setpoint": 400.0
},
"1": {
"status": "stopped",
"value" : 300.1,
"setpoint": 400.1
}
}
}
}
}
And here is code I am currently trying (I'm guessing I'm doing a LOT of things wrong here...):
<!DOCTYPE html>
<html>
<style>
table, th , td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
table tr:nth-child(odd) {
background-color: #f1f1f1;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
</style>
<table id="board status" border="1" width = 1000px height = 400px>
<thead>
<tr>
<th>Serial #</th>
<th>Channel #</th>
<th>Status</th>
<th>Value</th>
<th>Setpoint</th>
</tr>
</thead>
<tbody ng-repeat="serial in msg.boardMsg.serialNum">
<tr ng-repeat="channelNum in msg.boardMsg.serialNum[serial].channel">
<td> {{serial}} </td>
<td>{{channelNum}}</td>
<td ng-style = "{color : msg.boardMsg.serialNum[serial].channel[channelNum].status === 'stopped' ? 'red' : 'green'}">
{{msg.boardMsg.serialNum[serial].channel[channelNum].status == "stopped" ? "stopped" : "running"}}
</td>
<td>{{msg.boardMsg.serialNum[serial].channel[channelNum].value</td>
<td>{{msg.boardMsg.serialNum[serial].channel[channelNum].setpoint</td>
</tr>
</tbody>
</table>
I want the table to look like this:
So far my code only gives me the header. Thanks in advance for the help!
Use the (key, value) form of the ng-repeat directive:
<tbody ng-repeat="(serialNum, serialVal) in msg.boardMsg.serialNum">
<tr ng-repeat="(channelNum, channelVal) in serialVal.channel">
<td> {{serialNum}} </td>
<td>{{channelNum}}</td>
<td ng-style = "{color : channelVal.status === 'stopped' ? 'red' : 'green'}">
{{channelVal.status == "stopped" ? "stopped" : "running"}}
</td>
<td>{{channelVal.value}}</td>
<td>{{channelVal.setpoint}}</td>
</tr>
</tbody>
For more information, see
AngularJS ng-repeat Directive API Reference - Iterating Over Object Properties
I have JSON structure like below:
const villages =
{
"lossesOccured":
[
{
"type": "destroyed",
"affectedOn": "humans",
"quantity": 120,
"reliefFund": 100000,
"location": {
"district": "thanjavur",
"villageName": "madukkur",
"pincode": "614903"
}
},
{
"type": "physicalDamage",
"affectedOn": "humans",
"quantity": 250,
"reliefFund": 50000,
"location": {
"district": "thanjavur",
"villageName": "madukkur",
"pincode": "614903"
}
},
]
}
I need help in displaying the JSON data in the form of table like below Using React. Also, need the table row to be added automatically whenever a new element is added in JSON.
<table>
<thead>
<tr>
<th>AffectedOn</th>
<th>Type</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
{
villages.lossesOccured.map(loss => (
<tr>
<td>{loss.affectedOn}</td>
<td>{loss.type}</td>
<td>{loss.quantity}</td>
</tr>
)
}
</tbody>
</table>
JSON response is as below:
{
"clientInfo": [
{
"clientId": "1234",
"clientName": "Test1234"
},
{
"clientId": "4356",
"clientName": "Test4356"
}],
"realTimeClientInfo": [
{
"clientId": "1234",
"clientName": "Test1234",
"Location": "Test1234",
"Designation" :"Test1234"
},
{
"clientId": "4356",
"clientName": "Test7896",
"Location": "Test7896",
"Designation" :"Test7896"
}]
}
I want to fetch the data from the second JSON array.
In client.component.ts invoke the clientService as below:
#Input() clientInfo$: Observable<any>;
constructor(private clientService: ClientService) { }
ngOnInit() { this.clientInfo$ = Observable
.interval(1000)
.startWith(0).switchMap(() =>
this.clientService.getAllInfo()); }
client.service.ts is as below :
getAllInfo(): Observable<ClientInfo[]> {
this.http.get<ClientInfo[]>('http://localhost:8080/api/auth/clientInfo');
In client.component.html
<table class="table table-hover">
<thead>
<tr>
<th *ngFor="let col of clientH">{{ col }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let client of clientInfo$ | async ">
<td *ngFor="let col of clientH"> {{client [col]}}</td>
</tr>
</tbody>
</table>
If the JSON contains only one single array this is working. How we can use the same logic to retrieve some values from first array and some other values from the second array
{
"imports": {
"imported": [
{
"date": "19/9/2014",
"item": [
{
"sn": "3366698",
"type": "Food",
"weight": "10tn."
},
{
"sn": "3366699",
"type": "Eqipment",
"weight": "20kg."
}
]
},
{
"date": "20/9/2014",
"item": [
{
"sn": "3366700",
"type": "Electronics",
"weight": "100pt."
},
{
"sn": "3366701",
"type": "Food",
"weight": "5tn."
}
]
}
]
}
}
I have this json and I am not sure if it's in the right structure. I am trying to render each item type (duplicates included) as table header by the following $.getJSON method:
$scope.items = data.imports.item;
and HTML as:
<table border="1" >
<thead>
<tr>
<th ng-repeat="item in items">{{item.type}}</th>
</tr>
</thead>
</table>
But I couldn't succeed. What am I doing wrong?
EDIT: jsfiddler
I don't see you are using the imported propery at all, try
$scope.items = data.imports.imported;
since imported is your array and not item.
<table border="1" >
<thead>
<tr>
<th ng-repeat="item in items">{{item.type}}</th>
</tr>
</thead>
</table>
Your json ist broken, paste your json here:
http://jsonformatter.curiousconcept.com/
You'll see that data.imports.item would be undefined.
Correct JSON to access would look like:
{
"imports": {
"item": [
{
"sn": "3366698",
"type": "Food",
"weight": "10tn."
},
{
"sn": "3366699",
"type": "Eqipment",
"weight": "20kg."
}
]
}
}
Also access your data after:
<th ng-repeat="item in items">
{{item["type"]}}
</th>
I have an angular app where i am trying to create a table from a json. My json is as follows:
[
{
"campus_id": "321",
"name": "0"
},
{
"campus_id": "231",
"name": "1"
},
{
"campus_id": "123",
"name": "2"
}
]
Generally we will create a table in the html as follows:
<table class="table table-striped">
<tr>
<th>
Campus id
</th>
<th>
Name
</th>
</tr>
<tr ng-repeat="item in items">
<td >
{{item.campus_id}}
</td>
<td >
{{item.name}}
</td>
</tr>
</table>
How do i create even the headers from the json instead of defining them ourselves?
I would add the column headers within the json result like so
columnDefs: [
{field: 'campus_id', displayName: 'Campus ID'},
{field: 'name', displayName: 'Name'}],
data:
[
{
"campus_id": "57911000",
"name": "0"
},
{
"campus_id": "57911001",
"name": "HIGHLAND PARK HIGH SCHOOL"
},
{
"campus_id": "57911007",
"name": "P A S S Learning Center School"
}
]
otherwise you could use the key, value pairing ng-repeat="(key,value) in items" with a filter to return 1 row and then use {{key}}