Mohammed Farooq Mohammed Farooq - 5 months ago 178
jQuery Question

Dynatree - javascript Add Edit & Delete node

Need your help and Thanks alot in advance.

I am trying to do the Add, Edit and delete the node using Dyna tree. Following things am trying.


  1. When i click Add button by selecting any node then new node with textbox to be added and should take node name & on blur it should set value

  2. If no name entered then textbox should disappear from tree node.

  3. If existing nodes then edit the node - This is working.



Some functionalities i have achieved please review below jsfiddle and help me please

Below is my jsfiddle URL , Please help

$(function(){
$("#tree").dynatree({
onActivate: function(node) {
$("#info").text("You activated " + node);
},
children: [
{title: "Item 1"},
{title: "Folder 2", isFolder: true,
children: [
{title: "Sub-item 2.1"},
{title: "Sub-item 2.2"}
]
},
{title: "Item 3"}
],selectMode: 1,
checkbox: true,
onSelect: function(select, node) {
// Display list of selected nodes
var s = node.tree.getSelectedNodes().join(", ");
selectedNode = node;

},


onClick: function(node, event) {
if( event.shiftKey ){
editNode(node);
return false;
}
},
onDblClick: function(node, event) {
editNode(node);
return false;
},
onKeydown: function(node, event) {
switch( event.which ) {
case 113: // [F2]
editNode(node);
return false;
case 13: // [enter]
if( isMac ){
editNode(node);
return false;
}
}
}
});

var nodeExists = false;
var selectedNode = null;
function validateForm(){
if( selectedNode == null){
alert("Please select node to add folder");
return false;
}
if(selectedNode != null){
nodeExists = findNodeByTitle(selectedNode,$("#newFolderName").val());
return nodeExists;
}
}



function findNodeByTitle(tree, title){
var match = true;
tree.visit(function(node){
if(node.data.title == title) {
//match = node.data.title;
alert("Folder : "+title +" already exists")
match = false;
return false;
}
}, true);
return match;
}

function editNode(node){
var prevTitle = node.data.title,
tree = node.tree;
// Disable dynatree mouse- and key handling
tree.$widget.unbind();
// Replace node with <input>
$(".dynatree-title", node.span).html("<input id='editNode' value='" + prevTitle + "'>");
// Focus <input> and bind keyboard handler
$("input#editNode")
.focus()
.keydown(function(event){
switch( event.which ) {
case 27: // [esc]
// discard changes on [esc]
$("input#editNode").val(prevTitle);
$(this).blur();
break;
case 13: // [enter]
// simulate blur to accept new value
$(this).blur();
break;
}
}).blur(function(event){
// Accept new value, when user leaves <input>
var title = $("input#editNode").val();
console.log("onblur",title);
console.log("prevTitle",prevTitle);
if(title == ''){
openChildFunction(selectedNode);
}else{
node.setTitle(title);
// Re-enable mouse and keyboard handlling
tree.$widget.bind();
node.focus();
}


});
}




$("#btnAddCode").click(function(event){
// Sample: add an hierarchic branch using code.
// This is how we would add tree nodes programatically
event.preventDefault();
var node = $("#tree").dynatree("getActiveNode");

if( validateForm()){
var rx = /[<>:"\/\\|?*\x00-\x1F]|^(?:aux|con|clock\$|nul|prn|com[1-9]|lpt[1-9])$/i;
if(rx.test($("#newFolderName").val())) {
alert("Error: Input contains invalid characters!");
return false;
}

var node = $("#tree").dynatree("getActiveNode");
var childNode = selectedNode.addChild({
title: '',
});
$(".dynatree-title", childNode.span).html("<input id='editNode' value=''>");
var dict = $("#tree").dynatree("getTree").toDict();
}


});


});

Code

Jsfiddle tried example

hsh hsh
Answer

Add removeNode function like this to delete the selected node if its empty:

function removeNode(node){
   node.remove();
}

change the blur event like this to call removeNode on empty titles:

.blur(function(event){
      var title = $("input#editNode").val();
      //removes the node if title is empty
      if(title == ""){
         removeNode(node);
         tree.$widget.bind();
         return;
      }
      ....
});

finally change btnAddCode's click event like this to manage adding:

  1. get the selected node using selectedNode = $("#tree").dynatree("getActiveNode")
  2. add child element using addChild method
  3. expand the parent node like this :selectedNode.expand(true)
  4. and finally call the editNode function for newly added node

The btnAddCode's click event should look like this:

    $("#btnAddCode").click(function(event){

        event.preventDefault();
        selectedNode = $("#tree").dynatree("getActiveNode");

        if( validateForm()){
             var rx = /[<>:"\/\\|?*\x00-\x1F]|^(?:aux|con|clock\$|nul|prn|com[1-9]|lpt[1-9])$/i;
                if(rx.test($("#newFolderName").val())) {
                  alert("Error: Input contains invalid characters!");
                  return false;
                }   
                var childNode = selectedNode.addChild({
                   title: "My new node",
                   tooltip: "This folder and all child nodes were added programmatically."
                });
                selectedNode.expand(true);
                editNode(childNode);
        }    
    });

Edit:

you should change the blur event to prevent a tree category having multiple nodes with the same title.get child list of the parent node and check if any of them except the editing node,has same title as the editing node or not,if so, let the user know and return. so adding this code to blur event should do the trick:

var parentChilds = node.parent.childList;
var titleAvalible = false;
$.each(parentChilds,function(_index){
    if(this.data.key != node.data.key && this.data.title == title){
       titleAvalible = true;
    }
});
if(titleAvalible){
    alert("A node with same title is avalible");
    return;
}

I also updated the fiddle.

hope that helps.