Get DataTables to output an array of objects in appropriate columns - json

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.

Related

How to output response of type atom/xml feed into Jquery DataTable?

How to output response of type atom/xml feed (from arxiv call) into Jquery DataTable?
I have the datatable working for a simple json from Ajax call to flask server example.
When i try to do it with the xml from an arxiv api response, i cant seem to get it to display in the datatable (though i can just print the raw xml using <pre lang="xml" > or json).
I also tried to convert to json first via python dictionary, but still couldnt get it formatted into datatable as im unsure how to access the properties properly in the Ajax call when theyre deeper than the first level as in the basic example linked.
The HTML in template:
<table id="arxivtable" class="display" style="width:100%">
<thead>
<tr>
<th>title</th>
<th>id</th>
<th>link</th>
<th>author</th>
<th>published</th>
</tr>
</thead>
</table>
I tried via xml :
$('#arxivtable').DataTable({
"ajax": {
// "url": "static/objects2.txt", // This works for the static file
"url": "/get_arxivpapers", // This now works too thanks to #kthorngren
"dataType": "xml",
"type":"GET",
"dataSrc": "{{name}}",
"contentType":"application/atom+xml"
},
"columns": [
{"data": "title"},
{
"data": "link",
"render": function(data, type, row, meta){
if(type === 'display'){
data = '' + data + '';
}
return data;
}
},
{ "data": "id" },
{ "data": "link" },
{ "data": "author" },
{ "data": "journal" },
{ "data": "published" },
{ "data": "summary" }
]
});
JSON from AJAX call:
{
"feed": {
"#xmlns": "http://www.w3.org/2005/Atom",
"link": {
"#href": "http://arxiv.org/api/query?search_query%3Dall%3Aeinstein%26id_list%3D%26start%3D0%26max_results%3D2",
"#rel": "self",
"#type": "application/atom+xml"
},
"title": {
"#type": "html",
"#text": "ArXiv Query: search_query=all:einstein&id_list=&start=0&max_results=2"
},
"id": "http://arxiv.org/api/vehKAQR+bheXtHwJw3qx/OG/XXw",
"updated": "2022-06-14T00:00:00-04:00",
"opensearch:totalResults": {
"#xmlns:opensearch": "http://a9.com/-/spec/opensearch/1.1/",
"#text": "36970"
},
"opensearch:startIndex": {
"#xmlns:opensearch": "http://a9.com/-/spec/opensearch/1.1/",
"#text": "0"
},
"opensearch:itemsPerPage": {
"#xmlns:opensearch": "http://a9.com/-/spec/opensearch/1.1/",
"#text": "2"
},
"entry": [
{
"id": "http://arxiv.org/abs/1801.05533v2",
"updated": "2018-11-22T14:04:43Z",
"published": "2018-01-17T03:05:51Z",
"title": "Einstein-Weyl structures on almost cosymplectic manifolds",
"summary": "",
"author": {
"name": "Xiaomin Chen"
},
"arxiv:comment": {
"#xmlns:arxiv": "http://arxiv.org/schemas/atom",
"#text": "accepted by Periodica Mathematica Hungarica, 14 pages, no figures"
},
"link": [
{
"#href": "http://arxiv.org/abs/1801.05533v2",
"#rel": "alternate",
"#type": "text/html"
},
{
"#title": "pdf",
"#href": "http://arxiv.org/pdf/1801.05533v2",
"#rel": "related",
"#type": "application/pdf"
}
],
"arxiv:primary_category": {
"#xmlns:arxiv": "http://arxiv.org/schemas/atom",
"#term": "math.DG",
"#scheme": "http://arxiv.org/schemas/atom"
},
"category": [
{
"#term": "math.DG",
"#scheme": "http://arxiv.org/schemas/atom"
},
{
"#term": "53D10, 53D15",
"#scheme": "http://arxiv.org/schemas/atom"
}
]
},
{
"id": "http://arxiv.org/abs/0802.2137v3",
"updated": "2008-04-01T04:36:21Z",
"published": "2008-02-15T04:40:56Z",
"title": "",
"summary": ".",
"author": {
"name": ""
},
"arxiv:comment": {
"#xmlns:arxiv": "http://arxiv.org/schemas/atom",
"#text": "18 pages, added Theorem 5"
},
"link": [
{
"#href": "http://arxiv.org/abs/0802.2137v3",
"#rel": "alternate",
"#type": "text/html"
},
{
"#title": "pdf",
"#href": "http://arxiv.org/pdf/0802.2137v3",
"#rel": "related",
"#type": "application/pdf"
}
],
"arxiv:primary_category": {
"#xmlns:arxiv": "http://arxiv.org/schemas/atom",
"#term": "math.DG",
"#scheme": "http://arxiv.org/schemas/atom"
},
"category": [
{
"#term": "math.DG",
"#scheme": "http://arxiv.org/schemas/atom"
},
{
"#term": "53C30; 53C25",
"#scheme": "http://arxiv.org/schemas/atom"
}
]
}
]
}
}
Or the original atom/xml:
<feed xmlns="http://www.w3.org/2005/Atom">
<link href="http://arxiv.org/api/query?search_query%3Dall%3Aeinstein%26id_list%3D%26start%3D0%26max_results%3D2" rel="self" type="application/atom+xml">
<title type="html">ArXiv Query: search_query=all:einstein&id_list=&start=0&max_results=2</title>
<id>http://arxiv.org/api/vehKAQR+bheXtHwJw3qx/OG/XXw</id>
<updated>2022-06-14T00:00:00-04:00</updated>
<opensearch:totalresults xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">36970</opensearch:totalresults>
<opensearch:startindex xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">0</opensearch:startindex>
<opensearch:itemsperpage xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">2</opensearch:itemsperpage>
<entry>
<id>http://arxiv.org/abs/1801.05533v2</id>
<updated>2018-11-22T14:04:43Z</updated>
<published>2018-01-17T03:05:51Z</published>
<title></title>
<summary>
</summary>
<author>
<name></name>
</author>
<arxiv:comment xmlns:arxiv="http://arxiv.org/schemas/atom">accepted by Periodica Mathematica Hungarica, 14 pages, no figures</arxiv:comment>
<link href="http://arxiv.org/abs/1801.05533v2" rel="alternate" type="text/html">
<link title="pdf" href="http://arxiv.org/pdf/1801.05533v2" rel="related" type="application/pdf">
<arxiv:primary_category xmlns:arxiv="http://arxiv.org/schemas/atom" term="math.DG" scheme="http://arxiv.org/schemas/atom">
<category term="math.DG" scheme="http://arxiv.org/schemas/atom">
<category term="53D10, 53D15" scheme="http://arxiv.org/schemas/atom">
</category></category></arxiv:primary_category></entry>
<entry>
<id>http://arxiv.org/abs/0802.2137v3</id>
<updated>2008-04-01T04:36:21Z</updated>
<published>2008-02-15T04:40:56Z</published>
<title></title>
<summary>
</summary>
<author>
<name></name>
</author>
<arxiv:comment xmlns:arxiv="http://arxiv.org/schemas/atom"></arxiv:comment>
<link href="http://arxiv.org/abs/0802.2137v3" rel="alternate" type="text/html">
<link title="pdf" href="http://arxiv.org/pdf/0802.2137v3" rel="related" type="application/pdf">
<arxiv:primary_category xmlns:arxiv="http://arxiv.org/schemas/atom" term="math.DG" scheme="http://arxiv.org/schemas/atom">
<category term="math.DG" scheme="http://arxiv.org/schemas/atom">
<category term="53C30; 53C25" scheme="http://arxiv.org/schemas/atom">
</category></category></arxiv:primary_category></entry>
</feed>
The End Point:
#app.route('/get_arxivpapers')
def getArxivPapers(name="einstein"):
max_results = 2
searchterm = name.replace("_", "&#32")
url = 'http://export.arxiv.org/api/query?search_query=all:' + searchterm + '&start=0&' + 'max_results='+ str(max_results)
data = urllib.request.urlopen(url)
# data_dict = xmltodict.parse(data)
# json_data = json.dumps(data_dict)
# print(json_data)
# return jsonify(json_data)
return data.read().decode('utf-8')
I will use your JSON source data instead of the XML, since that is easier to handle in DataTables.
Here is a basic demo, to start with, followed by some explanatory notes:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
</head>
<body>
<div style="margin: 20px;">
<table id="arxivtable" class="display" style="width:100%">
<thead>
<tr>
<th>title</th>
<th>id</th>
<th>link</th>
<th>author</th>
<th>published</th>
<th>summary</th>
</tr>
</thead>
</table>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#arxivtable').DataTable({
"ajax": {
url: "YOUR_URL_GOES_HERE",
dataSrc: "feed.entry"
},
"columns": [
{"data": "title"},
{ "data": "id" },
{ "data": "link[].#href" },
{ "data": "author.name" },
{ "data": "published" },
{ "data": "summary" }
]
});
});
</script>
</body>
</html>
Notes
1 - Because you have provided hard-coded HTML column headers, you need to make sure the number of those headers matches the number of columns defined in the DataTable. Alternatively, you can remove the HTML <thead> section and use the DataTables columns.title option.
2 - Your Ajax JSON source data contains an array [ ... ]. DataTables needs to know where this array is located in your JSON response, as part of the Ajax handling option, so that it can iterate over that array. Each element in the array will be used to create a row of HTML table data. The ajax.dataSrc option therefore needs to be set accordingly:
dataSrc: "feed.entry"
Once you have set the above Ajax JSON starting point correctly, then you can use field names for each separate column data value - as shown below.
3 - The author JSON value is actually an object:
"author": {
"name": "Xiaomin Chen"
},
Therefore you need to drill down into that to get the field you want to show in the DataTable:
{ "data": "author.name" },
4 - I removed your column renderer function to keep my initial demo simple, but it can be used to access fields and sub-fields - and concatenate strings and other values as needed (as in your example in the question).
5 - The link JSON value is actually an array of objects. For my basic demo, I just accessed the final entry in that array, and then took the href field:
{ "data": "link[].#href" },
This may not be what you want. You may want to only choose links of a certain type, or choose all links, or something different.
This is where DataTables is limited in what it can handle. It cannot display arbitrary nested JSON values of this type (not surprisingly).
In such cases, you would need to re-structure the JSON, prior to sending it to DataTables - or restructure it in a dataSrc function inside DataTables itself:
"dataSrc": function ( json ) { ...transform and return your JSON here... }
6 - I was not sure what you wanted to display for { "data": "journal" }. I did not see anything called journal in the JSON.
7 - Note that all the source JSON data outside of the feed.entry array is also not available to DataTables. DataTables can only iterate over that outer array. Anything you may also need which is not in that outer array would need to be added to the array, to be accessible to DataTables.
See also Nested object data (arrays) and Nested object data (objects) for more related notes.

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" ]
}
]
}
]

