DataTables how to use multiple data from json objects - ajax

so what i'm trying to do is to call some data from a json file to fill my table. But instead of having a lot of json files, i'd like to keep some of the data in a single file. For example, i have 2 types of clients (person and company) and i want to keep them both in the same json, but as different objects, because each one goes in different table.
The problem is: I can't access the data in the JSON file.
I can use it normally if i use the 2 type of clients in different files (person.json and company.json - This works fine).
I did tried these 2 examples, but none of them worked for me.
https://www.datatables.net/examples/ajax/deep.html
https://www.datatables.net/examples/ajax/objects_subarrays.html
So, how can i do get the data from the file? Here is my json and my datatable code:
{
"clients": {
"person": [
{
"cd":0,
"id":"C-0010",
"nm_cliente":"Name AAA",
"dt_nasc":"02/11/1990",
"info":"Some basic info"
},
{
"cd":1,
"id":"C-0013",
"nm_cliente":"Name BBB",
"dt_nasc":"02/11/1990",
"info":"Some basic info"
},
{
"cd":2,
"id":"C-0017",
"nm_cliente":"Name CCC",
"dt_nasc":"02/11/1990",
"info":"Some basic info"
}
],
"company": [
{
"cd":0,
"id":"C-0032",
"nm_cliente":"Name Client",
"num_cnpj":"111.222.3333/0001-22",
"nm_cidade":"City AAA"
},
{
"cd":1,
"id":"C-0033",
"nm_cliente":"Client Name",
"num_cnpj":"111.222.3333/0001-22",
"nm_cidade":"City BBB"
},
{
"cd":2,
"id":"C-0035",
"nm_cliente":"jEmpresa teste",
"num_cnpj":"111.222.3333/0001-22",
"nm_cidade":"City CCC"
}
]
}
}
I already used jsonlint.com to verify, and everything is ok with my JSON. And here is how i'm trying to call this data into my tables.
TableA - Client type Person
//rest of the code goes here...
"aoColumns" : [
{ "mData": "person.id" },
{ "mData": "person.nm_cliente" },
{ "mData": "person.dt_nasc" },
{ "mData": "person.info" }
]
TableB - Client type Company
//rest of the code goes here...
"aoColumns" : [
{ "mData": "company.id" },
{ "mData": "company.nm_cliente" },
{ "mData": "company.nm_cnpj" },
{ "mData": "company.nm_cidade" }
]
I keep getting error like "lenght not defined"
Can anyone help me?

You must refer to the person and company arrays themselves, not the items. Updated to demonstrate initialization after load of JSON and how to reuse and manipulate the options :
//an options object, some example settings
var options = {
bPaginate: true,
sPaginationType: "full_numbers",
aLengthMenu: [25,50,100,500]
//etc
}
function initialize(json) {
options.aaData = json.clients.person;
options.aoColumns = [
{ "mData": "id" },
{ "mData": "nm_cliente" },
{ "mData": "dt_nasc" },
{ "mData": "info" }
];
$("#tableA").dataTable(options);
options.aaData = json.clients.company;
options.aoColumns = [
{ "mData": "id" },
{ "mData": "nm_cliente" },
{ "mData": "num_cnpj" },
{ "mData": "nm_cidade" }
];
$("#tableB").dataTable(options);
}
$.getJSON("your.json", function(json) {
initialize(json);
});
original demo showing how to inject the JSON -> http://jsfiddle.net/3g5wcyet/
reuseable options demo -> http://jsfiddle.net/bpgvfefd/

Related

What are the possible values for columnName when requesting a report through the API

