jstree refresh tree with response data - jstree

My first question why I cant get into 'check_node.jstree' event although I check a checkbox in tree..
And second. Here is my tree definition each time I click expand button which trigger 'before_open.jstree' event and refresh tree with new datas.. but after it rebuild tree it triggs the the event again and post to server.. how can I just refresh tree then stop the work.
$('#tree_2').jstree({
'plugins': ["checkbox","types","json_data" ,"ui"],
'core': {
"themes" : {
"responsive": true,
"icons":true
},
'data': [{}]
},
"types" : {
"default" : {
"icon" : "fa fa-folder icon-state-warning icon-lg"
},
"file" : {
"icon" : "fa fa-file icon-state-warning icon-lg"
}
}
}).bind('check_node.jstree', function (e, data) {
debugger
alert("check_node.jstree")
}).bind('before_open.jstree', function (e, datap) {
$.ajax({
url: "../../Controller/ActiveDirectoryController.php5",
type: "POST",
dataType: "json",
data: datap.node.text,//selected node text
success: function (result) {
debugger
if(result.Objects.length>0)
{
passOpen=false;
treeData_ = prepareObjectsforTree(result.Objects);
resfreshJSTree(treeData_);
}
},
error: function (a, b, c) {
}
})
})
and rebuild jstree with response data:
function resfreshJSTree(treeDataa) {
$('#tree_2').jstree(true).settings.core.data = treeDataa;
$('#tree_2').jstree("refresh");
}

check_node.jstree will only fire if checkbox.tie_selection is set to false in your config. If it is not - listen for select_node.jstree (or changed.jstree).
As for the second question - do not implement lazy loading this way - please read the docs on lazy loading - that is not the way to achieve it.

Related

jsTree cancel Create node

I'm using context menu is jsTree and here's my code:
"contextmenu" : {
"items": function ($node) {
return {
"create": {
"separator_before": false,
"separator_after": false,
"label": "Créer",
"action": function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.create_node(obj, {}, "last", function (new_node) {
new_node.type = "child";
setTimeout(function () {
inst.edit(new_node);
}, 0);
});
}
},
"Rename": {
"separator_before": false,
"separator_after": false,
"label": "Renommer",
"action": function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.edit(obj);
}
},
"Remove": {
"separator_before": false,
"separator_after": false,
"label": "Supprimer",
"action": function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.delete_node(obj);
}
}
};
}
},
If I am renaming a node and I decide to cancel it, I just press the escape button and the node returns to its previous name.
If I want to create a node, it creates the node first and put it into editing mode. Now if I press escape, the editing mode is exited but the node remains. What I want to accomplish is if I'm in creation mode, and I press escape, it should remove the newly created node.
Any ideas on how I can do this?
The node edit function itself accepts a callback as a second argument. The callback function when called, receives a boolean flag indicating if the user cancelled the edit.
inst.edit(new_node,"New node",function(node,bStatus,bCancelled){
if(bCancelled){
this.delete_node(node);
}
});
The current node and the instance is also returned which can be used to delete the node.
Reference: https://www.jstree.com/api/#/?q=edit

jsTree component background menu?

In jsTree component available a ContextMenu plugin.
But it's available only when user clicked on specific node.
I need to add context menu by clicking on component's background (to add root nodes, for example).
Is it possible to attach a context menu plugin for background ?
Yes you can, but you need to define all actions you need to be available, as the defaults are related to a node, so they won't work (rename, delete, etc).
This will show a menu when the tree container is clicked and will show an option to create a root node:
$('#tree').on('contextmenu.jstree', function (e) {
e.preventDefault();
if($(e.target).is('#tree')) {
$(document).one("context_show.vakata.jstree", $.proxy(function (e, data) {
var cls = 'jstree-contextmenu jstree-default-contextmenu';
$(data.element).addClass(cls);
}, this));
$.vakata.context.show($(this), { 'x' : e.pageX, 'y' : e.pageY }, {
"create" : {
"separator_before" : false,
"separator_after" : false,
"_disabled" : false,
"label" : "Create",
"action" : function (data) {
var inst = $.jstree.reference(e.target);
inst.create_node(null, {}, "last", function (new_node) {
setTimeout(function () { inst.edit(new_node); },0);
});
}
}
});
}
});

SAPUI5 custom pseudo-event

