【问题标题】:Is it possible to drag and drop external data into a jstree?是否可以将外部数据拖放到 jstree 中?
【发布时间】:2017-11-14 16:59:36
【问题描述】:

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

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

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

我的配置方式如下:

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

我正在使用 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');
    });
} 

我想要做的是将“标签”(我的意思是列表项)从单独的 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)。

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

例如我已经尝试过这个 - 它只是使用 jqueryui 并且与 jstree 除了引用它运行的 div 之外没有任何关系:

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

我的问题真的是我正在尝试做的事情是否可能?我花了很长时间研究这个问题,但我觉得我无处可去。

还有其他可以完成此类任务的东西吗?我已经看了看,但找不到任何东西。本质上,要求是能够创建树(名称、编辑、删除、拖放),然后还能够将标签(#tagList 中的&lt;li&gt; 元素)放入其中并保存。

【问题讨论】:

标签: jquery html jquery-ui cakephp jstree


【解决方案1】:

根据我在cmets发的文章,你需要创建一个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()函数只是一个简单的包装函数,让拖入的item更像jsTree已有的。

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

check_callback: true

这里的下一个关键是在可拖动的start 回调中。在这里,我们使用 jsTree 的 dnd 插件创建 jsTree 已经准备好处理的 Drag n Drop 元素。

  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 可以理解的特定属性和我们的帮助项的事件对象。

【讨论】:

  • 这真的很棒 - 非常感谢你,非常感谢我正在尝试做的事情。如果您有“位置 1”和“位置 2”,我还需要能够添加其他位置(使用表单 text 输入和按钮)。这是将这些项目附加到exData 的情况吗?
  • 是的,我需要能够添加其他位置。我尝试使用exData.push({ id: "loc3", parent: "#", text: "Another location" });,但它不会出现在树上。我尝试使用各种方法(例如$('#tree').jstree(true).refresh();)对其进行刷新,但这只是将其恢复到原始状态。那么如何向树中添加更多数据呢?
  • 您可以创建一个对象并以与拖动停止中相同的方式使用追加。
  • @Andy 不能和你争论。基于此,powiat.chelm.pl/jstree/demo/move_copy.html,您想利用onmove 回调和事件。
  • 我终于用$('#tree').on('copy_node.jstree', function (e, data) { ... }); 让它工作了。您提供的链接很有帮助,Google Group 中的链接对您的回答也有帮助。这也很有趣,但对我不起作用:github.com/vakata/jstree/issues/1510
猜你喜欢
  • 2012-07-01
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多