jsTree的contextmenu的自定义

我见过一个例子网上展示如何自定义jstree的右键(使用插件)的外观。 例如,允许删除“,而不是”文件夹“(通过隐藏”从对文件夹中删除“选项)。 现在,我找不到那个例子。任何人都可以在正确的方向?官方并没有真正的帮助。 编辑: 因为我想只有一个或两个小的改变默认的,我宁愿不重新创建(虽然我当然会,如果它是唯一的方法)。我想要做的是这样的:

"contextmenu" : {

items: {
 "ccp" : false,

 "create" : {
 // The item label
 "label" : "Create",
 // The function to execute upon a click
 "action"   : function (obj) { this.create(obj); },
 "_disabled"   : function (obj) { alert("obj=" + obj); return "default" != obj.attr('rel'); }
 }

}

}

但它不工作-创建项目只是始终禁用(警报从来没有出现)。


1. contextmenu插件已经具备了这种支持。从您链接到:items:预计一个对象或一个函数,它应该返回一个对象。如果一个函数它发射在树的背景和接收一个-那是正确的点击的节点。 因此,而不是给contextmenu一个硬编码对象一起工作,你可以提供以下功能。它会检查被点击了一类“文件夹”,并从对象删除它删除了“删除”菜单项:

function customMenu(node) {
 // The default set of all items
 var items = {
  renameItem: { // The "rename" menu item   label: "Rename",
   action: function () {...}
  },
  deleteItem: { // The "delete" menu item
   label: "Delete",
   action: function () {...}
  }
 };

 if ($(node).hasClass("folder")) {
  // Delete the "delete" menu item
  delete items.deleteItem;
 }

 return items;
}

注意,上面将隐藏的删除,但该插件还允许你显示一个项目,同时禁止其行为,通过添加_disabled: true到相关的资料。在这种情况下,你items.deleteItem._disabled = trueif代替。 应该是,但初始化插件与customMenu函数,而不是你有什么

$("#tree").jstree({plugins: ["contextmenu"], contextmenu: {items: customMenu}});
//                 ^
// ___________________________________________________________________|

编辑:如果您不希望在每次单击鼠标右键来重新创建,你可以把逻辑的操作处理程序的项目本身。

"label": "Delete",
"action": function (obj) {
 if ($(this._get_node(obj)).hasClass("folder") return; // cancel action
}

再次编辑:看后jsTree的源代码,它看起来像被重新创建的每个它反正所示(见show()parse()函数),所以我不认为我的第一个解决的问题。 不过,我不喜欢的符号你所提出的建议,用一个函数作为值_disabled。探索出一条潜在的路径是包装自己parse()用你自己的一个评估的功能函数disabled: function () {...}并将结果存储在_disabled,调用原来的前parse()。 这不会是困难要么直接修改其源代码。版本1.0-RC1的2867线有关的一个:

str += "<li class='" + (val._class || "") + (val._disabled ? " jstree-contextmenu-disabled " : "") + "'><ins ";

您可以在此一个检查前只需添加一行$.isFunction(val._disabled),如果是这样,val._disabled = val._disabled()。然后将其提交给创作者一个补丁:) 

2. 要清除一切。 :此相反的

$("#xxx").jstree({
'plugins' : 'contextmenu',

'contextmenu' : {
 'items' : { ... bla bla bla ...}
}

});

使用这样的:

$("#xxx").jstree({
'plugins' : 'contextmenu',

'contextmenu' : {
 'items' : customMenu }

});