What are the best practices for defining a custom pseudo-event in SAPUI5/OpenUI5?
For example, let's say I wanted to fire an event on an extended sap.m.Button when pressed and held for several seconds.
I'm not sure if there are yet any 'best practices', I really think there's only 'one' practice ;-) But I'm eager to learn any other takes, so if anyone can comment on this, please do not hesitate!
I think the general idea is just to define your event; the UI5 framework then automatically generates methods for registering (attach<YourEvent>), deregistering (detach<YourEvent>), and firing events (fire<YourEvent>).
For example:
return ControlToExtend.extend("your.custom.Control", {
metadata: {
properties: {
// etc...
},
aggregations: {
"_myButton": {
type: "sap.m.Button",
multiple : false,
visibility: "hidden"
},
// etc...
},
associations: {
// etc...
},
events: {
yourCustomEvent: {
allowPreventDefault: true,
parameters: {
"passAlong": { type: "string" }
}
}
}
},
init: function() {
ControlToExntend.prototype.init.apply(this, arguments);
var oControl = this, oMyButton;
oMyButton = new Button({ // Button required from "sap/m/Button"
// ...,
press: function (oEvent) {
oControl.fireYourCustomEvent({
passAlong: "Some dummy data to pass along"
});
}
});
this.setAggregation("_myButton", oMyButton);
},
// etc...
});
Hope this explains a bit.
For custom events, you can wrap jquery events
So, use a general pattern like this can be followed:
events: {
someEvent: {}
}
onBeforeRendering
var domNode = this.getDomRef();
$(domNode).unbind('someEvent')
onAfterRendering
var self = this, domNode = this.getDomRef();
$(domNode).bind('someEvent', function() {
self.fireSomeEvent({
customProp: customValue
})
});
A client of the control can do things like:
new CustomControl({
someEvent: function( o ) {
alert('customProp: ' + o.getParameter('customProp'));
}
})
The recommendation / best practice is to register the event using such as jQuery.bind (and remove using jQuery.unbind() to avoid memory leak).
Find additional information (copied from Tim's comment): https://sapui5.netweaver.ondemand.com/sdk/#docs/guide/91f1b3856f4d1014b6dd926db0e91070.html
........
Good Luck

Select2 with AJAX and Initial Local Data

So I'm trying to get the select2 plugin to work with a Backbone.js / CakePHP app. The idea is that this select2 holds email addresses for contacting people as tasks become completed, but the form is editable. What I want to do is (1) load / display all the already saved email addresses for the task being edited, and (2) I want to still have the select2 perform AJAX searches to list recognized emails.
I keep having this issue where I can either show initial data, OR have the AJAX search feature.
My current code for my select2 box is a Backbone.View, and it looks like:
define([
'backbone',
'jquery',
'jquery.select2'
],
function(Backbone, $, select2) {
var notificationSelector = Backbone.View.extend({
notifications: undefined,
events: {
'change' : 'select2ContactsChanged'
},
initialize: function(attrs) {
this.collection.on('add remove reset', this.render(), this);
this.select2ContactsChanged();
},
render: function() {
var contacts = ["abc#def.com", "joe#banana.com"];
$('.notification-selector').attr('value', contacts);
if(this.select2Control == undefined)
{
// Do Search() + query here
this.select2Control = this.$el.select2({
width: '200px',
placeholder: '#email',
tags: [],
minimumInputLength: 3,
// initSelection: function(element, callback) {
// return $.ajax({
// type: "GET",
// url: "/notifications/fetch/",
// dataType: 'json',
// data: { id: (element.val()) },
// success: function(data) {
// }
// }).done(function(data) {
// console.log(data);
// });
// },
});
}
else
{
// Do Search() + query here
this.select2Control = this.$el.select2({
width: '200px',
placeholder: '#email',
tags: [],
minimumInputLength: 3,
ajax: {
url: '/notifications/search/',
dataType: 'json',
data: function(term, page) {
return {
SearchTerm: term
};
},
results: function(data, page) {
return {
results: data
};
}
}
});
}
},
select2ContactsChanged: function() {
var contacts = this.select2Control.val().split(',');
this.collection.reset(contacts);
}
});
return notificationSelector;
});
I read a response by the creator of Select2 to someone else (https://github.com/ivaynberg/select2/issues/392) in which he says to use a 'custom query' to achieve what seems to be what I want. I'm having trouble finding relevant examples or making enough sense of the docs to figure out what he means.
Can anyone spot what I'm doing wrong / missing?
Thanks for your time!
EDIT
I forgot to mention -- the DOM element this is attached to is <input type="hidden" multiple="true" class="notification-selector select2-result-selectable"></input>
Ok, I finally figured out the solution.
I was misunderstanding $.ajax() -- I did not really think about it actually being an asynchronous call. My code to check for the data being returned from the call was running before the AJAX actually finished, so I was always getting undefined.
I assigned a variable to the AJAX call, and set "async: false", and it worked perfectly.
fetchSetNotifications: function() {
var addresses = $.ajax({
method: 'GET',
dataType: 'json',
context: $('#notifications'),
url: '/Notifications/fetch/',
async: false,
alert(addresses);
}
The jqXHR object I get in 'addresses' then contains the response data I want in the "responseText" attribute.

jstree - creating foreign draggable object after the tree is initialized

I was able to successfully init all the examples of jsTree, but there was no example on how to create a new div on-the-fly and have it as a legitimate object for dropping into jsTree.
I tried playing a bit with drag_target, dnd_prepare but no luck.
I tried this code:
"dnd" : {
"drop_finish" : function () {
alert("DROP");
},
"drag_check" : function (data) {
alert("drag_check");
if(data.r.attr("id") == "phtml_1") {
return false;
}
return {
after : false,
before : false,
inside : true
};
},
"drag_finish" : function (data) {
alert("DRAG OK");
}
But none of the alert boxes was called.
(I am referring to http://www.jstree.com/documentation of course)
ok I've found my mystake. One set class as 'jstree-draggable' on another div which will serve as the basis for cloning