是否可以将外部数据拖放到 jstree 中?

Is it possible to drag and drop external data into a jstree?

我正在做一个需要构建分层导航菜单的项目。 jstree 看起来不错。

树将保存到数据库中 - 我计划使用 CakePHP 的 Tree Behaviour(由于现有代码库,该项目必须在 Cake 2.x 而不是 3.x 中工作).

我需要做的一件事是能够从外部数据源将 "Tags" 添加到我的树中。

我的配置方式如下:

填充我的 jstree 的数据来自数据库 table(由于 Cake 的命名约定,称为 navigations)。它使用上面树行为 link 中给出的 table 结构。

我正在使用 ajax 方法将此数据加载到 jstree 中:

$.ajax({
    type : "GET",
    url : "/ajax_get_tree",
    dataType : "json",    

    success : function(json) {
        createJSTrees(json);
    },    

    error : function(xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
    }
});


function createJSTrees(jsonData) {
    $("#tree").jstree({
        'core': {
            "check_callback" : true,
            'data' : jsonData
        },
        "plugins" : ["dnd"]
    }).on('loaded.jstree', function() {
        $("#tree").jstree('open_all');
    });
} 

我想要做的是将 "Tags"(我指的是列表项)从单独的 div、#tagList 拖放到树上的元素中。标签数据格式如下:

<div id="tagList">
    <li data-tag="1">United Kingdom</li>
    <li data-tag="2">France</li>
    <li data-tag="3">Germany</li>
</div>

我知道可以使用 jqueryui 的 draggable 行为将它们从一个 div 移动到另一个(从 #tagList#tree)。

但是,我不知道如何 "drop" 标签,以便 jstree 将其列在适当的节点下。

例如,我试过这个 - 它只是使用 jqueryui 并且与 jstree 无关,除了引用 div 它是 运行 on:

$('#tagList li').draggable({
        cursor: 'move',
        helper: 'clone',
        connectToSortable: "#tree",
    });

我的问题真的是我正在尝试做的事情是否可行?我花了很长时间研究这个问题,但感觉一无所获。

还有其他东西可以完成这类任务吗?我看过但找不到任何东西。本质上,要求是能够创建树(名称、编辑、删除、drag/drop),然后将标签(#tagList 中的 <li> 元素)带入其中并保存.

根据我在评论里发的文章,你需要创建一个jsTree会比较熟悉的对象。

参考:

工作示例:

https://jsfiddle.net/Twisty/dLv7xk3t/

HTML

<div class="ui-widget">
  <div class="ui-widget-header">
    Tags
  </div>
  <div id="tagList">
    <ul>
      <li data-tag="1" id="uk-1">United Kingdom</li>
      <li data-tag="2" id="france-1">France</li>
      <li data-tag="3" id="germany-1">Germany</li>
    </ul>
  </div>
</div>
<div class="ui-widget">
  <div class="ui-widget-header">
    Tree
  </div>
  <div id="tree">
  </div>
</div>

JavaScript

var exData = [{
  id: "loc1",
  parent: "#",
  text: "Location 1"
}, {
  id: "loc2",
  parent: "#",
  text: "Location 2"
}, {
  id: "italy-1",
  parent: "loc2",
  text: "Italy",
  icon: "fa fa-flag"
}, {
  id: "poland-1",
  parent: "loc2",
  text: "Poland",
  icon: "fa fa-flag"
}];

function makeTreeItem(el) {
  return $("<a>", {
    id: $(el).attr("id") + "_anchor",
    class: "jstree-anchor",
    href: "#"
  });
}

$(function() {
  $('#tree').jstree({
    core: {
      check_callback: true,
      data: exData
    },
    types: {
      root: {
        icon: "fa fa-globe-o"
      }
    },
    plugins: ["dnd", "types"]
  });
  $('#tagList li').draggable({
    cursor: 'move',
    helper: 'clone',
    start: function(e, ui) {
      var item = $("<div>", {
        id: "jstree-dnd",
        class: "jstree-default"
      });
      $("<i>", {
        class: "jstree-icon jstree-er"
      }).appendTo(item);
      item.append($(this).text());
      var idRoot = $(this).attr("id").slice(0, -2);
      var newId = idRoot + "-" + ($("#tree [id|='" + idRoot + "'][class*='jstree-node']").length + 1);
      return $.vakata.dnd.start(e, {
        jstree: true,
        obj: makeTreeItem(this),
        nodes: [{
          id: newId,
          text: $(this).text(),
          icon: "fa fa-flag-o"
        }]
      }, item);
    }
  });
});

函数makeTreeItem()只是一个包装函数,使拖入的项目更像jsTree已有的。

首先要做的是更新核心首选项以启用新节点等的创建:

check_callback: true

此处的下一个关键点在可拖动 start 回调中。这是我们创建一个 jsTree 已经准备好处理的拖放元素的地方,利用 jsTree 的 dnd 插件。

  start: function(e, ui) {
      var item = $("<div>", {
        id: "jstree-dnd",
        class: "jstree-default"
      });
      $("<i>", {
        class: "jstree-icon jstree-er"
      }).appendTo(item);
      item.append($(this).text());
      var idRoot = $(this).attr("id").slice(0, -2);
      var newId = idRoot + "-" + ($("#tree [id|='" + idRoot + "'][class*='jstree-node']").length + 1);
      return $.vakata.dnd.start(e, {
        jstree: true,
        obj: makeTreeItem(this),
        nodes: [{
          id: newId,
          text: $(this).text(),
          icon: "fa fa-flag-o"
        }]
      }, item);
    }

基本上,我们有一个 div,带有一个图标和被拖动项目的文本。这将代表我们的助手,将在拖动时看到。然后我们制作并 return 一个具有 jsTree 将理解的特定属性的事件对象和我们的辅助项目。