Angularjs Table using JSON data - html

My two JSON arrays are,
$scope.myHospital = [
{"id":"1","name":"hos1"},
{"id":"2","name":"hos2"},
{"id":"3","name":"hos3"},
{"id":"4","name":"hos4"},
{"id":"5","name":"hos5"}
];
another one is
$scope.data = [
{
"category":"first category",
"procedure":[{
"name":"pro1",
"hospital": [
{"id":"1","price":"1101"},
{"id":"2","price":"1102"},
{"id":"3","price":"1103"},
{"id":"4","price":"1104"},
{"id":"5","price":"1105"}
]
}, {
"name":"pro2",
"hospital": [
{"id":"1","price":"1201"},
{"id":"2","price":"1202"},
{"id":"3","price":"1203"},
{"id":"4","price":"1204"},
{"id":"5","price":"1205"}
]
}, {
"name":"pro3",
"hospital": [
{"id":"1","price":"1301"},
{"id":"3","price":"1303"},
{"id":"5","price":"1305"}
]
}]
},
{
"category":"Second category",
"procedure":[{
"name":"pro4",
"hospital": [
{"id":"1","price":"2101"},
{"id":"2","price":"2102"},
{"id":"3","price":"2103"},
{"id":"4","price":"2104"},
{"id":"5","price":"2105"}
]
}, {
"name":"pro5",
"hospital": [
{"id":"1","price":"2201"},
{"id":"2","price":"2202"},
{"id":"4","price":"2204"}
]
}]
}
];
BY these I want a table like this
I tried it by ng-repeat till now I manage to generate the table here in plnkr
Now I stuck on the logic of null values by matching the hospital id. Inserting null values manually in JSON will not work for me because I am getting this JSON from backend. But I can ask them to change JSON structure(format of array) if needed.

Try smart table. https://github.com/lorenzofox3/Smart-Table
Our prepare your data before ng-repeat to fit your needs.

Not The Exact Solution But May Be Helpful..
<table border="2">
<tbody ng-repeat="cat in data">
<tr>
<td>{{cat.category}}</td>
</tr>
<tr ng-repeat="procedure in cat.procedure">
<td>{{procedure.name}}</td>
<td ng-repeat="hospital in procedure.hospital">{{hospital.price}}</td>
</tr>
</tbody>

Here is the working code.
I have made a bit of changes in your data source too which is easy to consider and make and in HTML too.
In your plunker you were displaying wrong value corresponding to the hospitals when there are few records present in "hospital" object in $scope.data.To rectify that I have added null objects too so the ng-repeat will pass right index for comparision to display
In JS
$scope.data = [
{
"category":"first category",
"procedure":[{
"name":"pro1",
"hospital": [
{"id":"1","price":"1101"},
{"id":"2","price":"1102"},
{"id":"3","price":"1103"},
{"id":"4","price":"1104"},
{"id":"5","price":"1105"}
]
}, {
"name":"pro2",
"hospital": [
{"id":"1","price":"1201"},
{"id":"2","price":"1202"},
{"id":"3","price":"1203"},
{"id":"4","price":"1204"},
{"id":"5","price":"1205"}
]
}, {
"name":"pro3",
"hospital": [
{"id":"1","price":"1301"},
{"id":"2","price":null}, // add null objects for considering right index in display...
{"id":"3","price":"1303"},
{"id":"4","price":null},
{"id":"5","price":"1305"}
]
}]
},
{
"category":"Second category",
"procedure":[{
"name":"pro4",
"hospital": [
{"id":"1","price":"2101"},
{"id":"2","price":"2102"},
{"id":"3","price":"2103"},
{"id":"4","price":"2104"},
{"id":"5","price":"2105"}
]
}, {
"name":"pro5",
"hospital": [
{"id":"1","price":"2201"},
{"id":"2","price":"2202"},
{"id":"3","price":null},
{"id":"4","price":"2204"},
{"id":"5","price":null}
]
}]
}
];
In your HTML
<tr ng-repeat="(index, hos) in myHospital">
<td width="100px">{{hos.name}}</td>
<td width="100px" ng-repeat="pro in d.procedure">
<p ng-show="pro.hospital[index].id == index+1">{{ pro.hospital[index].price }}</p>
<p ng-hide="pro.hospital[index].id == index+1 && pro.hospital[index].price">NULL</p>
</td>
</tr>

