I'm a longtime JavaScript coder but new to jQuery. I'm using jsTree and need to change a node name. I've searched for and tried many examples from this site and others, but can't find a solution that works. Basically, I'm trying to change a tree node name but it always renames to 'undefined'. In the following example, whenever a node is selected the text should change.
The block of code that is supposed to make the change is:
$('#catTree')
// listen for event
.on('changed.jstree', function (e, data) {
var node = data.instance.get_node(data.selected[0])
var newText = "Some new text";
$('#catTree').jstree('rename_node', [node , newText] );
})
In case is it something obvious that I'm just missing, here the whole example:
<div id="catTree" class="demo"></div>
<script>
var catData = [
{ "id" : "allCategories", "parent" : "#", "type" : "catRoot", "text" : "All categories" },
{ "id" : "category1", "parent" : "allCategories", "type" : "category", "text" : "Category 1" },
{ "id" : "category2", "parent" : "allCategories", "type" : "category", "text" : "Category 2" },
{ "id" : "category3", "parent" : "allCategories", "type" : "category", "text" : "Category 3" },
]
$.jstree.defaults.core = {
strings : false,
check_callback : true,
animation : 100,
aria_roles : true,
multiple : false,
themes : {
name : false,
url : true,
dots : true,
icons : true,
dir : false
},
base_height : false
};
$('#catTree')
// listen for event
.on('changed.jstree', function (e, data) {
var node = data.instance.get_node(data.selected[0])
var newText = "Some new text";
$('#catTree').jstree('rename_node', [node , newText] );
})
$(function () {
$("#catTree").jstree({
'core' : {
'data' : catData
},
"types" : {
"category" : { "icon" : "none", "max_children" : 1, "valid_children" : ["pasteText"] },
},
"crrm" : {
"move" : {
"check_move" : function (m) {
var p = this._get_parent(m.o);
if(!p) return false;
p = p == -1 ? this.get_container() : p;
if(p === m.np) return true;
if(p[0] && m.np[0] && p[0] === m.np[0]) return true;
return false;
}
}
},
"dnd" : {
"drop_target" : false,
"drag_target" : false
},
"plugins" : [ "themes", "html_data", "crrm", "dnd", "types" ]
});
});
</script>
I'm using jsTree v3.2.1 and jQuery v2.1.4
you don't have to get node because you can access it from data variable.
call rename_node as $('#catTree').jstree('rename_node', data.node, newText) instead of $('#catTree').jstree('rename_node', [node , newText] )
also move your .on code to the main jstree init function
So the code will look like below. See example JS Fiddle.
$(function () {
$("#catTree").on('changed.jstree', function (e, data) {
var newText = "Some new text";
$('#catTree').jstree('rename_node', data.node, newText);
})
.jstree({
'core' : {
'data' : catData
},
"types" : {
"category" : { "icon" : "none", "max_children" : 1, "valid_children" : ["pasteText"] },
},
"crrm" : {
"move" : {
"check_move" : function (m) {
var p = this._get_parent(m.o);
if(!p) return false;
p = p == -1 ? this.get_container() : p;
if(p === m.np) return true;
if(p[0] && m.np[0] && p[0] === m.np[0]) return true;
return false;
}
}
},
"dnd" : {
"drop_target" : false,
"drag_target" : false
},
"plugins" : [ "themes", "html_data", "crrm", "dnd", "types" ]
});
});
Related
Here is MongoDB scheme.
{
"_id" : ObjectId("222222"),
"active" : false,
"amount" : "15%",
"description" : "15% discount",
"name" : "20200628-test",
"policies" : {
"apply" : [
{
"name" : "expiryDate",
"params" : {
"date" : ISODate("2020-07-06T14:59:59.999Z")
}
},
{
"name" : "isApplyCategoryExist"
}
],
"discount" : [],
"conflict" : [
{
"name" : "exclusive"
}
],
"grant" : []
},
"target" : {
"sku" : "",
"products_ids" : [],
"category_ids" : [
ObjectId("11111111")
]
},
"title" : "15% coupon"
}
I want to access date.
For example, "policies.apply.params.date"...
I don't know how to access 'date' to Javascript.
Please let me know...
apply is an array, so you have to give it index which you want to get.
var num = 0; // pick up an array number you want
var date = policies.apply[num].params.date;
Your policies.apply is an array so if you want to access "2020-07-06T14:59:59.999Z", you should do this:
policies.apply[0].params.date
But the "policies.apply[1]" doesn't have params (params.date also) so you can write a function to get date like this:
function get_apply_date(index) {
if(policies.apply[index].params && policies.apply[index].params.date)
return policies.apply[index].params.date;
return undefined; // or null
}
Need help on operation like update,delete,add,upsert,delete on below document of MongoDB.
Below is MongoDB document that exists in temp collection.
{
"local_id" : "1841",
"name_first" : "tiger",
"name_last" : "lion",
"address" : [
{
"id" : 1,
"address_type" : "Home",
"city" : "Delhi",
"country" : "",
"po_box" : ""
},
{
"id" : 2,
"address_type" : "Work",
"city" : "",
"country" : "",
"po_box" : ""
}
],
"email" : [
{
"email_id" : "blah#gmail.com",
"id" : 1,
"type" : "Home"
},
{
"email_id" : "Pearl1#gmail.com",
"id" : 2,
"type" : "Work"
}
],
"phone_number" : [
{
"id" : 1,
"no" : "+911234567890",
"type" : "Mobile"
},
{
"id" : 2,
"no" : "+917894561230",
"type" : "work"
}
]
}`
Now I have some document like below, i want query that will compare,add,update,delete on my above document.
`
{
"local_id" : "1730",
"name_first" : "lion",
"name_last" : "king",
"address" : [
{
"id" : 1,
"address_type" : "Home",
"city" : "Delhi",
"country" : "India",
"po_box" : "110041"
},
{
"id" : 2,
"address_type" : "Work",
"city" : "Delhi-NCR",
"country" : "India",
"po_box" : "110048"
},
{
"id" : 3,
"address_type" : "Work",
"city" : "Delhi-NCR",
"country" : "Indai",
"po_box" : "110048"
}
],
"email" : [
{
"email_id" : "updatethis#gmail.com",
"id" : 1,
"type" : "Home"
},
{
"email_id" : "Pearl1#gmail.com",
"id" : 2,
"type" : "Work"
},
{
"email_id" : "addthisarray#gmail.com",
"id" : 3,
"type" : "personal"
}
],
"phone_number" : [
{
"id" : 1,
"no" : "+911234567890",
"type" : "Mobile"
}
/*second array not here so remove that array from that document*/
]
}`
You can save function on server as you can call that function to get the differences, as below.
db.system.js.save({
_id: "getupdatedArray",
value: function(obj1, obj2) {
var VALUE_CREATED = 'created';
var VALUE_UPDATED = 'updated';
var VALUE_DELETED = 'deleted';
var VALUE_UNCHANGED = 'unchanged';
function map(obj1, obj2) {
if (isValue(obj1) || isValue(obj2)) {
return {
type: compareValues(obj1, obj2),
old: obj1,
new: obj2
};
}
var diff = {};
for (var key in obj1) {
if (isFunction(obj1[key])) {
continue;
}
var value2 = undefined;
if ('undefined' != typeof(obj2[key])) {
value2 = obj2[key];
}
diff[key] = map(obj1[key], value2);
}
for (var key in obj2) {
if (isFunction(obj2[key]) || ('undefined' != typeof(diff[key]))) {
continue;
}
diff[key] = map(undefined, obj2[key]);
}
return diff;
}
function compareValues(value1, value2) {
if (value1 === value2) {
return VALUE_UNCHANGED;
}
if ('undefined' == typeof(value1)) {
return VALUE_CREATED;
}
if ('undefined' == typeof(value2)) {
return VALUE_DELETED;
}
return VALUE_UPDATED;
}
function isFunction(obj) {
return {}.toString.apply(obj) === '[object Function]';
}
function isArray(obj) {
return {}.toString.apply(obj) === '[object Array]';
}
function isObject(obj) {
return {}.toString.apply(obj) === '[object Object]';
}
function isValue(obj) {
return !isObject(obj) && !isArray(obj);
}
return map(obj1, obj2);
}
})
Then you can call function as below..
db.loadServerScripts();
getupdatedArray({"a": "abc"}, {"a": "a111", "b": "bbb"});
This will give you result as below:
{
"a" : {
"type" : "updated",
"old" : "abc",
"new" : "a111"
},
"b" : {
"type" : "created",
"old" : undefined,
"new" : "bbb"
}
}
Thanks
Satish Lakhani
Using AngularJS, say an array $scope.data.children has item with the following structure:
{
"sku" : "<sku>",
"selected" : "<boolean>"
}
Would there be a simple way referencing all selected = true children, ideally represented in $scope.data.components?
So, for example, if
$scope.data.children = [
{"sku" : "A","selected" : "true"},
{"sku" : "B","selected" : "false"},
{"sku" : "C","selected" : "true"},
{"sku" : "D","selected" : "false"}
]
then
$scope.data.components = [
{"sku" : "A","selected" : "true"},
{"sku" : "C","selected" : "true"},
]
and if $scope.data.children is updated to [{"sku" : "D","selected" : "true"}]
then $scope.data.components =,
[
{"sku" : "A","selected" : "true"},
{"sku" : "C","selected" : "true"},
{"sku" : "D","selected" : "true"}
]
$scope.$watch("data.children", setSelected);
var setSelected = function () {
var selected = []
for (var i = 0; i < $scope.data.children; i++) {
if ($scope.data.children[i].selected == "true") {
selected.push($scope.data.children[i];
}
}
$scope.data.components = selected;
}
try to use underscore.js in your project.
it makes your life 500% easier!
and your item.selected value is stored as string, not as boolean.
$scope.data.children = _.filter($scope.data.components, function (item) {
return item.selected == "true";
});
http://underscorejs.org/#filter
I'm somewhat new at web development so I apologize if I am using FSCollection incorrectly.
I have a FS.Collection instance that takes in audio files
LectureAudio = new FS.Collection("lectureAudio", {
stores: [new FS.Store.FileSystem("lectureAudio", {
path:"~/digicog/audioUpload",
filter: {
allow: {
contentTypes: ['audio/*'],
extensions: ['mp3', 'wav', 'MP3', 'WAV']
}
}
})]
});
And I am using an input file element to insert audio files into collection.
Template.audioControl.events({
'change #lecAudioPath': function (event) {
var files = document.getElementById("lecAudioPath").files;
if(files.length != 0){
var lecName = Router.current().params._id;
var audioFile = new FS.File(files[0]);
audioFile.metadata = {LectureId: lecName};
LectureAudio.insert(audioFile);
}
}
});
However when I type in LectureAudio.find().fetch() in the console for testing, I get empty brackets [ ].
Even though when I check my mongo database using:
>db.getCollection("cfs.lectureAudio.filerecord").find()
I see that my collection is populated.
{ "_id" : "wwyQtZZNwicbheCch", "copies" : { "lectureAudio" : { "name" : "fWnQyQpEWSXRDeuJq.mp3" } }, "original" : { "name" : "test1.mp3", "updatedAt" : ISODate("2013-08-16T16:07:40Z"), "size" : 8087475, "type" : "audio/mp3" }, "uploadedAt" : ISODate("2015-03-07T06:05:53.589Z") }
{ "_id" : "3rBbFfnGAT3Z8Bkti", "copies" : { "lectureAudio" : { "name" : "Efn235HcCyGrm5TPx.mp3" } }, "original" : { "name" : "test2.mp3", "updatedAt" : ISODate("2013-08-16T16:07:52Z"), "size" : 8806339, "type" : "audio/mp3" }, "uploadedAt" : ISODate("2015-03-07T06:17:06.234Z") }
{ "_id" : "RJ7LLH7XhgG2PnP9g", "copies" : { "lectureAudio" : { "name" : "fWnQyQpEWSXRDeuJq.mp3" } }, "original" : { "name" : "test3.mp3", "updatedAt" : ISODate("2013-08-16T16:07:52Z"), "size" : 8806339, "type" : "audio/mp3" }, "uploadedAt" : ISODate("2015-03-07T06:18:30.454Z") }
{ "_id" : "9YY33kFFbP7oBMjmr", "copies" : { "lectureAudio" : { "name" : "y7KQmq3ReqcP7Pzyw.mp3" } }, "original" : { "name" : "test4.mp3", "updatedAt" : ISODate("2013-08-16T16:07:40Z"), "size" : 8087475, "type" : "audio/mp3" }, "uploadedAt" : ISODate("2015-03-07T20:50:21.226Z") }
How do I get the collection to show?
You probably forgot to publish and subscribe to the collection.
On the server:
Meteor.publish('lecture_audio', function () {
return LectureAudio.find();
}
And on client:
Meteor.subscribe('lecture_audio');
More info in the docs here
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);