jjzjj

javascript - 嵌套的父/子复选框 - 工作解决方案需要 Bootstrap 的调整帮助

coder 2024-07-15 原文

我一直在寻找一种“完整”的解决方案来嵌套基于层次结构正确更改状态的父子复选框。

大多数“解决方案”都不起作用或只能在一个层面上起作用。他们还要求您以特定方式命名复选框。

This Stack Overflow 讨论涵盖了要点,但也提供了 Rory 发现的一个很好的解决方案 here .

我已经在我的开发项目中对其进行了测试,它可以完美地独立运行。但是,我使用的是 Bootstrap 2.x 和复选框

我有一个 JSFiddle它显示了工作示例代码,然后是我的带有禁用父复选框的版本,然后是无效的 Bootstrap 代码版本。

<!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); 
  }); 
});

我的理解是需要在某处更改代码以使用parentsclosest。代码更好的人能否帮助确定需要进行更改以使 Bootstrap 版本正常工作的位置。

最佳答案

看看免费的JSTree用户控制。它是基于 JavaScript 的,开源的,并允许配置多种样式的 TreeView ,例如:

由于此处显示的复选框只是图像,您可以轻松地将它们替换为单选按钮,并且通过事件处理,您可以禁止多项选择,因此它们在需要时表现得像单选按钮。

这是通过如下指定 “checkbox” 插件来实现的(请参阅下面我提供的完整工作代码片段):

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

相应的 HTML 结构如下所示,只需将其包含在您的页面正文中即可:

<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>

要获取选中的值,请使用此函数(假设您已经像我在 JSFiddle 示例中那样使用 id="listForDisplay" 创建了一个 div):

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(', '));
}

此代码可以在单击事件中触发,也可以像我一样绑定(bind) JSTree 事件。将以下内容附加到前面的 JavaScript 代码段即可:

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

注意:选择父节点时,父节点名称会与子节点一起列出。如果只选择 child ,则不会列出相关的 parent 。

您可以找到有关指定此插件行为的选项的更多信息 here .


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

$(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>

关于javascript - 嵌套的父/子复选框 - 工作解决方案需要 Bootstrap 的调整帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20355375/

有关javascript - 嵌套的父/子复选框 - 工作解决方案需要 Bootstrap 的调整帮助的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  4. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  5. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  6. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  8. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  9. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  10. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

随机推荐