How to get the clicked object in jstree - javascript

Wanted to get the clicked tree object value in javascript
what i'm trying to achieve is when user clicks a tree node then its related data i want to get the original object
here is what i have tried not getting object:
$('#jstree').jstree({
"json_data" : {
"data" : [
{
"data" : "A node",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
},
{
"attr" : { "id" : "li.node.id1" },
"data" : {
"title" : "Long format demo",
"attr" : { "href" : "#" }
}
}
]
},
"plugins" : [ "themes", "json_data", "ui" ]
});
$("#jstree").bind(
"select_node.jstree", function(evt, data){
//selected node object: data.node;
console.log('data',data.inst.get_json());
console.log('data.node.id',data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://old.static.jstree.com/v.1.0pre/jquery.jstree.js"></script>
<div id="jstree">
</div>
Expected Output:
from above snippet, when i click Child 1 or A Child 2 i should get below object
{
"data" : "A node",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
}
when user clicks on Long format demo i should get below object
{
"attr" : { "id" : "li.node.id1" },
"data" : {
"title" : "Long format demo",
"attr" : { "href" : "#" }
}
}
Please help me thanks in advance!!!

As your jstree version is old, I recommend you to update your jstree version. but, as for the 1.0v, You can use below code to get the parent node, if user clicked child one.
$('#jstree').jstree({
"json_data" : {
"data" : [
{
"data" : "A node",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
},
{
"attr" : { "id" : "li.node.id1" },
"data" : {
"title" : "Long format demo",
"attr" : { "href" : "#" }
}
}
]
},
"plugins" : [ "themes", "json_data", "ui" ]
});
$("#jstree").bind(
"select_node.jstree", function(evt, data){
if(data.inst._get_parent().length <= 0 || data.inst._get_parent()===-1){
console.log('data',data.inst.get_json());
console.log('data.node.id',data);
}else{
var parent = data.inst._get_parent();
console.log(data.inst.get_json(parent));
}
//selected node object: data.node;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://old.static.jstree.com/v.1.0pre/jquery.jstree.js"></script>
<div id="jstree">
</div>

Related

Get closest locations in an Array

I have a simple document, which has 3 location objects in an array.
Data:
{
"_id" : ObjectId("57c3c479a306b3613cf1ee5b"),
"location_history" : [
{
"location_name" : "Area 1",
"date" : 1472447609,
"_id" : ObjectId("57c3c479ac5a69612f0e0899"),
"location" : [
24.9532107, 67.1790576
]
},
{
"location_name" : "Area 2",
"date" : 1472448059,
"_id" : ObjectId("57c3c63bac5a69612f0e089c"),
"location" : [
24.9663937, 67.1462044
]
},
{
"location_name" : "Area 3",
"date" : 1472448987,
"_id" : ObjectId("57c3c9dbac5a69612f0e08a0"),
"location" : [
-24.987325, 115.1862298
]
}
}
Question: I need to fetch closest locations in this array.
Query I have tried:
db.getCollection('consumers_locations').aggregate([
{"$unwind": "$location_history"},
{"$match":{"_id":ObjectId("57c3c479a306b3613cf1ee5b")}},
{"$project" : { "abc" : "$location_history.location"} },
{ $geoNear: {
near: { type: "Point", coordinates: [ 24.942785, 67.157855 ] },
distanceField: "distance",
query : {"_id" : "_id"},
uniqueDocs: true,
includeLocs: "search_history.location",
maxDistance : 10000
}
}
])
But I get an error:
"ok" : 0,
"errmsg" : "$geoNear is only valid as the first stage in a pipeline.",
"code" : 2,
"codeName" : "BadValue"
Expected Output:
{
"_id" : ObjectId("57c3c479a306b3613cf1ee5b"),
"location_history" : [
{
"location_name" : "Area 1",
"date" : 1472447609,
"_id" : ObjectId("57c3c479ac5a69612f0e0899"),
"location" : [
24.9532107, 67.1790576
]
},
{
"location_name" : "Area 2",
"date" : 1472448059,
"_id" : ObjectId("57c3c63bac5a69612f0e089c"),
"location" : [
24.9663937, 67.1462044
]
}
}
It is not doable with your schema. Indexes are used to order documents in a collection, not sorting subdocuments within a document.
Consider to create a separate location_history collection with references to the parent document in consumers_locations. E.g. for your object, the collection may look like:
db.getCollection('location_history').insert([
{
"consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
"location_name" : "Area 1",
"date" : 1472447609,
"_id" : ObjectId("57c3c479ac5a69612f0e0899"),
"location" : [
24.9532107, 67.1790576
]
},
{
"consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
"location_name" : "Area 2",
"date" : 1472448059,
"_id" : ObjectId("57c3c63bac5a69612f0e089c"),
"location" : [
24.9663937, 67.1462044
]
},
{
"consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
"location_name" : "Area 3",
"date" : 1472448987,
"_id" : ObjectId("57c3c9dbac5a69612f0e08a0"),
"location" : [
-24.987325, 115.1862298
]
}
]);
Regarding to the error, the docs read:
You can only use $geoNear as the first stage of a pipeline.
since only the first stage can benefit from indexes.

General Tree Post Order Traversal

var tree = {
"name" : "root",
"children" : [
{
"name" : "first child",
"children" : [
{
"name" : "first child of first",
"children" : []
},
{
"name" : "second child of first",
"children" : []
}
]
},
{
"name" : "second child",
"children" : []
}
]
}
function postOrder(root) {
if (root == null) return;
postOrder(root.children[0]);
postOrder(root.children[1]);
console.log(root.name);
}
postOrder(tree);
Heres my code for a recursive post order traversal in javascript using a JSON tree.
How would I go about adapting this code to handle N children in a node?
This should do what you want: just replace your calls to postOrder with root.children.forEach(postOrder);.
var tree = {
"name" : "root",
"children" : [
{
"name" : "first child",
"children" : [
{
"name" : "first child of first",
"children" : []
},
{
"name" : "second child of first",
"children" : []
}
]
},
{
"name" : "second child",
"children" : []
}
]
}
function postOrder(root) {
if (root == null) return;
root.children.forEach(postOrder);
console.log(root.name);
}
postOrder(tree);
I'd also move the line that prints the root name before the call that prints the children names recursively, but this may not match your use case.

MongoDB: Getting document and only one object of an array

I got multiple documents like this:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM",
"timestamp" : 1453731403807,
"message" : "some text",
"name" : "Tom"
},
{
"id" : "BAHx9KeKjuMePce6f",
"timestamp" : 1453731403808,
"message" : "some text",
"name" : "Bob"
},
{
"id" : "ePce6fBAHx9KeKjuM",
"timestamp" : 1453731403809,
"message" : "some text",
"name" : "Tom"
}
]
}
I get this document by using this find-query:
Collection.find({}, { sort: { title: 1 }});
But I don't need the complete notes field. I'm only interested in the id of the last note-object. That means I have to order all notes object by timestamp and just take the first (=newest) one.
I'm not quite sure, if I can do that by the find-query or if I have to do that after getting the complete data.
So the best result for me would be:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM"
}
]
}
You can use the $slice projection to limit the number of array elements returned. For example:
db.collection.find({}, {title: 1, "notes.id": 1, notes: {$slice: 1}}).sort({title: 1});
Will return:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM"
}
]
}