Using Axios and Vue.js to load JSON data

I'm trying to display JSON data on my webpage by using the v-for function in Vue.js and Axios to get the data. Below is my code and an example of the JSON data i'm trying to use.
I have kept the JSON data URL out on purpose as it's private, which is why i've provided an example of the data structure.
I can print the entire data set to my page, as it appears below but if i use my code below to print specific parts of data, like the id or name, that's when i get nothing on the page.
<div id="root">
<p v-for="item in items">{{ item.name }}</p>
</div>
<script>
var app = new Vue({
el: '#root',
data: {
items: []
},
mounted() {
axios.get("...")
.then(response => {this.items = response.data.data})
}
});
</script>
JSON data example:
json
{
"current_page": 1,
"data": [
{
"id": "83",
"name": "Name1",
},
{
"id": "78",
"name": "Name2",
},
{
"id": "720",
"name": "Name3",
},
{
"id": "707",
"name": "Name4",
},
{
"id": "708",
"name": "Name5",
}
],
"from": 1,
"prev_page_url": null,
"to": 20,
"total": 42
}
looking at the code everything looks ok, but i have an example in the application i am working on and i've noticed that your items array should contain response.data.data.data wich is verbose but you can work on that later

DataTables ajax on nested data

I am using DataTables ajax to fill a table. I was following this example and it works if my json looks like their example, however my 'data' is a nested object in my json and then it is not able to fill the table because fails in getting the values from the json.
This json works:
{
"data": [
{"id": "myid1", "name": "name1"},
{"id": "myid2", "name": "name2"}
]
}
But my json looks like this, and it does not work
{
"result": {
"data": [
{"id": "myid1", "name": "name1"},
{"id": "myid2", "name": "name2"}
]
}
}
That's my html (which works with the first json):
<table id="myTable" class="tabletable-bordered dataTable">
<thead>
<tr>
<th>name</th>
<th>id</th>
</tr>
</thead>
<tbody>
<td></td>
<td></td>
</tbody>
</table>
And that's my js:
$('#myTable').DataTable( {
"ajax": "/names",
"processing": true,
"dataSrc" : "result.data",
"columns": [
{ "data": "name" },
{ "data": "id" }
]
} );
As you can see I try to access to my nested data by setting dataSrc to result.data, but nothing is shown in the table.
I cannot change the format of the json response, do you know if then is not possible to use DataTables ajax with this json? Thanks!
MY SOLUTION
Finally (before getting an answer to my post) I went with the following solution, I first make an ajax call and then on success I create my DataTable.
so I only changed my js to this one:
$.ajax({
type: "GET",
url: '/names',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
var myData = data.result.data;
$('#myTable').DataTable({
"data": myData,
"columns": [
{ "data": "id" },
{ "data": "name"},
]
});
}
});
I had more complex processing requirements so I implemented my own ajax function but I think you can get away with this:
$('#myTable').DataTable( {
"processing": true,
"ajax": {
"url": "/names",
"dataSrc" : function(jsonObj) {
// Just being safe here
if(!jsonObj.results || !json.results.data) {
return [];
}
return jsonObj.results.data;
}
},
"columns": [
{ "data": "name" },
{ "data": "id" }
]
});
Here is the reference for this: https://datatables.net/reference/option/ajax