You can change the JSON structure after receiving it in order to make it renderable on UI. Something like this,
angular.forEach($scope.data[0].procedure, function(pro) {
var arr = [];
angular.forEach(pro.hospital, function(hos) {
arr[hos.id] = hos.price
});
pro.hospital = arr;
});
Now your hospital array that has lesser values would look like following. If you notice, I changed the structure from array of objects to an array of strings having prices with keys denoting the hospital number..
hospital: [
2: "469",
3: "429",
5: "319"
]
Finally, you can have your rendering logic like following for embracing this change,
<tr ng-repeat="(index, hos) in myHospital">
<td ng-bind="hos.name"></td>
<td ng-repeat="pro in data[0].procedure">
<span ng-bind="pro.hospital[index+1]"></span>
<span ng-if="!pro.hospital[index+1]">NULL</span> <!--Optional-->
</td>
</tr>
DEMO

Related

How to bind array of string in html using aspose.html?

I am having my json like that and i am trying to bind this in Html and convert into pdf using aspose.html but i am not able to bind readings data i.e; array of string . HTML code which i tried that i also pasting here please go through this also.
Now i am getting my result in pdf like this
Date 2/1/2022,2/2/2022,2/3/2022
Time 10AM,11AM,12PM
But i want my result in different column like
CL1 CL2 CL3
Date 2/1/2022 2/2/2022 2/3/2022
HTML:
<table class="poc_tbl" style="width:100%;margin-top:10px;" data_merge='{{#foreach data_pages}}'>
<tr>
<td>
<table class="poc_tbl" style="width:100%;margin-top:10px;" data_merge='{{#foreach data_readings}}'>
<tbody style="background-color: #f5fbfe;">
<tr>
<td style="width:30%";data_merge="{{#foreach data_readings}}">{{title}}</td>
<td>{{readings}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
JSON:
"data_pages": [
{
"data_readings": [
{
"title": "Date",
"readings": [ "2/1/2022", "2/2/2022", "2/3/2022" ]
},
{
"title": "Time",
"readings": [ "10AM", "11AM", "12PM" ]
},
{
"title": "Order",
"readings": [ "O1", "O2", "O3" ]
}
]
},
{
"data_readings": [
{
"title": "Date",
"readings": [ "3/1/2022", "3/2/2022", "3/3/2022" ]
},
{
"title": "Time",
"readings": [ "1AM", "2AM", "3aM" ]
},
{
"title": "Order",
"readings": [ "O11", "O12", "O13" ]
}
]
}
]

Dynamically create HTML table rows from object using angular ng-repeat

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

Get DataTables to output an array of objects in appropriate columns

I'm working on a chemicals database web application. Using DataTables 1.10.16 and CakePHP 3.5
Cake is producing a JSON feed. A sample is below:
[
{
"id": 1,
"app_id": "ID000001",
"name": "Chromium",
"ecs": [
{
"id": 1,
"value": "123-456-7"
},
{
"id": 32,
"value": "222-333-444"
},
],
"cas": [
{
"id": 1,
"value": "987-654-3"
}
]
},
]
For certain chemicals there are multiple EC (ecs in the JSON) and CAS Numbers (cas in the JSON).
I don't know if/how it's possible to get DataTables to loop through these objects, outputting them in the appropriate columns, with a separator such as a <br> tag.
My table markup looks like this:
<table id="substancesTable" class="table responsive display table-striped" cellspacing="0" width="100%">
<thead>
<tr>
<th>Application ID</th>
<th>EC Number</th>
<th>CAS Number</th>
<th>Chemical Name</th>
</tr>
</thead>
</table>
And in my Javascript I'm doing this:
$('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url" : "/get-substances.json",
"method" : "POST",
"dataSrc":""
},
"columns": [
{ "data": "app_id", "name" : "app_id" },
{ "data": "ecs", "name" : "ec_number" },
{ "data": "cas", "name" : "cas_number" },
{ "data": "name", "name" : "name" },
]
});
This works in terms of populating the "Application ID" and "Chemical Name" columns - but that's because there is a simple 1:1 mapping in the JSON (no arrays/objects).
The output for the "EC Number" and "CAS Number" columns is just [object Object] and is repeated the number of objects there are. In the example above there are 2 EC Numbers for this chemical so the output under "EC Number" is [object Object],[object Object]
Can anyone assist with this? I'd like the output to be generated by looping through my JSON and introducing a break between each item, e.g.
123-456-7<br>222-333-444
You'll be needing a render function like this:
{
"data": "ecs",
"name": "ec_number",
"title":"EC Number",
"render": function(d,t,r){
return d.map(function(e) {
return e.value;
}).join("<br/>");
}
}
Working JSFiddle here.

