Reputation: 2035
Hi am using jsTree and created the below shown Tree
Now i want to disable n th node if (n-1) th node is selected,ie user cant able to select different level of nodes.
eg:
Is it possible to achieve this requirement ????
Thanks in advance
Upvotes: 3
Views: 2454
Reputation: 19163
All the other answers\fiddles listed above works in most scenarios but one. All the above scenarios works fine as long as all the nodes are expanded (becuase once you collapse a node, it is removed from the dom).
Assume you select a node at level three and then you collapse the node at level three and then you select a node at level 1, it system does not un-select level 3 node (as it was removed from dom when node was collapsed) and nodes at level 1 and 3 remains selected.
To fix the issue, I am sending the node an additional field in the JSON call level
which tells you about the current level of the node.
var myTree = $('#tree');
myTree .on('changed.jstree', function(event, data) {
mee.disableTreeNodesAtOtherLevels(event,data,myTree );
});
disableTreeNodesAtOtherLevels(event,data, tree){
var currentlevel = parseInt($('#' + data.node.id).attr('aria-level'));
var selectedNodes = tree.jstree(true).get_selected(true);
for (var i = 0; i < selectedNodes.length; i++) {
if(selectedNodes[i].original.level !== currentlevel){
tree.jstree(true).deselect_node(selectedNodes[i], true);
}
}
}
All this works based on assumption the data you are binding to tree is having a property called level
Upvotes: 0
Reputation: 2035
Solution for the above mentioned requiremnt will be available here in jsFfiddle
Here am listing the features
Here am adding the jquery code
var data = [{"id":"1","text":"India","state":{"opened":false},"parent":"#", "state": { "opened":true } },{"id":"1-1","text":"Banglore", "state": { "opened":true }, "parent":"1"},{"id":"1-1-1","text":"Koramangala","state":{"opened":false},"parent":"1-1"},{"id":"1-1-1-1","text":"Infosys ","state":{"opened":false},"parent":"1-1-1"},{"id":"1-1-1-1-1","text":"D","state":{"opened":false},"parent":"1-1-1-1"},{"id":"1-1-1-1-2","text":"E","state":{"opened":false},"parent":"1-1-1-1"},{"id":"1-1-1-1-3","text":"G","state":{"opened":false},"parent":"1-1-1-1"},{"id":"1-1-1-3","text":"Accenture ","state":{"opened":false},"parent":"1-1-1"},{"id":"1-1-1-3-8","text":"C","state":{"opened":false},"parent":"1-1-1-3"},{"id":"1-1-1-3:9","text":"E","state":{"opened":false},"parent":"1-1-1-3"},{"id":"1-1-2","text":"Electronic City","state":{"opened":false},"parent":"1-1"},{"id":"1-1-2-2","text":"TCS ","state":{"opened":false},"parent":"1-1-2"},{"id":"1-1-2-2-4","text":"C","state":{"opened":false},"parent":"1-1-2-2"},{"id":"1-1-2-2-5","text":"E","state":{"opened":false},"parent":"1-1-2-2"},{"id":"1-1-2-2-6","text":"F","state":{"opened":false},"parent":"1-1-2-2"},{"id":"1-1-2-2-7","text":"G","state":{"opened":false},"parent":"1-1-2-2"},{"id":"1-1-3","text":"WhiteField","state":{"opened":false},"parent":"1-1"},{"id":"1-1-3-4","text":"IBM ","state":{"opened":false},"parent":"1-1-3"},{"id":"1-1-3-4-10","text":"F","state":{"opened":false},"parent":"1-1-3-4"},{"id":"1-1-4","text":"Marathahally","state":{"opened":false},"parent":"1-1"},{"id":"1-1-4-5","text":"Wipro ","state":{"opened":false},"parent":"1-1-4"},{"id":"1-1-4-5-11","text":"G","state":{"opened":false},"parent":"1-1-4-5"},{"id":"1-2","text":"Chennai","state":{"opened":false},"parent":"1"},{"id":"1-2-5","text":"sholinganallur","state":{"opened":false},"parent":"1-2"},{"id":"1-2-6","text":"Tiruvanmiyur","state":{"opened":false},"parent":"1-2"},{"id":"2","text":"UK","state":{"opened":false},"parent":"#"},{"id":"2-3","text":"London","state":{"opened":false},"parent":"2"},{"id":"3","text":"US","state":{"opened":false},"parent":"#"},{"id":"3-4","text":"Texas","state":{"opened":false},"parent":"3"},{"id":"3-5","text":"Washington","state":{"opened":false},"parent":"3"},{"id":"3-6","text":"California","state":{"opened":false},"parent":"3"}]
$.jstree.defaults.core = {};
var currentlevel;
$('#tree')
.on('changed.jstree', function (event, data) {
if( data.action == 'select_node'){
$('#tree').find('li').removeClass('disabled_node');
console.log('select '+ data.node.text);
currentlevel = parseInt( $('#'+data.node.id).attr('aria-level') );
$('#tree').find('li').each( function() {
if($(this).attr('aria-level') > currentlevel) {
$(this).addClass('disabled_node');
// remove checks from levels below
$('#tree').jstree('deselect_node', '#'+this.id);
} else if($(this).attr('aria-level') < currentlevel) {
// remove checks from levels above
$('#tree').jstree('deselect_node', '#'+this.id);
}
});
}
if( data.action == 'deselect_node' && data.event && data.event.type === 'click'){
// if have other checked nodes at same level - do not enable children
if ( $('#tree').find('li:not(#'+data.node.id+')[aria-level="'+currentlevel+'"][aria-selected="true"]').length>0 ) {
return;
}
$('#tree').find('li').each( function() {
if($(this).attr('aria-level') > currentlevel) {
$(this).removeClass('disabled_node');
}
});
}
})
.on('open_node.jstree', function(event, obj ) {
$('#'+obj.node.id).find('li').each( function() {
if($(this).attr('aria-level') > currentlevel) {
$(this).addClass('disabled_node');
}
});
})
.jstree({
"core" : {
"data" : data,
"multiple": true,
"themes": {
"url": true,
"icons": true
}
},
"checkbox" : {
"three_state" : false
},
"conditionalselect" : function (node, event) {
return !$('#'+node.id).hasClass('disabled_node');
},
"plugins" : [ "checkbox","conditionalselect" ]
});
Thanks to nikolay-ermakov
Upvotes: 0
Reputation: 5061
You can use an attribute added by jsTree to all li
elements - the aria-level
attribute. It starts from 1 for root element and spans whole tree showing level for every node.
You will have to do this:
changed
event to disable visible nodes from next level and below and open_node
to update status of to-be disabled nodes previously hidden (non-existent in the DOM till this moment to be exact)conditionalselect
plugin to disallow node selection if node is disabledI kept the currently selected level in var currentlevel
. You should check that it is kept local. Also you can surely optimize the code so it wouldn't repeat enable/disable functionality.
Check demo - JS Fiddle
Upvotes: 2