Related
I am building a site which will output data from a JSON file into a table, but I am having issues getting the content to output. This JSON file is generated from another site which surfaces documentation, while my site just creates a table for easy searching of those docs.
SAMPLE JSON for 2 docs:
[{
"title": "SampleTitleA",
"lang": "en-US",
"lastEdition": "2020-07-28",
"version": "1.0",
"metadata": [
{
"key": "sampleKeyA1",
"label": "sampleLabelA1",
"values": ["sampleValueA1"]
},
{
"key": "sampleKeyA2",
"label": "sampleLabelA2",
"values": ["sampleValueA2"]
}]
},
{
"title": "SampleTitleB",
"lang": "en-US",
"lastEdition": "2020-07-28",
"version": "1.0",
"metadata": [
{
"key": "sampleKeyB1",
"label": "sampleLabelB1",
"values": ["sampleValueB1"]
},
{
"key": "sampleKeyB2",
"label": "sampleLabelB2",
"values": ["sampleValueB2"]
}]
}]
I am using DataTables for this (https://datatables.net/examples/ajax/deep.html) and have tried doing what it describes. It doesnt really cover reading arrays within arrays though.
To select an array within an array I have tried to follow the datatables example and done the following:
$(document).ready(function() {
$('#example').DataTable({
//sort on col 3 desc
"order": [3, 'desc'], //order by date
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
"ajax": {
"type": 'GET',
"dataType": 'json',
"lengthChange": true,
"contentType": 'application/json; charset=utf-8',
"url": "jsonlocation",
"deferRender": true,
"dataSrc": ""
},
"buttons": [ 'copy', 'excel',
{ extend: 'colvis', columns: [0,1,2,3,4,5,6]}
],
"dom": 'Bfrtip',
"columns": [
{ data: 'metadata.15.values.0', "defaultContent": "-" },
{ data: 'title', "defaultContent": "-" },
{ data: 'metadata.16.values.0', "defaultContent": "-" },
{ data: 'lastEdition', "defaultContent": "-" },
{ data: 'lang', "defaultContent": "-" },
{ data: 'version', "defaultContent": "-" },
{ data: 'readerUrl', "defaultContent": "-" },
{ data: 'readerUrl', "defaultContent": "-" },
],
"columnDefs": [{
"targets": [5],
"render": function(data, type, row, meta) {
return 'Click';
}
},
{
"targets": [7],
"visible": false,
"searchable": true
}
]
});
}
);
A table is created, but not populated, and shows no errors in console.
Has anyone any experience using dataTables for this purpose?
Thanks
Check if this helps you out.
var data = {
"title": "SampleTitle",
"lang": "en-US",
"lastEdition": "2020-07-28",
"version": "1.0",
"metadata": [
{
"key": "sampleKey1",
"label": "sampleLabel1",
"values": ["sampleValue1"]
},
{
"key": "sampleKey2",
"label": "sampleLabel2",
"values": ["sampleValue2"]
}]
}
var result = { data: data.metadata[1].values[0], "defaultContent": "-" }
console.log(result);
Your JSON data structure is an array - everything is contained in a [...] - therefore DataTables can iterate over this array to generate its table rows.
Here is an example with everything removed from your code except for the column data definitions (and column titles):
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable({
ajax: {
// my test URL:
url: 'http://localhost:7000/sample2',
dataSrc: ''
},
"columns": [
{ title: 'Title', data: 'title' },
{ title: 'Language', data: 'lang' },
{ title: 'Key', data: 'metadata[0].key' },
{ title: 'Label', data: 'metadata[0].label' },
{ title: 'First Value', data: 'metadata[0].values[0]' }
]
} );
} );
</script>
This generates a table which looks like this:
How does this work?
By default, DataTables expects the JSON structure to be as one of the following:
An object containing an array of other objects:
{ "data": [ {...},{...},... ] }
An object containing an array of arrays:
{ "data": [ [...],[...],... ] }
In both these cases, the array has a name (in this case data).
In your case, as already noted, your data is just a plain array of objects:
[ {...}, {...},... ]
Because the array has no name, we need to use dataSrc: '' in our DataTable definition, to indicate this lack of a name.
After that, you can reference the values you need to display, for example data: 'title'.
For the metadata section, that is itself a label referring to an array of objects:
"metadata": [ {...} ]
However, in this case the array only contains one object. We can refer to that first object in the metadata array using [0] - and then we can access the values in that object - for example, by using: data: 'metadata[0].label'.
I am trying to display data and view/edit/delete buttons using datatables.
I am getting user data and permission using two objects like this:
]
{
"data": [
{
"userid": "1",
"username": "John",
"email": "john#gmail.com",
"userrole": "SYSTEM VENDOR",
"isactive": "Y",
"activationstat": "deactivate",
"activationmsg": "Deactivate"
}
],
"perm":
{
"read": "y",
"edit": "y",
"delete": "n"
}
}
The button needs to be rendered for each row. Datatables code is as:
$('#dt-user').DataTable({
dom: 'lBfrtip',
buttons: [
{
extend: 'copyHtml5',
exportOptions: {
columns: ':visible'
}
},
{
extend: 'csvHtml5',
exportOptions: {
columns: ':visible'
}
},
{
extend: 'excelHtml5',
exportOptions: {
columns: ':visible'
}
},
{
extend: 'pdfHtml5',
exportOptions: {
columns: ':visible'
}
},
{
extend: 'print',
exportOptions: {
columns: ':visible'
}
},
'colvis'
],
ajax: baseURL + 'user/list-user-aj',
columns: [
{
"data": "id",
render: function (data, type, row, meta) {
return meta.row + meta.settings._iDisplayStart + 1;
}
},
{ data: 'username' },
{ data: 'email' },
{ data: 'userrole' },
{ data: 'isactive' }
],
responsive: {
details: false
}
});
How can I access the "perm" JSON object for checking its values for displaying buttons for edit, delete, print etc?
Short answer: You will not be able to get "perm" object within datatables initialization code. Datatables initialization code only works with "data" array from JSON.
However, here are two possible solutions to your situation:
Option 1:
If the "perm" object is going to be common for all elements (users) in the "data" array in JSON, like follows:
{
"data": [
{
"userid": "1",
"username": "John",
"email": "john#gmail.com",
"userrole": "SYSTEM VENDOR",
"isactive": "Y",
"activationstat": "deactivate",
"activationmsg": "Deactivate"
},
{
"userid": "2",
"username": "John2",
"email": "john2#gmail.com",
"userrole": "SYSTEM VENDOR2",
"isactive": "Y",
"activationstat": "deactivate",
"activationmsg": "Deactivate"
}
<!-- and maybe some more objects-->
],
"perm":
{
"read": "y",
"edit": "y",
"delete": "n"
}
}
then you can access the perm object like below: (and that would be outside of Datatables definition)
var permissions;
userDatatable.on('xhr', function () {
var json = userDatatable.ajax.json();
var permissions = json.perm;
});
where userDatatable will be the global javascript variable when you initialize Datatables like below:
var userDatatable = $('#dt-user').DataTable({ //......and all your code
Then inside your columns definition, you can access perm object and render buttons like this:
columns:[
{
data:null,
"render": function(data, type, row, meta){
if(perm.delete === 'y'){
return "<button class='deleteButton'> Delete </button>";
}
}
}
]
Make sure javascript variable "permissions" is global and visible to your Datatables initialization code. This will get you the Delete button, but you will have to write additional Javascript/JQuery code to trigger the Datatables Editor's AJAX call to delete the row; both at backend and from the grid.
Option 2: You could modify your server-side code to return JSON such that it will have permissions object within each element of the "data" array:
{
"data": [
{
"userid": "1",
"username": "John",
"email": "john#gmail.com",
"userrole": "SYSTEM VENDOR",
"isactive": "Y",
"activationstat": "deactivate",
"activationmsg": "Deactivate",
"perm":
{
"read": "y",
"edit": "y",
"delete": "n"
}
},
{
"userid": "2",
"username": "John2",
"email": "john2#gmail.com",
"userrole": "SYSTEM VENDOR2",
"isactive": "Y",
"activationstat": "deactivate",
"activationmsg": "Deactivate",
"perm":
{
"read": "y",
"edit": "y",
"delete": "n"
}
}
<!-- and maybe some more objects-->
]
}
With this second option, you could access perm object within the "render" function using "row.perm.delete" property.
Hope this help!
I'm trying to use datatables with a set number of columns and an array of objects I get from jQuery ajax.
I get the error:
datatables warning (table id = myId requested unknown parameter 0 from the data source for row 0
Searching the internet has shown me that it's probable I have a different number of column headers and column data in my message_json array;
I have 21 columns set up in my data table initialization:
var construct_messages_table = function(message_json){
var oTable = $('#tableId').dataTable( {
"sPaginationType": "full_numbers",
"bProcessing": true,
"bDeferRender": true,
"aaData": message_json,
"aoColumns": [
{ "sTitle": "coloumn1"},
{ "sTitle": "coloumn2"},
{ "sTitle": "coloumn3"},
{ "sTitle": "coloumn4"},
{ "sTitle": "coloumn5"},
{ "sTitle": "coloumn6"},
{ "sTitle": "coloumn7"},
{ "sTitle": "coloumn8"},
{ "sTitle": "coloumn9"},
{ "sTitle": "coloumn10"},
{ "sTitle": "coloumn11"},
{ "sTitle": "coloumn12"},
{ "sTitle": "coloumn13"},
{ "sTitle": "coloumn14"},
{ "sTitle": "coloumn15"},
{ "sTitle": "coloumn16"},
{ "sTitle": "coloumn17"},
{ "sTitle": "coloumn18"},
{ "sTitle": "coloumn19"},
{ "sTitle": "coloumn20"},
{ "sTitle": "coloumn21"}
]
} );
};
And
for (var i = 1; i < message_json.length; i++){
console.log(Object.keys(message_json[i]).length);
}
shows all objects have a length of 21. What could be wrong here?
EDIT:
I've removed nulls as that might be the problem, but still no help.
for (var i = 0; i < message_json.length; i++){
for (var o in message_json[i]){
if (message_json[i][o] == null){
message_json[i][o] = "";
}
}
}
EDIT:
message_json is in this format
[
{type: "int",
id: "111",
name: "co",
description: "",
is_bool: "0",
keyword: "<tag name="various-xml">fields</xml>",
message: "hello",
temp: "world",
settings: "",
priority: "100",
enabled: "0",
secure: "1",
var1: "post",
var1_desc: "some desc↵",
var1_query: "<DATA>blah</DATA>",
prop: "1",
prop_name: "Draft",
transaction: "1",
users: "0",
table_name: "abc"},
{type: "int",
id: "111",
name: "co",
description: "",
is_bool: "0",
keyword: "<tag name="various-xml">fields</xml>",
message: "hello",
temp: "world",
settings: "",
priority: "100",
enabled: "0",
secure: "1",
var1: "post",
var1_desc: "some desc↵",
var1_query: "<DATA>blah</DATA>",
prop: "1",
prop_name: "Draft",
transaction: "1",
users: "0",
table_name: "abc"}];
But with lots more elements of course. And not just a duplicates.
Well the number of elements must be the same as the columns otherwise Datatables will look for a value not included in the data.
If you want to use a structure like the one in:
[
{type: "int",
id: "111",
name: "co",
description: "",
is_bool: "0",
keyword: "<tag name="various-xml">fields</xml>",
message: "hello",
temp: "world",
settings: "",
priority: "100",
enabled: "0",
secure: "1",
var1: "post",
var1_desc: "some desc↵",
var1_query: "<DATA>blah</DATA>",
prop: "1",
prop_name: "Draft",
transaction: "1",
users: "0",
table_name: "abc"},
{type: "int",
id: "111",
name: "co",
description: "",
is_bool: "0",
keyword: "<tag name="various-xml">fields</xml>",
message: "hello",
temp: "world",
settings: "",
priority: "100",
enabled: "0",
secure: "1",
var1: "post",
var1_desc: "some desc↵",
var1_query: "<DATA>blah</DATA>",
prop: "1",
prop_name: "Draft",
transaction: "1",
users: "0",
table_name: "abc"}];
It will be better to use "sAjaxSource" on your dataTable
When you add the aaData to your datatables normally they provide an array of arrays:
Example:
Fiddle
If your want to use a key:value JSON object you will need to add the mData property to your aoColumms config like this:
var oTable = $('#tableId').dataTable( {
"sPaginationType": "full_numbers",
"bProcessing": true,
"bDeferRender": true,
"aaData": message_json,
"aoColumns": [
{ "sTitle": "coloumn1","mData":"type"},
{ "sTitle": "coloumn2","mData":"id"},
{ "sTitle": "coloumn3","mData":"name"},
{ "sTitle": "coloumn4","mData":"description"},
{ "sTitle": "coloumn5","mData":"is_bool"},...
This will tell datatables where to find the value for that column.
I am using jQuery dataTables for grids (http://www.datatables.net/).
However my json is formatted differently than the json example included with dataTables docs. Is it possible for dataTables to interpret the formatting in our json?
Their json looks like this
{"aaData": [
[
"Trident",
"Internet Explorer 4.0",
"Win 95+",
"4",
"X"
],
[
"Trident",
"Internet Explorer 5.0",
"Win 95+",
"5",
"C"
]
]
}
My JSON looks like this and unfortunately I can't change it to look like the example included in their docs.
"allconfig": {
"card.inserted": {
"value": "Not Inserted",
"type": "enum",
"range": "",
"clone": false,
"archive": false,
"access": "R"
},
"card.cisproc": {
"value": "Processed",
"type": "string",
"range": "",
"clone": false,
"archive": false,
"access": "R"
}
}
}
Here is my jQuery
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": 'json/test.json'
});
});
You can change your json format to required format.
Use
$.getJSON('json/test.json', function(data) {
var newJson = [];
var myJson = data ;
$.each(myJson.allconfig, function (key, value) {
var rowArray = [];
rowArray.push(key);
$.each(myJson.allconfig[key], function (key1, value1) {
rowArray.push(value1);
});
newJson.push(rowArray);
});
$('#example').dataTable( { "bProcessing": true, "aaData":newJson });
});
check http://jsfiddle.net/JASdL/
I am trying to load grid data from a ExtDirect router. The results contain a metaData object that should reconfigure the store's fields. I am getting the following error however when I try to load my data:
Uncaught TypeError: Cannot read property 'sortType' of undefined (ext-all-debug.js:23943)
The JSON result is:
{
"action": "Dashboard",
"method": "dashboarddata",
"type": "rpc",
"result": {
"success": true,
"metaData": {
"sortInfo": {
"direction": "ASC",
"field": "id"
},
"fields": [{
"mapping": "id",
"id": "id"
},
{
"mapping": "owner",
"id": "owner"
},
{
"mapping": "name",
"id": "name"
},
{
"mapping": "type",
"id": "type"
},
{
"mapping": "strategy",
"id": "strategy"
},
{
"mapping": "primebroker",
"id": "primebroker"
},
{
"mapping": "startdate",
"id": "startdate"
},
{
"mapping": "date_afc_prelim_approval",
"id": "date_afc_prelim_approval"
},
{
"mapping": "date_afc_approval",
"id": "date_afc_approval"
},
{
"mapping": "date_submit_regulator",
"id": "date_submit_regulator"
},
{
"mapping": "date_approval_regulator",
"id": "date_approval_regulator"
},
{
"mapping": "enddate",
"id": "enddate"
},
{
"mapping": "main_iso_currency",
"id": "main_iso_currency"
},
{
"mapping": "nav_frequency",
"id": "nav_frequency"
},
{
"mapping": "date_first_nav",
"id": "date_first_nav"
},
{
"mapping": "launch_size",
"id": "launch_size"
},
{
"mapping": "target_size",
"id": "target_size"
},
{
"mapping": "memo",
"id": "memo"
},
{
"mapping": "isin_codes",
"id": "isin_codes"
},
{
"mapping": "status",
"id": "status"
}],
"totalProperty": "total",
"successProperty": "success",
"idProperty": "id",
"root": "data"
},
"data": [{
"status": "Project closed",
"strategy": "Strategy X",
"date_afc_approval": "2010-01-01",
"startdate": "2010-01-01",
"nav_frequency": "Bi-monthly",
"date_first_nav": "2010-01-01",
"enddate": "2010-01-01",
"date_approval_regulator": "2010-01-01",
"id": "1",
"date_afc_prelim_approval": "2010-01-01",
"isin_codes": "123",
"target_size": "2000",
"owner": "Some name",
"name": "First project",
"memo": "TEXTEXTEXT",
"main_iso_currency": "TND",
"primebroker": "Yes",
"date_submit_regulator": "2010-01-01",
"launch_size": "1000",
"type": "TypeX"
}],
"total": 1
},
"tid": 6
}
The store itself is configured like:
var store = new Ext.data.DirectStore({
idProperty: 'id'
,paramsAsHash: true
,directFn: MyApp.Direct.Dashboard.dashboarddata
,root:'data'
,autoLoad: false
,totalProperty:'total'
,fields: [
{name: 'id', mapping: 'id'},
{name: 'type', mapping: 'type'}
]
,baseParams: {
type: this.type,
filters: this.filters
}
});
Can anyone please help me? This is driving me nuts, I cannot see what I am doing wrong.
Thanks!
Rob
PS. I am using ExtJS 3.3.0
Why not debug that place using Chrome or Firefox debug facility? The helpful options is setting the break on exception in the Chrome.
I fixed it. Debugging did the trick.
Apparently when updating the fields through the metaData object in the JSON response you need to name the fields. ExtJS uses the name field as a lookup field internally. Strange thing is that with static configuration of a store's fields you don't need that field...
...
"fields": [{
"mapping": "id",
"name": "id",
"id": "id"
},
{
"mapping": "owner",
"name": "owner",
"id": "owner"
},
...