jstree get data after update - javascript

I pass some json data in jstree and then I update the tree.
For example my initial data is
[
{ "id" : "demo_root_1", "text" : "Root 1", "children" : true, "type" : "root" },
{ "id" : "demo_root_2", "text" : "Root 2", "type" : "root" }
]
I update it a little (simple rename). "Root 1" becomes "UPDATED". How can I get the updated version of my data in json format like below?
[
{ "id" : "demo_root_1", "text" : "UPDATED", "children" : true, "type" : "root" },
{ "id" : "demo_root_2", "text" : "Root 2", "type" : "root" }
]

Okay..so basically if you want to refresh the tree with the updated data, then after the updation code, call the jstree callback:
$(tree).jstree('refresh');
This will refresh the tree with the new json data.
let me know in case of further issues.

Related

"Evaluate" Function that is stored in MongoDB Server

My collection looks like this:
> db.projects_columns.find()
{ "_id" : "5b28866a13311e44a82e4b8d", "checkbox" : true }
{ "_id" : "5b28866a13311e44a82e4b8e", "field" : "_id", "title" : "ID", "sortable" : true }
{ "_id" : "5b28866a13311e44a82e4b8f", "field" : "Project", "title" : "Project", "editable" : { "title" : "Project", "placeholder" : "Project" } }
{ "_id" : "5b28866a13311e44a82e4b90", "field" : "Owner", "title" : "Owner", "editable" : { "title" : "Owner", "placeholder" : "Owner" } }
{ "_id" : "5b28866a13311e44a82e4b91", "field" : "Name #1", "title" : "Name #1", "editable" : { "title" : "Name #1", "placeholder" : "Name #1" } }
{ "_id" : "5b28866a13311e44a82e4b92", "field" : "Name #2", "title" : "Name #2", "editable" : { "title" : "Name #2", "placeholder" : "Name #2" } }
{ "_id" : "5b28866a13311e44a82e4b93", "field" : "Status", "title" : "Status", "editable" : { "title" : "Status", "type" : "select", "source" : [ { "value" : "", "text" : "Not Selected" }, { "value" : "Not Started", "text" : "Not Started" }, { "value" : "WIP", "text" : "WIP" }, { "value" : "Completed", "text" : "Completed" } ], "display" : "function (value, sourceData) { var colors = { 0: 'Gray', 1: '#E67C73', 2: '#F6B86B', 3: '#57BB8A' }; var status_ele = $.grep(sourceData, function(ele){ return ele.value == value; }); $(this).text(status_ele[0].text).css('color', colors[value]); }", "showbuttons" : false } }
You can see that in the very last document that I have stored a function as text.Now the idea is that I will request this data and will be in an Javascript Array format.
But I want to be able to have my function without the quotes! You can see that simply evaluating it will not work because I need to have it still needs to be inside of the object ready to be executed when the array is used.
How can I achieve this?
Thanks for any help!
There are two possible solutions, but neither particularly safe and you should strongly consider why you need to store functions as strings in the first place. That being said, you could do two things.
The simplest is to use eval. To do so, you would have to first parse the object like normal, and then set the property that you want to the result of eval-ing the function string, like so:
// Pass in whatever JSON you want to parse
var myObject = JSON.parse(myJSONString);
// Converts the string to a function
myObject.display = eval("(" + myObject.display + ")");
// Call the function with whatever parameters you want
myObject.display(param1, param2);
The additional parentheses are to make sure that evaluation works correctly. Note, that this is not considered safe by Mozilla and there is an explicit recommendation not to use eval.
The second option is to use the Function constructor. To do so, you would need to restructure your data so that you store the parameters separately, so you could do something like this:
var myObject = JSON.parse(myJSONString);
// displayParam1 and displayParam2 are the stored names of your parameters for the function
myObject.display = Function(myObject.displayParam1, myObject.displayParam2, myObject.display)
This method definitely takes more modification, so if you want to use your existing structure, I recommend eval. However, again, make sure that this is absolutely necessary because both are considered unsafe since outside actors could basically inject code into your server.

Add new element to array with setState

