3

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

Mohammed Farooq
  • 227
  • 1
  • 5
  • 23

1 Answers1

1

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.

hsh
  • 1,825
  • 9
  • 16
  • 1
    Thank you very much :) exactly what i was looking. – Mohammed Farooq Jun 13 '16 at 04:40
  • But it takes nodes with same name. If i add 2 nodes with same name then it should say already exists with the same name. – Mohammed Farooq Jun 16 '16 at 07:30
  • @MohammedFarooq, I updated the answer for your problem. – hsh Jun 16 '16 at 08:20
  • Need your help - In my tree only the last child is selectable but i am not able to select top most node is not selectable. What may be wrong – Mohammed Farooq Jun 23 '16 at 06:19
  • @MohammedFarooq ,please create a new question or update this one and provide some sample code. – hsh Jun 23 '16 at 06:24
  • Ok. But only thing is Root nodes are not selectable in my tree. I have used same code as is in sample jsfiddle. – Mohammed Farooq Jun 23 '16 at 06:29
  • @MohammedFarooq ،they are selectable on jsfiddle, so I should see your sample that doesn't work – hsh Jun 23 '16 at 06:37
  • Thanks bro it worked . this was causing problem. onActivate : function(node) { if (node.getChildren() !== null) { node.deactivate(); } } – Mohammed Farooq Jun 23 '16 at 07:03
  • Any idea how to reload particular node after persisting new node to db. – Mohammed Farooq Jun 23 '16 at 07:05
  • @MohammedFarooq ,you mean expand nodes to an specific node received from data base? If so you should search through all nodes and their children to find the node by I'd or name and then expand nodes on the path one by one, I think you should create new question for that,comment the link here ,I will help if I can – hsh Jun 23 '16 at 07:21
  • 1
    Ok sure.. Thank you. trying with node.reload() it is saying use reloadChildren(). Will try . – Mohammed Farooq Jun 23 '16 at 07:26
  • Last query bro. On selectedNode can we set the isLazy to true or false ? – Mohammed Farooq Jun 23 '16 at 11:46
  • I need your help bro. its regarding check/uncheck nodes. When i Uncheck the node only first child node should get uncheck and remaining childs should stay as is its states checked. – Mohammed Farooq Jul 22 '16 at 07:22
  • Please help me for my other post on dynatree [link](http://stackoverflow.com/questions/39876516/dynatree-lazy-load-form-elements#39876516) – Mohammed Farooq Oct 05 '16 at 14:37