I'm trying to programatically request an Executive Report (on Campaigns) that my users usally run manually.
Following the instructions found at https://developers.google.com/doubleclick-search/v2/reference/reports/request , I can use the request_report() method succesfully if I only selected the Campaign and Clicks columns in the report:
request = service.reports().request(
body=
{
"reportScope": {
"agencyId": "xxx",
"advertiserId": "xxx"
},
"reportType": "campaign",
"columns": [
{ "columnName": "Campaign" },
{ "columnName": "Clicks" }
],
"timeRange" : {
"startDate" : "2016-07-24",
"endDate" : "2016-07-30"
},
#"filters": [ ],
"downloadFormat": "csv",
"maxRowsPerFile": 6000000,
"statisticsCurrency": "agency",
"verifySingleTimeZone": "false",
"includeRemovedEntities": "false"
}
)
but if I try to add Engine and/or Trans as columns to the report, like this:
"columns": [
{ "columnName": "Campaign" },
{ "columnName": "Engine" },
{ "columnName": "Trans" },
{ "columnName": "Clicks" }
],
I get the following error back:
googleapiclient.errors.HttpError: <HttpError 400 when requesting
https://www.googleapis.com/doubleclicksearch/v2/reports?alt=json returned
"columns[1]: Column identifier is missing or have unrecognized values. Must
include at least one of: columnName, customDimensionName, customMetricName,
savedColumnName">
I guess this means that Engine and Trans must have some other name, but I can't find any documentation for it.
Any suggestions on where I can look it up?
Thank you

How do I suppress AJAX calls in jsTree?

I'm using ajax as my data source, as you can see from the code below. However, I also need to programmatically insert nodes into the tree. When I do this, jsTree is making an ajax callback after the node is created. Is there any way to suppress this based on node attributes? In my particular case, I have nodes that are listed in a CORBA name service and nodes that are not. The ones that are in the CORBA name service are working perfectly, and are available via AJAX. I want to insert arbitrary nodes, with the attribute 'ns'='none' into the tree and NOT have it make an ajax call. Here is my code:
function renderJsonTree() {
$("#JsonTree").jstree({
"plugins" : [ "json_data", "types", "themes", "ui", "cookies" ],
"ui" : {"select_limit" : 1},
"json_data" : {
"ajax" :
{
"url":"lookup",
"data":function(n) {
return {"server":n.attr?n.attr('data-ns'):'',
"longName":n.attr?n.attr('data-longname'):'',"isObj":n.attr?n.attr('data-isObj'):'n'};
}
}
},
"types": {
"valid_children" : [ "nameServer" ],
"types" : {
"nameServer": {
"icon": {"image":"/corba_browser/static/images/drive.png"},
"valid_children" : [ "default" ],
},
"global": {
"icon": {"image":"/corba_browser/static/images/globe.png"},
"valid_children" : [ "default" ]
},
"object": {
"icon": {"image":"/corba_browser/static/images/alien.png"},
"valid_children" : [ "default" ]
},
"default" : {"valid_children" : [ "default" ]}
}
}
}).bind("loaded.jstree", function (event, data) {
jQuery("li").css('line-height', "15pt");
jQuery("li").css('font-size', "12pt");
}).bind("open_node.jstree close_node.jstree", function (e,data) {
jQuery("li").css('line-height', "15pt");
jQuery("li").css('font-size', "12pt");
var currentNode = data.args[0];
if(e.type === "close_node") {
currentNode.addClass("to-be-refreshed");
}
if(e.type === "open_node") {
if (currentNode.attr('ns')!='none') {
if (currentNode.hasClass("to-be-refreshed")) {
var tree = $.jstree._reference("#JsonTree");
tree.refresh(currentNode);
}
}
}
});
};

ActiveRecord relation with nested objects to JSON