How to add new element to array with setState
I have this data
this.state = {
items : [
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" },
{ "id" : "24", "parent" : "dwdw", "text" : "Root node" },
{ "id" : "55", "parent" : "ajson2", "text" : "Ch" },
{ "id" : "9866", "parent" : "ajson2", "text" : "oiiojio" },
]
}
I'm mapping the data
{this.state.items.sort((a,b) => a.newID < b.newID).map((item)=>
<ul>
<li key={item.id}><span>ID: </span>{item.id} <span>parent: </span>{item.parent} <span>text: </span>{item.text}</li>
</ul>
)}
and then I'm sorting the data by newID That I need to create it with setState
this.setState(prevState=>({newData: [...prevState.items, this.props.account.info]}));
How can I create new element with this.props.account.info add somthing like i++ I don't know actually
this.props.account.info It's adding data like
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So I need to add an element inside this will be like
{ "newID": "1", "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So if you want to add "newID" field in the object, there is a way to do this using object spread operator.
{...this.props.account.info, "newID":"1"}
This will give you a new object with the "newID" field added with "1" as its value associated with it.
This is a shorthand for this:
Object.assign({}, this.props.account.info, {"newID": "1"});

Get all parent documents in a mongoDB model tree structure

I'm using a model tree structure for my collection. As references I'm using parent-fields. I need to get attributes from the current object and all its parents. The last element in a path has a field 'target'. So I start with
var result = parent = Articles.findOne({target: this.params._id});
do {
parent = Articles.findOne({_id: parent.parent}).parent;
for (var attrname in parent) { result[attrname] = parent[attrname]; }
}
while (parent.parent === null);
That seems to be very inefficient to me. Isn't it possible to do that with one line to get an object with all elements? Then I could process that object.
Example documents
{
"_id" : "LD6h5ZcDuJjexfKfx",
"title" : "title",
"publisher" : "public",
"author" : "author"
}
{
"_id" : "KSiyh8zHRq8RZQ2E6",
"edition" : "edition",
"year" : "2020",
"parent" : "LD6h5ZcDuJjexfKfx"
}
{
"_id" : "5yCk4y25wrLBLZhyY",
"pageNumbers" : "1-10",
"target" : "9sjhzPhyTuQ5Kbh6v",
"parent" : "KSiyh8zHRq8RZQ2E6"
}
So starting with "target" : "9sjhzPhyTuQ5Kbh6v" I would like to get the two parent documents (in this example).
At least I need the dataset
"title" : "title",
"publisher" : "public",
"author" : "author",
"edition" : "edition",
"year" : "2020",
"pageNumbers" : "1-10"
If you want to do this in a single query then you need to follow the array of ancestors pattern in Mongodb. Otherwise you need to recursively traverse the branches above the leaf node as you are doing. For hierarchies with low depth such as yours this is not a big penalty.
With an array of ancestors your doc tree would look like:
{
"_id" : "LD6h5ZcDuJjexfKfx",
"title" : "title",
"publisher" : "public",
"author" : "author",
}
{
"_id" : "KSiyh8zHRq8RZQ2E6",
"edition" : "edition",
"year" : "2020",
"ancestors" : ["LD6h5ZcDuJjexfKfx"],
"parent" : "LD6h5ZcDuJjexfKfx"
}
{
"_id" : "5yCk4y25wrLBLZhyY",
"pageNumbers" : "1-10",
"target" : "9sjhzPhyTuQ5Kbh6v",
"ancestors" : ["LD6h5ZcDuJjexfKfx","KSiyh8zHRq8RZQ2E6"],
"parent" : "KSiyh8zHRq8RZQ2E6"
}
To get the doc and its parents:
Articles.find({ $or: [ { target: target },
_id: { $in: Articles.findOne({ target: target }).ancestors }]});

Tree Layout - Links - Data Formatting

I am working on a project where I want to show how various files within a website interact with each other. I thought that this would be a fairly simple task using D3, but now I am wondering about how my json data is arranged. Here is a sample of my data :
{
"pages" : [{
"ID" : "1",
"name" : "config.xml",
"class" : "dvs",
"path" : "/config.xml",
"children" : [{"dvs":"2","dvs":"3","sites":"4","sites":"5"}]
},{
"ID" : "2",
"name" : "site-pages.xml",
"class" : "dvs",
"path" : "/pages/site-pages.xml",
"children" : [{"dvs":"1"}]
},{
"ID" : "3",
"name" : "customscripts.vm",
"class" : "sites",
"path" : "components/customscripts.vm",
"children" : [{"dvs":"1","sites":"4","sites":"5"}]
},{
"ID" : "4",
"name" : "badge.vm",
"class" : "sites",
"path" : "components/badge.vm",
"children" : [{"dvs":"1","sites":"3"}]
},{
"ID" : "5",
"name" : "price.vm",
"class" : "sites",
"path" : "components/price.vm",
"children" : [{"dvs":"1","sites":"3"}]
}]
}
My plan was to use the ID's to show links between files and the classes to color code the types of files. When I started looking into d3.layout.tree() I started to realize that the layouts seem to be very dependant on having a specific data model, namely :
{ "name" : "foo",
"children" : [{
"name" : "bar",
"children" : [{
}]
}]
}
etc, etc, etc
Am I correct in thinking that the data being passed into d3.layout.tree() has to match that exact format?
Ultimately, I was hoping that I would be able to make each node of my data tree clickable, which would turn that node into the root node of the graph, but maybe that is just not possible?
Any guidance/advice on data formatting and the d3.layout.tree() would be much appreciated.
As for your desire to make a selected node the new root of the tree, I unearthed this fiddle that I started putting together sometime ago. It is simple minded and much can be done to improve it but it should provide you with a reasonable start.
function click(d) {
update(d.depth == 0 ? root : d)
}

java.lang.ClassCastException calling RedQueryBuilderFactory.create with args

This line in my JS file:
RedQueryBuilderFactory.create(config,
'SELECT "x0"."title", "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."status" = (?))',
[]
);
works fine witih an empty array as the 3rd parameter. This parameter is supposed to be an array of strings according to the documentation and any sample code I can find. When I pass a string in the array it fails:
RedQueryBuilderFactory.create(config,
'SELECT "x0"."title", "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."status" = (?))',
['in_process']
);
I get java.lang.ClassCastException in the Safari console. Here's the related part of the config if it's relevant:
var config = {
meta : {
tables : [ {
"name" : "ticket",
"label" : "Ticket",
"columns" : [ {
"name" : "title",
"label" : "Title",
"type" : "STRING",
"size" : 255
}, {
"name" : "priority",
"label" : "Priority",
"type" : "REF"
} ],
fks : []
} ],
types : [ {
"name" : "REF",
"editor" : "SELECT",
"operators" : [ {
"name" : "IN",
"label" : "any of",
"cardinality" : "MULTI"
}]
} ]
}
};
Looks like this is a bug in passing in parameter values. Internally it is expecting a collection but this is not happening.
Best if you raise a https://github.com/salk31/RedQueryBuilder bug report here?
NB Should be "IN" not "="

Categories

Resources