I want to make ajax call to get data for results nodes. In my sample code (see here) the ajax call is made but the server doesn't return any thing (tested using firebug) But if I use the same url in a web browser I can save the json file.
My questions are:
how to make the ajax call to work so the return values are displayed in jsTree? It works nicely here - search for Using both the data & ajax config options
how to pass the ajax call parameters
one would be the parent/parent name ( basics for the first results node )
second one would be the parent node's name ( login for the first results node)
See my code below or use the fiddle
<html>
<head>
<title>jsTree & ajax</title>
<script type="text/javascript" src="http://static.jstree.com/v.1.0pre/jquery.js"></script>
<script type="text/javascript" src="http://static.jstree.com/v.1.0pre/_docs/syntax/!script.js"></script>
<script type="text/javascript" src="http://static.jstree.com/v.1.0pre/jquery.cookie.js"></script>
<script type="text/javascript" src="http://static.jstree.com/v.1.0pre/jquery.hotkeys.js"></script>
<script type="text/javascript" src="http://static.jstree.com/v.1.0pre/jquery.jstree.js"></script>
<script type='text/javascript'>
data = [
{
"data" : "Basics",
"state" : "closed",
"children" : [ {
"data" : "login",
"state" : "closed",
"children" : [ "login", {"data" : "results", "state" : "closed"} ]
} ,
{
"data" : "Basics",
"state" : "closed",
"children" : [ "login", "something",{"data" : "results", "state" : "closed"} ]
} ]
},
{
"data" : "All",
"state" : "closed",
"children" : [ {
"data" : "AddCustomer",
"state" : "closed",
"children" : [ "login","Add", {"data" : "results", "state" : "closed"} ]
} ]
}
]
$(function () {
$("#jstree").jstree({
"json_data" : {
"data" : data ,
"ajax" : { "url" : "http://www.jstree.com/static/v.1.0pre/_docs/_json_data.json" }
},
"plugins" : [ "themes", "json_data" ]
});
});
</script>
</head>
<body>
<div id="jstree"></div>
</body>
</html>
Update 1
Even I copy the sample code from jstree.com into jsfiddle it won't work. I guess I am missing something somewhere....
Try not to make Ajax calls from your server to another server - this will result in a cross-domain security exception. There are ways around it (JSONP) but it is simpler to just request data from your own server.
Once you've sorted out your ajax request, you probably want to add some attributes to your "results" nodes so that the ajax has some data it can hook into, e.g. IDs. Something like:
"data": "results", "state": "closed", "attr": { "id": "node-123" }
Then you can add a handler for the ajax data option:
"ajax": {
"url": "/my/local/json/",
"data": function(n) {
// get parent / grandparent node
var lists = $(n).parents('ul');
var p = $(lists[0]).prev('a');
var gp = $(lists[1]).prev('a');
// the result is fed to the AJAX request 'data' option
return {
"parent": $.trim(p.text()),
"grandparent": $.trim(gp.text()),
"id": n.attr ? n.attr("id").replace("node-", "") : 1,
};
}
}
This should result in an Ajax request such as: http://myserver/my/local/json/?parent=login&grandparent=Basics&id=123
Hope that helps.
Edit: here's an updated JsFiddle for you: http://jsfiddle.net/robgallen/3uCX3/
Related
This is my HTML Form
<form id="inputform" action="#" method="post">
<input type="text" class="form-control" id="tgl_awal" placeholder="Start Date..." value="2019-05-01" />
<input type="text" class="form-control" id="tgl_akhir" placeholder="End Date..." value="2019-05-15" />
</form>
This is my Jquery code
$("#inputform").submit(function(){
$('#demo-dt-basics').dataTable( {
"ajax": {
"url" : "controller/menu_autodebet.php",
"type" : "POST",
"data" : function ( ) {
return JSON.stringify({
tgl_awal: $("#tgl_awal").val(),
tgl_akhir: $("#tgl_akhir").val()
});
}
},
"columns" : [
{ "data" : "co_brand" },
{ "data" : "tanggal" },
{ "data" : "waktu" },
{ "data" : "no_mc" },
{ "data" : "nama" },
{ "data" : "nomor_peserta" }
]
});
});
And here is the data from php
{"resultCode":"00","resultDesc":"Success","data":{"1":{"co_brand":"jkn","tanggal":"18/03/2019","waktu":"09:16:49","no_mc":"082245326737","nama":"xxxxxx","nomor_peserta":"889980000001118201"},"2":{"co_brand":"jkn","tanggal":"25/03/2019","waktu":"07:34:31","no_mc":"08119235344","nama":"Muhaaa Ryuu","nomor_peserta":"899880172403268601"}}}
The problem is, i can't show the entire data that i've gained from my ajax request. When i use code above, the datatable still showing "No data available in table".
Please help me to figure it out which code that messed up
Your data function in the ajax request is not returning the response back to Datatables.
You would write a normal ajax loaded Datatable as such
$('#demo-dt-basics').DataTable({
ajax: {
url: 'controller/menu_autodebet.php',
dataSrc : ''
},
columns: [
{ "data" : "co_brand" },
{ "data" : "tanggal" },
{ "data" : "waktu" },
{ "data" : "no_mc" },
{ "data" : "nama" },
{ "data" : "nomor_peserta" }
]
});
If you wanted to retrieve the ajax response as well, you would do it like so
$('#demo-dt-basics').DataTable({
ajax: {
url: 'controller/menu_autodebet.php',
dataSrc : function (result) {
//Process result here (e.g. assign to variable)
//You must return the result of the ajax call back to the Datatable constructor
return result;
}
},
columns: [
{ "data" : "co_brand" },
{ "data" : "tanggal" },
{ "data" : "waktu" },
{ "data" : "no_mc" },
{ "data" : "nama" },
{ "data" : "nomor_peserta" }
]
});
This sends the result of the ajax query back to the Datatables constructor, without which, the data will not load.
I'm new to using DataTables and I had it working fine until I wanted to switch to server-side processing.
It feels like I'm starting to get close to it working, it now gives me an error and displays the right amount of rows but without any data.
So I get the error:
DataTables warning: table id=dataTables-outputTest - Requested unknown parameter '0' for row 0. Fore more information about this error, please see https://www.datatables.net/manual/tech-notes/4
This is my js:
$(document).ready( function () {
$('#dataTables-outputTest').DataTable({
"processing": true,
"serverSide": true,
"ajax": "/TestData/data-source"
});
});
This is the JSON I'm trying to put into the table:
{
"data": [
{
"cycle_p": 628320,
"designation": "C1",
"gear": "R660",
"cycle_k": 204000,
"reportnr": "NA05006"
}
],
"draw": "1",
"recordsFiltered": 1,
"recordsTotal": 1
}
Don't know if it matters but I'm using Django and the output is a mix of attributes from different models.
And here are the relevant HTML:
<div class="dataTable_wrapper">
<table class="table table-bordered table-hover" id="dataTables-outputTest">
<thead>
<tr>
<th>Report</th>
<th>Test</th>
<th>Gear</th>
<th>Cycle K</th>
<th>Cycle P</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
Would really appreciate some help since the database has to be able to grow quite a lot without slowing everything down.
You're using Objects in your data, therefore you need to match object properties to table columns using columns.data. See the example below:
$('#dataTables-outputTest').DataTable({
"processing": true,
"serverSide": true,
"ajax": "/TestData/data-source",
"columns": [
{ "data": "cycle_p" },
{ "data": "designation" },
{ "data": "gear" },
{ "data": "cycle_k" },
{ "data": "reportnr" }
]
});
You need to specify which data corresponds to which columns :
$('#dataTables-outputTest').DataTable({
"processing": true,
"serverSide": true,
"ajax": "/TestData/data-source",
columns : [
{ data : "cycle_p" },
{ data : "destination" },
{ data : "gear" },
{ data : "cycle_k" },
{ data : "reportnr" }
]
});
This will produce rows with <td>'s in the order they are declared in columns. If you have another layout, and / or additionally <td>'s that not should receive data from the JSON, you can use columnDefs instead :
columnDefs : [
{ data : "cycle_p", targets : 0 },
{ data : "destination", targets : 8 },
{ data : "gear", targets : 3 },
{ data : "cycle_k", targets : 2 },
{ data : "reportnr", targets : 1 }
]
where target is the column index.
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);
}
}
}
});
};
I've a JSON string:
{
"items": [
{"name": "red" },
{"name": "blue" }
],
"test" : {
"items" :[
{ "name" : "Hello" },
{ "name" : "World" }
]
}
}
How do I print out
<li>Hello</li>
<li>World</li>
I tried with the template below but it doesn't work. It instead prints "Red and blue". I don't have access to change the JSON string, I have to manipulate the template only.
{{#test}}
{{#items}}
<li>{{name}}</li>
{{/items}}
{{/test}}
For some reason, the following code:
<head>
<script src="https://github.com/andyet/ICanHaz.js/raw/master/ICanHaz.js"></script>
<script>
function clicked()
{
ich.addTemplate("user", "{{#test}} {{#items}} <li>{{name}}</li>\n {{/items}} {{/test}}");
document.getElementById("result").innerHTML = ich.user(userData);
}
var userData = {
"items": [
{"name": "red" },
{"name": "blue" }
],
"test" : {
"items" :[
{ "name" : "Hello" },
{ "name" : "World" }
]
}
};
</script>
</head>
<body>
<button onclick="clicked()">CLICK</button>
<ul id="result"><li>Result</li></div>
</body>
gives me exactly:
Hello
World
So, your template should be correct.
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>