Passing client-side JSON to dataTable - syntax?

I'm stuck trying to pass JSON to a dataTable.
I load JSON at a different point in the script, then truncate the part I need and pass it into a function that is supposed to render the table.
The function is:
function populateCasesTable(d){
var json = d.cases;
var cols = [
{ "data" : json.service_area},
{ "data" : json.presenting_issue },
{ "data" : json.referred_by },
{ "data" : json.date_opened },
{ "data" : json.case_status },
{ "data" : json.preferred_staff }
];
console.log(json);
$('#cases_table').DataTable( {
"data": json,
"columns": cols
} );
}
HTML for the table is
<table id='cases_table' width="100%">
<thead>
<tr>
<th>Service Area</th>
<th>Presenting Issue</th>
<th>Referred by</th>
<th>Date opened</th>
<th>Status</th>
<th>Preferred Staff</th>
</tr>
</thead>
</table>
The console.log output returns the right amount of objects (12) and a single object looks eg:
0 Object:
action:9
case_status:"Open"
date_created:"11/07/2017"
date_opened:"11/07/2017"
file:5
id:31646
issues:8
preferred_staff:"Doc Kuran"
presenting_issue:"Anxiety Disorder"
referral:0
referred_by:"Academic staff"
serviceAreaId:14
service_area:"Disability Services"
staff:0
I get the right number of pages rendered accompanied by the cryptic 'DataTables warning: table id=cases_table - Requested unknown parameter '0' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4' pop-up.
I'm sure this is a config issue, but I could not work this out.
What am I missing?
Thanks.
I found it. Cols must be set as follows:
var cols = [
{ "data" : 'service_area'},
{ "data" : 'presenting_issue' },
{ "data" : 'referred_by' },
{ "data" : 'date_opened' },
{ "data" : 'case_status' },
{ "data" : 'preferred_staff' }
];

JS Render For Loop in child JSON object

Trying to make this work. I need to display FIRST_NAME and LAST_NAME values beetween to new TDs. The value are stored in an object of the data item. I can't seem to loop througt the child object.
Template example
<script id="row_tmpl" type="text/x-jsrender">
<tr id="{{>id}}">
<td class="textC">{{>id}}</td>
<td class="">{{>email}}</td>
{{for data}}
??????
{{/for}}
</tr>
</script>
Here is an example of the json object sent to the template ( actually, data.results is sent to the template )
{
"results":[
{
"id":"1",
"email":"aaaa#test.com",
"data":{
"1":{
"first_name":{
"value":"Name 1",
"public":"1",
"field":"1",
"mandatory":"1",
"possible_value":"",
"type":"text"
},
"last_name":{
"value":"Name 2",
"public":"1",
"field":"2",
"mandatory":"1",
"possible_value":"",
"type":"text"
}
}
}
},
{
"id":"2",
"email":"test2#test.com",
"data":{
"2":{
"first_name":{
"value":"Name 3",
"public":"0",
"field":"1",
"mandatory":"1",
"possible_value":"",
"type":"text"
},
"last_name":{
"value":"Name 4",
"public":"0",
"field":"2",
"mandatory":"1",
"possible_value":"",
"type":"text"
}
}
}
}
]
}
That's a poorly structured response. I should not need to know the id of data's parent to access its children. Also, data isn't an array.
<script id="row_tmpl" type="text/x-jsrender">
<tr id="{{>id}}">
<td class="textC">{{>id}}</td>
<td class="">{{>email}}</td>
<td class="">{{>data.{{:id}}.first_name.value}}</td>
<td class="">{{>data.{{:id}}.lastt_name.value}}</td>
</tr>
</script>