I'm using ActiveRecord with Sinatra. I have AR relation Post has_many Comments.
I need to create response in JSON that returns all posts and their comments. It should look like this:
[
{
"id":1,
"title:"Title_1",
"comments":[
{ "content":"lorem ipsum", "post_id":1 },
{ "content":"foo bar", "post_id":1 },
]
},
{
"id":2,
"title:"Title_2",
"comments":[
{ "content":"lorem ipsum", "post_id":2 },
{ "content":"foo bar", "post_id":2 },
]
}
]
I think it common task to create response like that, so I hope there should be some nice way to do it.
My temporary solution (the code below) works correctly but it too long and unreadable:
Post.all.map{|x| x.as_json(include: [:comments]).values[0] }.to_json
This is another solution that I found:
Post.all.as_json(include: [:comments]).to_json
Sadly, the returned structure looks different, it wraps every post into additional node "post: {}". I'd like to avoid it.
[
{
"post":{
"id":1,
"title:"Title_1",
"comments":[
{ "content":"lorem ipsum", "post_id":1 },
{ "content":"foo bar", "post_id":1 },
]
}
},
{
"post":{
"id":1,
"title:"Title_2",
"comments":[
{ "content":"lorem ipsum", "post_id":2 },
{ "content":"foo bar", "post_id":2 },
]
}
}
]
try:
ActiveRecord::Base.include_root_in_json = false
http://apidock.com/rails/ActiveRecord/Serialization/to_json

jsTree - loading subnodes via ajax on demand

I'm trying to get a jsTree working with on demand loading of subnodes. My code is this:
jQuery('#introspection_tree').jstree({
"json_data" : {
"ajax" : {
url : "http://localhost/introspection/introspection/product"
}
},
"plugins" : [ "themes", "json_data", "ui" ]
});
The json returned from the call is
[
{
"data": "Kit 1",
"attr": {
"id": "1"
},
"children": [
[
{
"data": "Hardware",
"attr": {
"id": "2"
},
"children": [
]
}
],
[
{
"data": "Software",
"attr": {
"id": "3"
},
"children": [
]
}
]
]
}
.....
]
Each element could have a lot of children, the tree is going to be big. Currently this is loading the whole tree at once, which could take some time. What do I have to do to implement on-demand-loading of child-nodes when they are opened by the user?
Thanks in advance.
Irishka pointed me in the right direction, but does not fully resolve my problem. I fiddled around with her answer and came up with this. Using two different server functions is done only for clarity. The first one lists all products at top level, the second one lists all children of a given productid:
jQuery("#introspection_tree").jstree({
"plugins" : ["themes", "json_data", "ui"],
"json_data" : {
"ajax" : {
"type": 'GET',
"url": function (node) {
var nodeId = "";
var url = ""
if (node == -1)
{
url = "http://localhost/introspection/introspection/product/";
}
else
{
nodeId = node.attr('id');
url = "http://localhost/introspection/introspection/children/" + nodeId;
}
return url;
},
"success": function (new_data) {
return new_data;
}
}
}
});
The json data returned from the functions is like this (notice the state=closed in each node):
[
{
"data": "Kit 1",
"attr": {
"id": "1"
},
"state": "closed"
},
{
"data": "KPCM 049",
"attr": {
"id": "4"
},
"state": "closed"
},
{
"data": "Linux BSP",
"attr": {
"id": "8"
},
"state": "closed"
}
]
No static data is needed, the tree is now fully dynamic on each level.
I guess it would be nice to display by default first level nodes and then the children will be loaded on demand. In that case the only thing you have to modify is to add "state" : "closed" to the nodes whose child nodes are going to be loaded on demand.
You might wish to send node's id in ajax call so you modify your code
"json_data": {
//root elements to be displayed by default on the first load
"data": [
{
"data": 'Kit 1',
"attr": {
"id": 'kit1'
},
"state": "closed"
},
{
"data": 'Another node of level 1',
"attr": {
"id": 'kit1'
},
"state": "closed"
}
],
"ajax": {
url: "http://localhost/introspection/introspection/product",
data: function (n) {
return {
"nodeid": $.trim(n.attr('id'))
}
}
}
}
From jsTree documentation
NOTE:
If both data and ajax are set the initial tree is rendered from the data string. When opening a closed node (that has no loaded children) an AJAX request is made.
you need to set root elements as tree data on page load and then you will be able to retrieve their children with an ajax request
$("#introspection_tree").jstree({
"plugins": ["themes", "json_data", "ui"],
"json_data": {
//root elements
"data": [{"data": 'Kit 1', "attr": {"id": 'kit1'}} /*, ... */], //the 'id' can not start with a number
"ajax": {
"type": 'POST',
"data": {"action": 'getChildren'},
"url": function (node) {
var nodeId = node.attr('id'); //id="kit1"
return 'yuorPathTo/GetChildrenScript/' + nodeId;
},
"success": function (new_data) {
//where new_data = node children
//e.g.: [{'data':'Hardware','attr':{'id':'child2'}}, {'data':'Software','attr':{'id':'child3'}}]
return new_data;
}
}
}
});
See my answer to a similar question here (the old part) for more details
I spended hours on this problem. Finally i got it that way:
$("#resourceTree").jstree({
"types": {
"default": {
"icon": "fa fa-folder-open treeFolderIcon",
}
},
"plugins": ["json_data", "types", "wholerow", "search"],
"core": {
"multiple": false,
"data": {
"url" : function(node){
var url = "rootTree.json";
if(node.id === "specialChildSubTree")
url = "specialChildSubTree.json";
return url;
},
"data" : function(node){
return {"id" : node.id};
}
}
},
});
rootTree.json:
[
{
"text": "Opened root folder",
"state": {
"opened": true
},
"children": [
{
"id" : "specialChildSubTree",
"state": "closed",
"children":true
}
]
}
]
specialChildSubTree.json:
[
"Child 1",
{
"text": "Child 2",
"children": [
"One more"
]
}
]
So i mark the node that become the parent of the ajax loaded subtree with an id, i watch for in the core configuration.
NOTE:
That node must have the "state" : "closed" parameter and it must have
the parameter "children" : true.
I am using jsTree.js in version 3.3.3
Above solution is all fine. Here I am also providing similar working solution and very simple for lazy loading of nodes using ajax call vakata. When your API works like
https://www.jstree.com/fiddle/?lazy
and for getting any child nodes
https://www.jstree.com/fiddle/?lazy&id=2
for explanation and for complete solution you can have a look at https://everyething.com/Example-of-jsTree-with-lazy-loading-and-AJAX-call
<script type="text/javascript">
$(function () {
$('#SimpleJSTree').jstree({
'core' : {
'data' : {
'url' : "https://www.jstree.com/fiddle/?lazy",
'data' : function (node) {
return { 'id' : node.id };
}
}
}
});
});
</script>