Updating array inside two object in mongod

I have a collection of the structure as follows:
collection name : "positions"
Structure
{
"_id" : "vtQ3tFXg8THF3TNBc",
"candidatesActions" : {
"sourced" : [ ],
},
"appFormObject" : {
"name" : "✶ mandatory",
"questions" : [
{
"qusId" : "qs-585494",
"type" : "simple",
"qus" : "Which was your previous company"
},
{
"qusId" : "qs-867766",
"type" : "yesNo",
"qus" : "Are you willing to relocate?",
"disqualify" : "true"
}
]
}
}
I want to update "qus" field of the above collection whose _id is "vtQ3tFXg8THF3TNBc" and "qusId" is "qs-585494".
Try following....
db.positions.update(
{_id: "vtQ3tFXg8THF3TNBc", "appFormObject.questions.qusId":"qs-585494"},
{$set:{"appFormObject.questions.$.qus": "this is updated value"}}
)
Use following query
db.positions.findAndModify({
query: { _id: "vtQ3tFXg8THF3TNBc", "appFormObject.questions.qusId":"qs-585494"} ,
update: { $set: { 'appFormObject.questions.$.qus': 'Brilliant Green' } },
});
Thanks

jstree - adding child nodes which themselves contain children

I have some code in which I need the ability to add child nodes to a jstree which themselves contain children. The below code adds a 'child2' node correctly to 'child1' but ignores the child3 data. Any help much appreciated. Code follows:
<html>
<head>
<script type="text/javascript" src="http://static.jstree.com/v.1.0rc2/jquery.js"></script>
<script type="text/javascript" src="http://static.jstree.com/v.1.0rc2/jquery.jstree.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function () {
$("#tree").jstree({
"json_data" : {
"data" : [
{
"data" : "parent",
"attr" : { "id" : "root.id" },
"children" : [ { "data" : "child1",
"attr" : { "id" : "child1.id" },
"children" : [ ] }
]
},
]
},
"plugins" : [ "themes", "json_data", "crrm" ]
});
});
$("#add").click(function() {
$("#tree").jstree("create", $("#child1\\.id"), "inside",
{ "data" : "child2", "attr" : { "id" : "child2.id" },
"children" : [ { "data" : "child3", "attr" : { "id" : "child3.id" }, "children": [ ] } ] },
function() { alert("added"); }, true);
});
});
</script>
</head>
<body>
<div id="tree" name="tree"></div>
<input type="button" id="add" value="add" />
</body>
</html>
First off, that's not valid json with the last comma inside the last bracket. Take that off:
[
{
"data" : "parent",
"attr" : {
"id" : "root.id"
},
"children" : [
{
"data" : "child1",
"attr" : {
"id" : "child1.id"
},
"children" : [ ]
}
]
}
]
Also, as of version 3.0 or perhaps before you can simply just insert a new node with json. Recursion is no longer needed.
I created json like so, which creates a folder called income and puts many text children underneath it but also those could be folders just like the parent with more content. See my function below which inserts this folder into the parent with all it's children:
{
"text" : "Income",
"id" : "_folder_income",
"state" : {
"opened" : true
},
"children" : [
{
"text" : "$125,000 - $150,000",
"state" : {
"selected" : true
},
"icon" : "jstree-file",
"id" : "6017897162332"
},
{
"text" : "$150,000 - $250,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6017897374132"
},
{
"text" : "$250,000 - $350,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6017897397132"
},
{
"text" : "$350,000 - $500,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6017897416732"
},
{
"text" : "Over $500,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6017897439932"
},
{
"text" : "$30,000 - $40,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6018510070532"
},
{
"text" : "$100,000 - $125,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6018510083132"
},
{
"text" : "$40,000 - $50,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6018510087532"
},
{
"text" : "$75,000 - $100,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6018510100332"
},
{
"text" : "$50,000 - $75,000",
"state" : {
"selected" : false
},
"icon" : "jstree-file",
"id" : "6018510122932"
}
]
}
This same json could also be used to fill a parent folder on tree instance:
/**
* inserts a new node (json object returned from url) into an existing node (parentNodeId), for the div ud in jsTreeName which is
* an instanced jstree.
* #param string jsTreeName {name of an instanced tree}
* #param string url {returns json}
* #param string parentNodeId {string of the parent node id}
*/
function insertUrlIntoNode(jsTreeName, url, parentNodeId) {
var nodeTree = getSynchronousJson(url);
var tree = $('#'+jsTreeName).jstree(true);
tree.deselect_all();
var sel = tree.create_node(parentNodeId, nodeTree);
//tree.deselect_all();
//tree.select_node(sel); //optionally you could select the new node after insersion
}
As far as I can see from the source, "create" function doesn't support creating multi-level tree at once. The method that gets called doesn't use and check the children attribute on passed data.
You need to do it yourself, something like that :
var recursivelyCreate = function (node, parentNodeId) {
tree.jstree("create", $("#"+parentNodeId), "inside", node, function() {}, true);
if(node.children){
$.each(node.children, function(i, child){
recursivelyCreate(child, node.attr.id);
});
}
};
recursivelyCreate(rootNodeYouWantToInsert,nodeParentId);

Categories

Resources