Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用具有父子关系的JSON数据创建带有复选框的树?_Javascript_Jquery_Html_Json_Tree - Fatal编程技术网

Javascript 如何使用具有父子关系的JSON数据创建带有复选框的树?

Javascript 如何使用具有父子关系的JSON数据创建带有复选框的树?,javascript,jquery,html,json,tree,Javascript,Jquery,Html,Json,Tree,我有JSON数据,JSON数据有父子关系。我想从中创建树结构。我找到了很多插件和库,但我找不到我的需求。我使用PHP脚本获取这个JSON数据 这是我想要创建的具有树结构的图像。我被卡住了。我知道JSON并不像图中显示的那个样,但我只想告诉你们树应该是什么样子。如何在图中创建树。我只想用javascript代码来处理和创建这种类型的树结构。工作的例子是必须和非常赞赏 您可以随意使用JSON格式,树应该是可折叠的。还可以为它提供所需的JSON格式 我的JSON数据如下: { "

我有JSON数据,JSON数据有父子关系。我想从中创建树结构。我找到了很多插件和库,但我找不到我的需求。我使用PHP脚本获取这个JSON数据

这是我想要创建的具有树结构的图像。我被卡住了。我知道JSON并不像图中显示的那个样,但我只想告诉你们树应该是什么样子。如何在图中创建树。我只想用javascript代码来处理和创建这种类型的树结构。工作的例子是必须和非常赞赏

您可以随意使用JSON格式,树应该是可折叠的。还可以为它提供所需的JSON格式

我的JSON数据如下:

     {
     "2":
         {
          "5": "Wrist Watch"
         },
     "5":
         {
          "9": "Men's"
         },
     "18": 
         {
         "3": "Clothing"
         },
     "28": 
         {
         "1": "Perfumes"
         },
     "29": 
         {
         "7": "Laptop",
         "10": "Tablets"
         },
     "30":
         {
          "8": "Mobile"
         },
    "31": 
         {
          "2": "Books"
         },
    "33": 
         {
          "6": "Electronics"
         },
   "34": 
         {
          "4": "Home & Kitchen\n"
         }
    }

编程的问题是:现有的库和工具很少能完全满足您的需要。始终由您将输入数据转换为他们期望的格式,然后将输出数据转换为您需要的格式。有时,这种转换比编写自己的代码而不是库函数需要更多的努力——这似乎是其中之一

正如@philosophocat已经指出的,在HTML标记中呈现这样一个树的最好方法是嵌套列表。您只需递归地遍历JSON数据并创建相应的元素:

函数createList(数据)
{
var结果=document.createElement(“ul”);
for(var输入数据)
{
如果(!data.hasOwnProperty(key)| | key==“_title”)
继续;
var值=数据[键];
var item=createItem(key,typeof value==“string”?value:value.\u title);
如果(值的类型==“对象”)
item.appendChild(createList(value));
结果:儿童(项目);
}
返回结果;
}
函数createItem(值、标题)
{
var结果=document.createElement(“li”);
var checkbox=document.createElement(“输入”);
setAttribute(“类型”、“复选框”);
复选框.setAttribute(“名称”、“选择”);
复选框.setAttribute(“值”,值);
结果.追加子项(复选框);
result.appendChild(document.createTextNode(title));
返回结果;
}
document.body.appendChild(createList(jsonData));
请注意,此处项目的显示顺序为“随机”,因为对象键通常是无序的。您可以更改上面的代码以某种方式对键进行排序,也可以更改数据以使用数组并定义顺序。我还为数据添加了一个
“\u title”
属性,以确保已标记类别-您的数据中没有任何类别的标签

现在,您需要以使列表看起来像一棵树的方式设置列表的样式。显而易见的解决方案是使用网格线图像替换通常的项目符号。但是,这对嵌套列表不起作用-在嵌套列表中,您需要显示多个图像、高层列表中的垂直线以及实际属于当前列表项的图像

这可以通过为列表项使用背景图像来解决,这些背景图像也将显示在子列表旁边。以下是我得到的示例样式:

ul
{
填充:0;
列表样式类型:无;
字体大小:14px;
}
锂
{
背景图片:url(数据:image/png;base64,ivborw0kggoaaansuheugaa0aaabkcayaaabdelruaaap0leqvr42u3pqoaiageqp3/o6t7JAhdolkQD4sMZuwZazKKlGXniHRDOu6HfyKRSCQSiUQikUgkEolEIv0rTc/fNmQ78+lpaaaelftksuqmcc);
背景重复:无重复;
左侧填充:13px;
}
李:最后一个孩子
{
背景图片:url(数据:image/png;base64,ivborw0kggoaaaansuheugaa0aaaajcayaadpeqzqaaahuleqvr42mnkwat/gzirak/ak0mkplgbqgethoacfgjcvdbeqaaaaaaasuvork5cyii=);
}
li>ul
{
左边距:5px;
}
请注意,如果子列表太高,这仍然会变得难看-我使用的背景图像的高度仅为100px。当然,这可以通过使用更大的背景图像来解决。一个更干净的替代方案是使用Firefox,但目前只支持Firefox


编辑:详细介绍如何设置嵌套列表(如树)的样式。虽然该方法类似,但它通过为垂直线使用单独的图像(可以垂直重复)来避免我上面提到的图像大小问题。另一方面,这种方法似乎只适用于实线,如果应用于虚线,则可能会产生瑕疵。

如果您想自己滚动,“树”中的关键字是递归。它需要支持任何深度的数据,代码和数据都应该支持递归

这意味着您的JSON数据应该是一个递归结构,其中每个节点看起来都是相同的(如下所示):

注意:我已经更改了示例数据以包含更多深度,因为2个级别从未出现递归问题

e、 g:

递归函数如下所示:

{
    id: 1,                  // data id
    title: "title",         // display title
    children: [             // list of children, each with this same structure
        // list of child nodes
    ]
}
function addItem(parentUL, branch) {
    for (var key in branch.children) {
        var item = branch.children[key];
        $item = $('<li>', {
            id: "item" + item.id
        });
        $item.append($('<input>', {
            type: "checkbox",
            name: "item" + item.id
        }));
        $item.append($('<label>', {
            for: "item" + item.id,
            text: item.title
        }));
        parentUL.append($item);
        if (item.children) {
            var $ul = $('<ul>').appendTo($item);
            addItem($ul, item);
        }
    }
}
最终结果如下所示:

{
    id: 1,                  // data id
    title: "title",         // display title
    children: [             // list of children, each with this same structure
        // list of child nodes
    ]
}
function addItem(parentUL, branch) {
    for (var key in branch.children) {
        var item = branch.children[key];
        $item = $('<li>', {
            id: "item" + item.id
        });
        $item.append($('<input>', {
            type: "checkbox",
            name: "item" + item.id
        }));
        $item.append($('<label>', {
            for: "item" + item.id,
            text: item.title
        }));
        parentUL.append($item);
        if (item.children) {
            var $ul = $('<ul>').appendTo($item);
            addItem($ul, item);
        }
    }
}

如果要根据选中状态切换可见性,请使用以下选项:

$(':checkbox').change(function () {
    $(this).closest('li').children('ul').slideToggle();
});
$('label').click(function(){
    $(this).closest('li').find(':checkbox').trigger('click');
});
如果还希望标签切换复选框,请使用以下选项:

$(':checkbox').change(function () {
    $(this).closest('li').children('ul').slideToggle();
});
$('label').click(function(){
    $(this).closest('li').find(':checkbox').trigger('click');
});
注:我只提供了最基本的造型,因为这通常是“品味”。链接中的示例显示在另一个答案中

--更新:

修正:项目31和32的ID可能错误

用于更好地选择和取消选择的函数(对于级联到子节点的父节点):

--如图所示()更新fiddle,它将工作得更好,还允许您单击文本展开,而无需同时选择-我知道我发现这更有用。它将帮助(这是个人偏好)您查看哪些值和选项可用,而无需选择第一个。

使用。这个库提供了我在使用树和javascript时需要的每个函数

您只需根据给定的格式()更改json响应:

设置javascript并包含所有必需的fi { "title": "Sports & Outdoors", "isFolder": true, "key": "0", "children": [ { "title": "Fitness Accessories", "key": "1", "isFolder": true, "children": [ { "title": "Fitness Accessories", "key": "2", "isFolder": true, "children": [ { "title": "Pedometer & Watches", "key": "3" } ] } ] } ] } $("#buildTree").dynatree({ onActivate: function (node) { // A DynaTreeNode object is passed to the activation handler // Note: we also get this event, if persistence is on, and the page is reloaded. leftActiveNodeKey = node.data.key; }, persist: false, checkbox: true, selectMode: 3, children: $.parseJSON(response.d) });
$(this).prop('checked', false);
$(function () {
    addItem($('#root'), data);
    $(':checkbox').click(function () {
        var matchingId = $(this).attr('id');
        if ($(this).attr('checked'))
        {
            $('input[id*=' + matchingId +']').each(function() {
            $(this).removeAttr('checked');
            $(this).prop('checked', false);
                $(this).prop('checked', $(this).attr('checked'));
                return;
            });
        }
        else {
             $('input[id*=' + matchingId +']').each(function() {
            $(this).attr('checked', 'checked');
                $(this).prop('checked', $(this).attr('checked'));
             });
        }

    });
    $('label').click(function(){
        $(this).closest('li').children('ul').slideToggle();

    });
});