AJAX call to REST service doesn't display results in page but a call to the same response in a flat file does

I'm trying to make a call to WCF Data Services and display the results in a GridPanel.
The call works and returns the correct JSON except the GridPanel doesn't display any results.
I tried copying the returned json into a file also on the webserver and replacing the destination url for that. This worked correctly and displays the results.
So as far as I can tell the JSON, the code and the service are all correct but they don't work together properly.
The Ext JS
Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: ['Id', 'CustomerName'],
proxy: {
headers: {
'Accept' : 'application/json'
},
type: 'rest',
url: 'Service.svc/Customers',
reader: {
type: 'json',
root: 'd'
}
}
});
The JSON back from the service
{
"d" : [
{
"__metadata": {
"uri": "http://localhost:52332/testservice.svc/Customers(1)",
"type": "PierbridgeShinePlatformTestModel.Customer"
},
"Id": 1,
"CustomerName": "fred",
"Invoices": {
"__deferred": {
"uri": "http://localhost:52332/testservice.svc/Customers(1)/Invoices"
}
}
},
{
"__metadata": {
"uri": "http://localhost:52332/testservice.svc/Customers(2)",
"type": "PierbridgeShinePlatformTestModel.Customer"
},
"Id": 2,
"CustomerName": "Mr Fred",
"Invoices": {
"__deferred": {
"uri": "http://localhost:52332/testservice.svc/Customers(2)/Invoices"
}
}
}
]
}

Resources