I am using jstree with Json. My problem is that I can provide the Json directly into jsTree data, but when I pass it as a variable it will print the entire Json string as the title of one node.
below is nodes.json
{
"id": "ajson1",
"parent": "#",
"text": "Simple root node"
}, {
"id": "ajson2",
"parent": "#",
"text": "Root node 2"
}, {
"id": "ajson3",
"parent": "ajson2",
"text": "Child 1"
}, {
"id": "ajson4",
"parent": "ajson2",
"text": "Child 2"
},
this code below works
request = $.getJSON("nodes.json");
var data;
request.complete(function() {
data = request.responseText;
console.log(data);
$.jstree.defaults.core.themes.responsive = true;
$('#tree').jstree({
plugins: ["checkbox", "sort", "types", "wholerow", "search"],
"types": {
"file": {
"icon": "jstree-file"
}
},
'core': {
'data': [{
"id": "ajson1",
"parent": "#",
"text": "Simple root node"
}, {
"id": "ajson2",
"parent": "#",
"text": "Root node 2"
}, {
"id": "ajson3",
"parent": "ajson2",
"text": "Child 1"
}, {
"id": "ajson4",
"parent": "ajson2",
"text": "Child 2"
}, ]
}
});
});
But this below does not work
request = $.getJSON("nodes.json");
var data;
request.complete(function() {
data = request.responseText;
console.log(data);
$.jstree.defaults.core.themes.responsive = true;
$('#tree').jstree({
plugins: ["checkbox", "sort", "types", "wholerow", "search"],
"types": {
"file": {
"icon": "jstree-file"
}
},
'core': {
'data': [data]
}
});
});
also if you would like to see the code execute I had it hosted on my domain.
http://www.jordanmclemore.com/projects/jstree/test/visual/current.html
In your original question data is a string (since you are using .responseText), to make it work as a variable, you should have used JSON.parse to convert the string to an array of objects.
Best regards,
Ivan
$.jstree.defaults.core.themes.responsive = true;
$('#tree').jstree({
plugins: ["checkbox", "types"],
"types": {
"file": {
"icon": "jstree-file"
}
},
'core': {
'data': {
'url': function(node) {
return 'nodes.json'
},
'data': function(node) {
return {
'id': node.id
};
}
}
}
});
I just followed Ivan's JSTree API more closely. His API is fantastic and following it closely will save you a lot of headache. ALSO, my json had a trailer comma I beleive and was invalid, so I had to fix that as well. I tested using a json validator.
I know you have already answered your own question, but I'd like to tell what's probably the cause of it anyway.
When looking at nodes.json you provided us with, I'd have to say that it isn't properly formatted as JSON. It is clearly an array, but not formatted as such. Thus you have multiple root elements, which is invalid JSON.
If you'd change nodes.json to this:
[{
"id": "ajson1",
"parent": "#",
"text": "Simple root node"
}, {
"id": "ajson2",
"parent": "#",
"text": "Root node 2"
}, {
"id": "ajson3",
"parent": "ajson2",
"text": "Child 1"
}, {
"id": "ajson4",
"parent": "ajson2",
"text": "Child 2"
}]
And in your javascript:
request = $.getJSON("nodes.json");
var data;
request.complete(function() {
data = request.responseText;
console.log(data);
$.jstree.defaults.core.themes.responsive = true;
$('#tree').jstree({
plugins: ["checkbox", "sort", "types", "wholerow", "search"],
"types": {
"file": {
"icon": "jstree-file"
}
},
'core': {
'data': data
}
});
});
I think your problem would've been solved already.
Since your 'answer' doesn't fix the JSON, I'd say it's the wrong answer, and I advice you to try the things I suggested above.
By the way, a handy tool to validate your JSON with in the future:
http://jsonformatter.curiousconcept.com/
Please note that you may, or may not have to use $.parseJSON(data);
Related
I am making a tokenizer that builds an abstract tree and I want to collect all the "text" from an array that is output by my tokenizer.
Output:
{
"error": false,
"tokens": [
{
"type": "keyword",
"value": "print",
"text": "print"
},
{
"type": "string",
"value": "hello world",
"text": "hello world"
},
{
"type": "keyword",
"value": "var",
"text": "var"
},
{
"type": "keyword_valueof",
"value": "msg",
"text": "msg"
},
{
"type": "operator",
"value": "eq",
"text": "="
},
{
"type": "string",
"value": "secret message",
"text": "secret message"
}...
It should turn out like this:
print "hello world"
var msg = "secret message"
Can you help me, I don't know how to do this.
If you want to extract each value of the "text" to an array, you can use the map() method:
const arr = obj.tokens.map((token) => token.text);
Where 'obj' is the main object (with the "errors" and "tokens" keys).
To print each element of the array in a new line:
arr.forEach(elem => {console.log(elem);});
e.g.:
const obj = {
"error": false,
"tokens": [
{
"type": "...",
"value": "...",
"text": "text 1"
},
{
"type": "...",
"value": "...",
"text": "text 2"
}
]
}
const tokensArr = obj.tokens.map(token => token.text);
tokensArr.forEach(elem => {console.log(elem);});
Is this what you're looking for?
let array = ["secretMessage", "anotherMessage"]; //The array
let theNumberIdOfMessage = 0; //The first item of the array
console.log(array[theNumberIdOfMessage]); //Get the item first in the array and log it
theNumberIdOfMessage = 1; //The second item of the array
console.log(array[theNumberIdOfMessage]); //Log the second item
I'm having problems dislaying events fetched via JSON with Dynamic 'extraParams' parameter as explained here in the Docs:
var calendarEl = document.getElementById('calendar');
calendar = new FullCalendar.Calendar(calendarEl, {
...,
events: {
url: '/getEvents',
method: 'POST',
extraParams: function() {
var combobox = document.getElementById('combobox');
var value = combobox.options[combobox.selectedIndex].value;
return {client: value};
},
failure: function(error) {
console.log(error);
alert("Error", "Unable to fetch events", "red");
},
},
...
});
calendar.render();
On the debug panel, I can see the request made by FullCalendar:
XHR POST https://127.0.0.1:8443/getEvents
With this params:
client: All
start: 2019-09-30T00:00:00Z
end: 2019-11-11T00:00:00Z
timeZone: UTC
And the response:
{
"error": "",
"events": [
{
"allDay": 1,
"color": "blue",
"end": "2019-10-24T00:00:00.000Z",
"extendedProps": {
"company": "Company 1",
"state": "Active",
"type": "task"
},
"groupId": "48",
"id": 27,
"start": "2019-10-23T00:00:00.000Z",
"title": "Title 1",
"url": ""
},
{
"allDay": 1,
"color": "blue",
"end": "2019-11-07T00:00:00.000Z",
"endpoints": 0,
"extendedProps": {
"company": "All",
"description": "Description",
"creationDate": "2019-11-04",
"state": "Active",
"tecnology": "test",
"element": "test 1",
"type": "type 2",
"user": "user 1",
"version": "1.2"
},
"id": 76,
"start": "2019-11-04T00:00:00.000Z",
"title": "Title 2",
"url": ""
}
]
}
But FullCalendar doesn't display this two received events. I don't know what I'm doing wrong.
Regards.
This is happening because your server must return a simple array containing only the events, and nothing else. You're returning a complex object. FullCalendar does not know how to unpack your object and find the "events" property containing the relevant data.
You need to return simply:
[
{
"allDay": 1,
"color": "blue",
"end": "2019-10-24T00:00:00.000Z",
"extendedProps": {
"company": "Company 1",
"state": "Active",
"type": "task"
},
"groupId": "48",
"id": 27,
"start": "2019-10-23T00:00:00.000Z",
"title": "Title 1",
"url": ""
},
{
"allDay": 1,
"color": "blue",
"end": "2019-11-07T00:00:00.000Z",
"endpoints": 0,
"extendedProps": {
"company": "All",
"description": "Description",
"creationDate": "2019-11-04",
"state": "Active",
"tecnology": "test",
"element": "test 1",
"type": "type 2",
"user": "user 1",
"version": "1.2"
},
"id": 76,
"start": "2019-11-04T00:00:00.000Z",
"title": "Title 2",
"url": ""
}
]
from your server, without the rest of it.
I must say that the fullCalendar documentation doesn't make this fact particularly clear.
N.B. I'd argue the "errors" property is superfluous anyway, in any JSON response. If there was an error, you should return a HTTP status code indicating the nature of the error, and a completely different response body indicating whatever you want to tell the user about the error. This would fire the "failure" callback in your JS and allow the browser code to respond appropriately.
So I have a bunch of JSON data and it contains a few fields. for example:
[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
what I'm trying to do is kind of conversion table (from a different JSON file)
if a field has the value 'a' replace it with 'some other text..' etc.
I have a service for the JSON pipeline, so I guess this is the right place to do the replacement.
so for this example, I have the JSON above and in my conversion table I have the following terms:
next: forward,
song: music,
a: option1,
just: from
etc...
What you are looking for can be achieved with templates. Replace the variable sections with some specific markers that you can find and replace from some external tools such as perl or sed.
For example, you could have a template.json with something like this:
...
"type": {
"value": "##VALUE##"
}
...
Then when you need the actual JSON, you could pass this though an intermediate script that replaces these templates with actual data.
cat template.json | sed -e 's/##VALUE##/my_value/' > target.json
Alternatively, with Perl:
cat template.json | perl -pi -e 's:\#\#VALUE\#\#:my_value:' > target.json
The best way is to parse it, replace the text in the object, and then stringify it.
The next best way is to use a regular expression.
In this example, I catch exceptions if path cannot be indexed, and use ['type'] instead of .type so it will scale to indexing 'non-type' if you wish.
const data = `[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
`
const o = JSON.parse(data)
o[0].body.forEach(b => {
try {
if (b.extended.spl['type'].value === 'a') {
b.extended.spl['type'].value = 'CHANGED'
}
} catch (e) {}
})
const newData = JSON.stringify(o, null, 2)
console.log(newData)
A string replace approach will work if you know and can rely on your source conforming, such as the only "value" is inside "type"
const data = `[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
`
const newData = data.replace(/"value": "a"/g, '"value": "NEWVALUE"')
console.log(newData)
i have used $.getJSON for getting json data on pagebeforeshow but it is not working as it have to.
$(document).on('pagebeforeshow', '#inpGrid', function(e) {
alert("inpGrid");
var tat_url = "http://192.168./html5/Demo/json/list.json";
var url = "http://api.openweathermap.org/data/2.5/forecast?lat=35&lon=139&callback=?" ;
$.getJSON(tat_url, function(res) {
console.log(res)
});
});
the code is as above, when using url in $.getJSON it is working, wheras as using tat_url it is not working.
the http://192.168./html5/Demo/json/list.json consists as follows
{
"response": {
"respCode": 0,
"output": {
"delAction": "OP",
"delTmplt": "sibcVizEdit",
"title": "List TATs",
"layout": "grid",
"srvObjRef": "iawme1/IAWMblztnExpert-ListSIBCs_MB1412577249595",
"startIndex": "0",
"recsPerPage": "18",
"noPages": "1",
"curPageNo": "1",
"fieldInfo": [
{
"label": "Name",
"type": "STRING"
}
{
"label": "Alias",
"type": "STRING"
}
{
"label": "Datatype",
"type": "STRING"
}
{
"label": "Default Value",
"type": "STRING"
}
{
"label": "Visibility",
"type": "STRING"
}
],
"records": [
{
"Name": "psngrType"
"Alias": "Pasngr Type"
"Datatype": "STRING"
"Default Value":"CC"
"Visibility": "0"
},
{
"Name": "flightNo"
"Alias": "Flight No"
"Datatype": "STRING"
"Default Value":"$RV_flightNo"
"Visibility": "0"
}
],
"relServices": {
"AServices": [
{
"ref": "IAWMblztnExpert-ListSIBCs-UpdateBizContext_MB",
"title": "Update SIBC",
"desc": "",
"srvRef": "IAWMblztnExpert-ListSIBCs-UpdateBizContext_MB",
"slctdOffsets": "0"
},
{
"ref": "IAWMblztnExpert-ListSIBCs-ListIICsInSIBC_MB",
"title": "List IICs",
"desc": "",
"srvRef": "IAWMblztnExpert-ListSIBCs-ListIICsInSIBC_MB",
"slctdOffsets": "0"
},
{
"ref": "IAWMblztnExpert-ListSIBCs-Deploy SIBC_MB",
"title": "Deploy",
"desc": "",
"srvRef": "IAWMblztnExpert-ListSIBCs-Deploy SIBC_MB",
"slctdOffsets": "0"
}
]
}
}
}
}
Can someone help me please thanks.
Your JSON contain syntax errors, look your ''fieldInfo'' node. You didn't seperate your differents object by ,
Example:
{
"label": "Name",
"type": "STRING"
},
{
"label": "Alias",
"type": "STRING"
}
instead of
{
"label": "Name",
"type": "STRING"
}
{
"label": "Alias",
"type": "STRING"
}
Use online JSON validator if you need check rest of your json file easily : http://jsonlint.com/
I have jstree setup to load all content via ajax and json. Is it possible for the script to execute my ajax/json url and keep sub-searching when possible, if it finds it open all sub nodes until its visible and select it (.jstree-clicked). And is such a feature built in, if not know any where I could start with this? I am not the most fluent at javascript.
Here is my setup:
$("#jstFormMirror").jstree({
"types" : {
"types" : {
"default" : {
"select_node" : function(e) {
this.toggle_node(e);
return true;
}
}
}
},
"ui" : {
"select_limit" : 1,
"selected_parent_close" : "select_parent"
},
"json_data" : {
"progressive_unload" : true,
"ajax" : {
"url" : "/back-end/json/categories.json",
"data" : function (n) {
return { id : n.attr ? n.attr("id") : 0 };
}
}
},
"plugins" : [ "themes", "json_data", "types", "ui" ],
"core": {
"animation": 100
}
}).bind("select_node.jstree", function(event, data) {
$("#category").val($(".jstree-clicked").parent().attr("rel"));
})
And he is a typical json response when the script loads a node:
[
{
"attr": {
"id": "87"
},
"data": {
"title": "Bevel Clusters-Over 350 Designs",
"attr": {
"href": "#",
"rel": "658"
}
},
"state": "closed"
},
{
"attr": {
"id": "394"
},
"data": {
"title": "Bevels, Straight Lines-Over 210 Shapes & Sizes",
"attr": {
"href": "#",
"rel": "321"
}
},
"state": "closed"
}
]
I want to execute:
$("#jstFormCategories").jstree("search", ID_HERE);
For this, DefiantJS is excellent (http://defiantjs.com).
This lib extends the global object JSON with the method "search" and enables you to search a JSON structure with XPath expressions.
To understand how easy XPath (which is a standardised query language) is, check out this tool;
http://www.defiantjs.com/#xpath_evaluator
Here is a working fiddle;
http://jsfiddle.net/hbi99/vV43F/
var data = [
{
"attr": {
"id": "87"
},
"data": {
"title": "Bevel Clusters-Over 350 Designs",
"attr": {
"href": "#",
"rel": "658"
}
},
"state": "closed"
},
{
"attr": {
"id": "394"
},
"data": {
"title": "Bevels, Straight Lines-Over 210 Shapes & Sizes",
"attr": {
"href": "#",
"rel": "321"
}
},
"state": "closed"
}
],
res = JSON.search( data, '//*[id=394]/../data' );
console.log( res[0].title );