JQuery Dynatree
is another simple and useful plugin for display tree structures. Additionally it
allows selection of nodes, single selection (radio-button) or multiple selections
(Check-box). A simple multiple choice dynatree can be loaded with a script
similar to this:
$("#dynaTree").dynatree({
checkbox: true,
classNames: { checkbox: "dynatree-checkbox
" },
selectMode: 2,
children: TreeData,
onSelect: function (select, node) {
var
selNodes = node.tree.getSelectedNodes();
var selTitles = $.map(selNodes, function (node) {
return node.data.title;
});
var selKeys = $.map(selNodes, function (node) {
return node.data.key;
});
},
onClick: function (node, event) {
if (node.getEventTargetType(event) == "title") {
node.toggleSelect();
}
},
onKeydown: function (node, event) {
if (event.which == 32) {
node.toggleSelect();
return false;
}
}
});
This tree has selecteMode
set to 2 which enables multiple selections. There is no limit to the number of
selections. So what if we want to limit the number of selections to say, 5? Here’s
how to do it. Every time an click event occurs on the tree onClick function is
called first. Right now it only toggles selection if a title is clicked (we
don’t need to toggle if click event is “checkbox” because it will result a
double toggle). In order to limit selections, what we have to do is get the
number of already selected nodes and if it is greater than or equals to 5 simply
return false. Then it will not call onSelect function which add node to
selected nodes. Here is the code:
$("#dynaTree").dynatree({
checkbox: true,
classNames: { checkbox: "dynatree-checkbox
" },
selectMode: 2,
children: TreeData,
onSelect: function (select, node) {
var selNodes = node.tree.getSelectedNodes();
var selTitles = $.map(selNodes, function (node) {
return node.data.title;
});
var selKeys = $.map(selNodes, function (node) {
return node.data.key;
});
},
onClick: function (node, event) {
var selNodes = node.tree.getSelectedNodes();
var selTitles = $.map(selNodes, function (node) {
return node.data.title;
});
if (node.getEventTargetType(event) == "title") {
if (selTitles.length >= 5 ) {
//disable toggle if selection limit is exceeded
return false;
}
}
else if
(node.getEventTargetType(event) == "checkbox")
{
// disable selection if hospital limit is
exceeded
if (selTitles.length >= 5 ) {
return false;
}
}
},
onKeydown: function (node, event) {
if
(event.which == 32) {
var selNodes = node.tree.getSelectedNodes();
var selTitles
= $.map(selNodes, function (node) {
return node.data.title;
});
if (selTitles.length >= 5 ) {
return false;
}
else{
node.toggleSelect();
return false;
}
}
}
});
Apart from just disabling the selections when limit exceed,
we might want to toggle selection if an already selected node is clicked again
so that we can uncheck one node and select another node in its place. For that,
we need to check whether the clicked node is selected or not. If selected we
can toggle the selection. I modified the code to enable it:
$("#dynaTree").dynatree({
checkbox: true,
classNames: { checkbox: "dynatree-checkbox
" },
selectMode: 2,
children: TreeData,
onSelect: function (select, node) {
var selNodes = node.tree.getSelectedNodes();
var selTitles = $.map(selNodes, function (node) {
return node.data.title;
});
var selKeys = $.map(selNodes, function (node) {
return node.data.key;
});
},
onClick: function (node, event) {
var selNodes = node.tree.getSelectedNodes();
var selTitles = $.map(selNodes, function (node) {
return node.data.title;
});
if (node.getEventTargetType(event) == "title") {
// click on a title
if (selTitles.length >= 5 &&
!node.isSelected()) {
//disable toggle if limit is exceeded and node is not a selected one
return false;
}
else
{
node.toggleSelect();
}
}
else if
(node.getEventTargetType(event) == "checkbox")
{
// click on a checkbox
if (selTitles.length >= 5 &&
!node.isSelected()) {
//disable selection if hospital limit is exceeded and node is not a selected one
return false;
}
}
},
onKeydown: function (node, event) {
if
(event.which == 32) {
var selNodes = node.tree.getSelectedNodes();
var selTitles
= $.map(selNodes, function (node) {
return node.data.title;
});
if (selTitles.length >= 5 &&
!node.isSelected()) {
return false;
}
else{
node.toggleSelect();
return false;
}
}
}
});