3. 我已经适应了与类型有点不同,虽然,也许它可以帮助其他人的工作建议的解决方案: 其中#{$ id_arr [$ K]}是参考到div容器...在我的情况下,许多树木等等所有这些代码会输出到浏览器,但你的想法。基本上我想所有的选项,但只有“创建”和驱动器的节点上“粘贴”。用正确绑定到这些操作以后:

    <div id="$id_arr[$k]" class="jstree_container"></div>
  </div>
  </li>

  <!-- JavaScript neccessary for this tree : {$value} -->
  <script type="text/javascript" >
   jQuery.noConflict();

  jQuery(function ($) {

  // This is for the context menu to bind with operations on the right clicked node
    function customMenu(node) {
   // The default set of all items

  var control;

   var items = {

      createItem: { 
     label: "Create",
     action: function (node) { return {createItem: this.create(node) }; }
    },

      renameItem: { 
     label: "Rename",
     action: function (node) { return {renameItem: this.rename(node) }; }
    },

     deleteItem: { 
     label: "Delete",
     action: function (node) {  return {deleteItem: this.remove(node) }; },
     "separator_after": true

    },
      copyItem: { 
        label: "Copy",
        action: function (node) { $(node).addClass("copy"); return {copyItem: this.copy(node) }; }
    },
        cutItem: { 
        label: "Cut",
        action: function (node) { $(node).addClass("cut"); return {cutItem: this.cut(node) }; }
    },
      pasteItem: { 
        label: "Paste",
        action: function (node) { $(node).addClass("paste"); return {pasteItem: this.paste(node) }; }
    }


   };


   // We go over all the selected items as the context menu only takes action on the one that is right clicked
    $.jstree._reference("#{$id_arr[$k]}").get_selected(false, true).each(function(index,element)
    { 

      if ( $(element).attr("id") != $(node).attr("id") )
      {
       // Let's deselect all nodes that are unrelated to the context menu -- selected but are not the one right clicked

       $("#{$id_arr[$k]}").jstree("deselect_node", '#'+$(element).attr("id") ); 
      }
     });




  //if any previous click has the class for copy or cut
    $("#{$id_arr[$k]}").find("li").each(function(index,element)  
    { 
      if ($(element) != $(node) )
     { 
      if( $(element).hasClass("copy") || $(element).hasClass("cut") ) control=1;
     }
     else if( $(node).hasClass("cut") || $(node).hasClass("copy"))
      {
      control=0;
      }
   });


   //only remove the class for cut or copy if the current operation is to paste
  if($(node).hasClass("paste") )
  { 
   control=0; 
   // Let's loop through all elements and try to find if the paste operation was done already  
   $("#{$id_arr[$k]}").find("li").each(function(index,element)
   {  
    if( $(element).hasClass("copy") ) $(this).removeClass("copy"); 
     if ( $(element).hasClass("cut") ) $(this).removeClass("cut"); 
     if ( $(element).hasClass("paste") ) $(this).removeClass("paste"); 
    });
  }    switch (control)
    {
    //Remove the paste item from the context menu
    case 0:
        switch ($(node).attr("rel"))
         {

           case "drive":
            delete items.renameItem;
            delete items.deleteItem;
            delete items.cutItem;
            delete items.copyItem;
           delete items.pasteItem;
           break;

           case "default":
           delete items.pasteItem;
           break;

         } 
    break;

    //Remove the paste item from the context menu only on the node that has either copy or cut added class
      case 1:
      if( $(node).hasClass("cut") || $(node).hasClass("copy") )
      {            switch ($(node).attr("rel"))
            {

                case "drive":
                 delete items.renameItem;
                 delete items.deleteItem;
                 delete items.cutItem;
                 delete items.copyItem;
                delete items.pasteItem;
                break;

                case "default":
                delete items.pasteItem;
                break;


            }
          } 
           else //Re-enable it on the clicked node that does not have the cut or copy class
            {         switch ($(node).attr("rel"))
            {

              case "drive":
               delete items.renameItem;
               delete items.deleteItem;
               delete items.cutItem;
               delete items.copyItem;
              break;

            }  
           } 

     break;

    //initial state don't show the paste option on any node
    default:    switch ($(node).attr("rel"))
              {

                case "drive":
                 delete items.renameItem;
                 delete items.deleteItem;
                 delete items.cutItem;
                 delete items.copyItem;
                 delete items.pasteItem;
                break;

                case "default":
                delete items.pasteItem;
                break;

              } 

    break;

     }

   return items;

  }




  $("#{$id_arr[$k]}").jstree({


    // List of active plugins used
    "plugins" : [ "themes","json_data", "ui", "crrm" , "hotkeys" , "types" , "dnd", "contextmenu"], 

    "contextmenu" : { "items" : customMenu , "select_node": true},



4. 您可以修改@BOX9代码,以满足您的动态禁用的:

function customMenu(node) {

 ............
 ................
 // Disable the "delete" menu item 
 // Original // delete items.deleteItem; 
 if ( node[0].attributes.yyz.value == 'notdelete' ) {


  items.deleteItem._disabled = true;
 } 

}

你需要在你的XML或JSON数据添加一个属性“XYZ”

你可能感兴趣的:(js)