嵌套的父/子复选框 - 工作解决方案需要Bootstrap的调整帮助 [英] Nested parent/child checkboxes - working solution need adjustment help for Bootstrap

查看:75
本文介绍了嵌套的父/子复选框 - 工作解决方案需要Bootstrap的调整帮助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一个完整的解决方案来嵌套父子复选框,这些复选框可以根据层次结构正确地改变状态。



大多数'解决方案'不起作用或只工作到一个级别。它们还要求您以特定方式命名复选框。








可运行代码段(完整代码)



  $(function(){var $ demo1 = $(#demo1); var $ listForDisplay = $(#listForDisplay); function displayList(data){// see:https://www.jstree .com / docs / events / var i,j,r = []; for(i = 0,j = data.selected.length; i< j; i ++){r.push(data.instance.get_node(data) .selected [i])。text);} $ listForDisplay.html('Selected:'+ r.join(','));} $ demo1.jstree({themes:{theme:apple ,点:假, icons:false},plugins:[themes,html_data,checkbox,sort,ui]}); $ demo1.on('loaded.jstree',function(e,data){displayList(data);}); $ demo1.on('changed.jstree',function(e,data){displayList(data);});});  

 < head> < script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>< / script> < link href =https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css\"rel =stylesheet/> < script src =https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js>< / script>< / head>< body> < div id =demo1class =demostyle =height:100px;> < UL> < li id =phtml_1> < a href =#>根节点1< / a> < UL> < li id =phtml_2> < a href =#>子节点1< / a> < /锂> < li id =phtml_3> < a href =#>子节点2< / a> < /锂> < / UL> < /锂> < li id =phtml_4> < a href =#>根节点2< / a> < /锂> < / UL> < / DIV> <峰; br /> < div id =listForDisplay/>< / body>  


I have been looking for a 'complete' solution to nesting parent child checkboxes that change state correctly based on a hierarchy.

Most 'solutions' do not work or only work to one level. They also require you to name the checkboxes in a particular way.

This Stack Overflow discussion covers the main points but also provide a good solution discovered by Rory here.

I have tested it within my development project and it works perfectly standalone. However, I am using Bootstrap 2.x and for checkboxes

I have a JSFiddle which shows the working example code, then my version with a disabled parent checkbox and then the bootsrap code version which does not work.

<!DOCTYPE html>
<body>
<!-- Raw working example from site http://css-tricks.com/indeterminate-checkboxes/ -->

<b>Raw working example</b>
<p>
<ul>
    <li>
        <input type="checkbox" name="tall" id="tall">
        <label for="tall">Tall Things</label>
        <ul>
            <li>
                <input type="checkbox" name="tall-1" id="tall-1">
                <label for="tall-1">Buildings</label>
            </li>
            <li>
                <input type="checkbox" name="tall-2" id="tall-2">
                <label for="tall-2">Giants</label>
                <ul>
                    <li>
                        <input type="checkbox" name="tall-2-1" id="tall-2-1">
                        <label for="tall-2-1">Andre</label>
                    </li>
                    <li>
                        <input type="checkbox" name="tall-2-2" id="tall-2-2">
                        <label for="tall-2-2">Paul Bunyan</label>
                        <ul>
                            <li>
                                <input type="checkbox" name="tall-2-2-1" id="tall-2-2-1">
                                <label for="tall-2-2-1">Son</label>
                            </li>
                            <li>
                                <input type="checkbox" name="tall-2-2-2" id="tall-2-2-2">
                                <label for="tall-2-2-2">Daughter</label>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li>
                <input type="checkbox" name="tall-3" id="tall-3">
                <label for="tall-3">Two sandwiches</label>
            </li>
        </ul>
    </li>
    <li>
        <input type="checkbox" name="short" id="short">
        <label for="short">Short Things</label>
        <ul>
            <li>
                <input type="checkbox" name="short-1" id="short-1">
                <label for="short-1">Smurfs</label>
            </li>
            <li>
                <input type="checkbox" name="short-2" id="short-2">
                <label for="short-2">Mushrooms</label>
            </li>
            <li>
                <input type="checkbox" name="short-3" id="short-3">
                <label for="short-3">One Sandwich</label>
            </li>
        </ul>
    </li>
</ul>

<hr>

<!-- Non Bootstrap Example -->
<b>My initial code example - Is Working</b>
<p>
<ul>
    <li>

        <input type="checkbox" name="" value="" disabled><strong>Ford</strong>

        <ul>
            <li>

                <input type="checkbox" name="" value="">Fiesta</label>
            </li>
            <li>

                <input type="checkbox" name="" value="">Focus</label>
            </li>
            <li>

                <input type="checkbox" name="" value="">Mondeo</label>
            </li>
        </ul>
    </li>
    <li>

        <input type="checkbox" name="" value="" disabled><strong>Vauxhall</strong>


        <ul>
            <li>

                    <input type="checkbox" name="" value="">Corsa</label>
            </li>
            <li>

                    <input type="checkbox" name="" value="">Astra</label>
            </li>
            <li>

                    <input type="checkbox" name="" value="">Vectra</label>
            </li>
        </ul>
    </li>
</ul>

            <hr>

<!-- Bootstrap Example -->

<b>Bootstrap based code example - Not Working</b>
<p>

<ul>
    <li>
        <label class="checkbox">
            <input type="checkbox" name="" value="" disabled><strong>Ford</strong>

        </label>
        <ul>
            <li>
                <label class="checkbox">
                    <input type="checkbox" name="" value="">Fiesta</label>
            </li>
            <li>
                <label class="checkbox">
                    <input type="checkbox" name="" value="">Focus</label>
            </li>
            <li>
                <label class="checkbox">
                    <input type="checkbox" name="" value="">Mondeo</label>
            </li>
        </ul>
    </li>
    <li>
        <label class="checkbox">
            <input type="checkbox" name="" value="" disabled><strong>Vauxhall</strong>

        </label>
        <ul>
            <li>
                <label class="checkbox">
                    <input type="checkbox" name="" value="">Corsa</label>
            </li>
            <li>
                <label class="checkbox">
                    <input type="checkbox" name="" value="">Astra</label>
            </li>
            <li>
                <label class="checkbox">
                    <input type="checkbox" name="" value="">Vectra</label>
            </li>
        </ul>
    </li>
</ul>

$(function () {
  // Apparently click is better chan change? Cuz IE?
  $('input[type="checkbox"]').change(function (e) {
      var checked = $(this).prop("checked"),
          container = $(this).parent(),
          siblings = container.siblings();

      container.find('input[type="checkbox"]').prop({
          indeterminate: false,
          checked: checked
      });

      function checkSiblings(el) {
          var parent = el.parent().parent(),
              all = true;

          el.siblings().each(function () {
              return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
          });

          if (all && checked) {
              parent.children('input[type="checkbox"]').prop({
                  indeterminate: false,
                  checked: checked
              });
              checkSiblings(parent);
          } else if (all && !checked) {
              parent.children('input[type="checkbox"]').prop("checked", checked);
              parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
              checkSiblings(parent);
          } else {
              el.parents("li").children('input[type="checkbox"]').prop({
                  indeterminate: true,
                  checked: false
              }); 
          } 
      } 

      checkSiblings(container); 
  }); 
});

My understanding is that the code needs to be changed somewhere to use parents or closest. Can someone who is a much better code please help identify where the change needs to happen to get the Bootstrap version working.

解决方案

Take a look at the free JSTree user control. It is JavaScript-based, open source and allows to be configured for multiple styles of tree views, for example:

Since the checkboxes displayed here are just images, you can replace them by radio buttons easily, and via event handling you can disallow multiple selections so they behave like radio buttons if required.

This is achieved by specifying the "checkbox" plugin as follows (see the snippet I provided below for the complete working code):

$(function () {
    $("#demo1")
        .jstree({
        "themes": {
            "theme": "apple","dots": false,"icons": false
        },
        "plugins": ["themes", "html_data", "checkbox", "sort", "ui"]
    });
});

The corresponding HTML structure looks like this, just include it in the body of your page:

<div id="demo1" class="demo" style="height:100px;">
    <ul>
        <li id="phtml_1">   <a href="#">Root node 1</a>
            <ul>
                <li id="phtml_2">   <a href="#">Child node 1</a>
                </li>
                <li id="phtml_3">   <a href="#">Child node 2</a>
                </li>
            </ul>
        </li>
        <li id="phtml_4">   <a href="#">Root node 2</a>
        </li>
    </ul>
</div>

To get the checked values, use this function (assuming you have created a div with id="listForDisplay" as I did in the JSFiddle example):

var $listForDisplay = $("#listForDisplay");
function displayList(data) { // see: https://www.jstree.com/docs/events/
    var i, j, r = [];
    for (i = 0, j = data.selected.length; i < j; i++) {
        r.push(data.instance.get_node(data.selected[i]).text);
    }
    $listForDisplay.html('Selected: ' + r.join(', '));
}

This code can either be triggered in a click event or you can bind JSTree events like I did. Appending the following to the previous JavaScript snippet does the job:

    $("#demo1")
    .on('loaded.jstree', function (e, data) {
            displayList(data);
        })
    .on('change_state.jstree', function (e, data) {
            displayList(data);
        });

Note: When a parent node is selected, the parent name is listed along with the childs. If only the childs are selected, the related parent(s) will not be listed.

You can find more about the options specifying the behaviour of this plugin here.


Runnable code snippet (complete code)

$(function() {

  var $demo1 = $("#demo1");
  
  var $listForDisplay = $("#listForDisplay");
  function displayList(data) { // see: https://www.jstree.com/docs/events/
    var i, j, r = [];
    for (i = 0, j = data.selected.length; i < j; i++) {
      r.push(data.instance.get_node(data.selected[i]).text);
    }
    $listForDisplay.html('Selected: ' + r.join(', '));
  }

  $demo1.jstree({
    "themes": {
      "theme": "apple",
      "dots": false,
      "icons": false
    },
    "plugins": ["themes", "html_data", "checkbox", "sort", "ui"]
  });
  $demo1.on('loaded.jstree', function(e, data) {
    displayList(data);
  });
  $demo1.on('changed.jstree', function(e, data) {
    displayList(data);
  });
});

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" rel="stylesheet" />

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
</head>

<body>
  <div id="demo1" class="demo" style="height:100px;">
    <ul>
      <li id="phtml_1"> <a href="#">Root node 1</a>
        <ul>
          <li id="phtml_2"> <a href="#">Child node 1</a>
          </li>
          <li id="phtml_3"> <a href="#">Child node 2</a>
          </li>
        </ul>
      </li>
      <li id="phtml_4"> <a href="#">Root node 2</a>
      </li>
    </ul>
  </div>
  <br/>
  <div id="listForDisplay" />
</body>

这篇关于嵌套的父/子复选框 - 工作解决方案需要Bootstrap的调整帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