DataTables with Codeigniter MYSQL query

I'm trying to display three data tables as shown on this page with the variant of getting the data from my database, as shown here.
I first tested the page with the static data (from arrays.txt - first link) and it worked fine. However I'm now struggling with the MYSQL data and the JSON.
An info message showing "Processing..." shows up but the tables stay empty.
My Javascript:
$(document).ready(function(){
$('a[data-toggle="tab"]').on( 'shown.bs.tab', function (e) {
$.fn.dataTable.tables( {visible: true, api: true} ).columns.adjust();
} );
$('table.table').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"dataSrc": "Data", // Tried adding this but didn't help
"url": "/hireStaffController/getDataTable",
"type": "POST"
},
"columns": [
{ "data": "id_staff" },
{ "data": "name_english" },
{ "data": "name_french" },
{ "data": "position" },
{ "data": "efficiency" },
{ "data": "salary" }
]
} );
}
My controller:
public function getDataTable(){
$data = $this->staffModel->get_all_staff_DB();
echo json_encode($data);
}
My Model:
public function get_all_staff_DB(){
$query = $this->db
->select('*')
->from('game_staff')
->get();
return $query->result();
}
The JSON Response from Firebug seems correct:
[{
"id_staff": "1",
"name_english": "Ski patrol 1",
"name_french": "Pisteur secouriste 1",
"position": "skipatrol",
"efficiency": "50",
"salary": "1500"
}, {
"id_staff": "10",
"name_english": "Bus driver 2",
"name_french": "Chauffeur de bus 2",
"position": "driver",
"efficiency": "55",
"salary": "1380"
}]
Firebug throws this error:
TypeError: c is undefined
...iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)N(a,c[d]);a.aiDisplay=...
^
So I've tried to add "dataSrc": "Data", in the Ajax, as described here but no luck, same error. WHat is this Data? I tried with a small "d" as well.
Can you see what is wrong?
My HTML code:
<div class="tab-pane active" id="tab-table1">
<table id="myTable1" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Extn.</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
</table>
</div>
<div class="tab-pane" id="tab-table2">
<table id="myTable2" class="table table-striped table-bordered" cellspacing="0" width="100%">
//same ...
</table>
</div>
try including "Data" as key to the echoed data:
public function getDataTable(){
$data = $this->staffModel->get_all_staff_DB();
echo json_encode(array('Data' => $data));
}
When you specify dataSrc as "Data", datatables looks for a "Data" property in the json returned by the ajax call, and uses that property as source for the table.
I hope the HTML table with is present there.
Try using ID instead of class.
Everything else you have done looks fine.
$('#ID').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"url": "/hireStaffController/getDataTable",
"type": "POST"
},
"columns": [
{ "data": "id_staff" },
{ "data": "name_english" },
{ "data": "name_french" },
{ "data": "position" },
{ "data": "efficiency" },
{ "data": "salary" }
]
} );