Bootstrap:多个目标:崩溃的次数超出预期

问题描述

我正在寻找一种同时折叠/展开多个表格的方法,我在此站点上找到了以下方法

<button type="button" data-parent="#wrap" data-toggle="collapse" data-target=".demo">
    simple collapsible
</button>
<div id="wrap">
    <div class="demo collapse">
        test1
    </div>
    <div class="demo collapse">
        test1
    </div>
</div>

基本上,这工作正常,但我注意到它也在折叠/展开具有其他父 ID 的其他表。我需要的是两个按钮,每个按钮可以展开/折叠多个表格。 由于这些表是动态生成的,它们都获得了一个具有相同开头的类名。

<button type="button" data-parent="#wrap1" data-toggle="collapse" data-target=".demo">
    simple collapsible 1
</button>
<div id="wrap">
    <div class="demo collapse 1a">
        test1
    </div>
    <div class="demo collapse 1b">
        test1
    </div>
</div>
<button type="button" data-parent="#wrap2" data-toggle="collapse" data-target=".demo">
    simple collapsible 2
</button>
<div id="wrap2">
    <div class="demo collapse 2a">
        test1
    </div>
    <div class="demo collapse 2b">
        test1
    </div>
</div>

解决这个问题的最佳方法是什么?

一些背景信息,我收到了一个 webtool,它是用 Python、Django 和 Iommi 的组合创建的。我们的实习生创建了这个非常好的工具,一些用户提出了一些改进要求。

创建不同车道(行)的模板 HTML,每个车道都包含它自己的一组表格。目前,每个桌子和每个泳道都包含一个展开/折叠按钮,属于桌子的按钮工作正常,但属于泳道的按钮正在操纵所有桌子,而不仅仅是属于该泳道的桌子。

模板 HTML:

{% load django_bootstrap_icons %}
{% load mathfilters %}
{% load markdownify %}
<div class="align-self-center" id="lanetypegrouper-{{lanetype.grouper}}">
        {% for lane in lanetype.list %}
        {% regroup lane.blocks.all|dictsort:"position" by position as tblock_positiongroups %}
        <div class="card
            {% if lane.type == 'DIE' %}border-primary {% endif %}
            {% if lane.type == 'FIN' %}border-info {% endif %}
            {% if lane.type == 'PRE' %}border-warning {% endif %}
        {% if lanetype.grouper == False%} ml-auto {% endif%}
        m-2
        tlanetype
        lanetype-{{lane.type}}
        "
        id="lane-{{lane.uuid}}"
        {% with lanewidth=tblock_positiongroups|length|mul:12|add:1 %} style="width:{{lanewidth}}rem; min-width:11rem" {% endwith%}>
            <script>
              var btnUp = '{% bs_icon "chevron-up" %}';
              var btnDown = '{% bs_icon "chevron-down" %}';

              function change_btn(objButton)
              {
                var btnval = objButton.innerHTML;
                $(".collapse").on('hidden.bs.collapse',function(){
                  if (btnval===btnDown) objButton.innerHTML = btnUp;
                  else objButton.innerHTML = btnDown;
                });
                $(".collapse").on('shown.bs.collapse',function(){
                  if (btnval===btnDown) objButton.innerHTML = btnUp;
                  else objButton.innerHTML = btnDown;
                });
              }

              function change_row_btn(objButton)
                {
                  var btnval = objButton.innerHTML;
                  $(".collapse").on('hidden.bs.collapse',function(){
                    if (btnval===btnDown) objButton.innerHTML = btnUp;
                    else objButton.innerHTML = btnDown;
                  });
                  $(".collapse").on('shown.bs.collapse',function(){
                    if (btnval===btnDown) objButton.innerHTML = btnUp;
                    else objButton.innerHTML = btnDown;
                  });
                }
            </script>
            <div class="card-header  p-2">
                {{lane.get_type_display}}: {{lane.name}}
                <a class="btn btn-sm btn-outline-secondary p-1 small" role="button" href="{% url 'laneedit' lane.pk %}">{% bs_icon 'pencil-fill' %} Edit Row</a>
                <a class="btn btn-sm btn-outline-secondary p-1 small" 
                        type="button"
                        data-toggle="collapse"
                        data-parent="#row-{{lane.uuid}}"
                        data-target=".collapse"
                        aria-expanded="true"
                        aria-controls="collapseExample"
                        onclick="change_row_btn(this)"
                >{% bs_icon "chevron-down" %}</a>
            </div>
              <div class="card-body">
                <div id="row-{{lane.uuid}}" class="row {% if lanetype.grouper == False %}float-right{%endif%}">
                    {% for blockgroup in tblock_positiongroups%}
                    <div class="col tlane-position p-1 m-0" id="laneposition-{{blockgroup.grouper}}">
                        {% for tblock in blockgroup.list%}
                        <div class="card
                            {% if lane.type == 'DIE' %}border-primary text-white{% endif %}
                            {% if lane.type == 'FIN' %}border-info text-white {% endif %}
                            {% if lane.type == 'PRE' %}border-warning {% endif %}
                            tblock-card"
                             id="block-{{tblock.uuid}}">
                            <div class="card-header p-1
                                {% if tblock.notForRelease %}
                                    text-white bg-secondary 
                                {% else %}
                                    {% if lane.type == 'DIE' %}bg-primary {% endif %}
                                    {% if lane.type == 'FIN' %}bg-info {% endif %}
                                    {% if lane.type == 'PRE' %}bg-warning {% endif %}
                                {% endif %}
                                ">
                                <div class="row">
                                    <div class="col" style="padding-right:0">
                                        <b>{{tblock.type}}</b> {% if tblock.typeCounter > 0 %}{{tblock.typeCounter}}{%endif%}
                                    </div>
                                    <div class="col-auto small">
                                       <button class="btn btn-sm p-1
                                       {% if lane.type == 'PRE' %}btn-outline-dark {%else %} btn-outline-light {% endif %}
                                      small tblock-collapsebtn"
                                              type="button"
                                              data-toggle="collapse"
                                              data-target="#collapsable-{{tblock.uuid}}"
                                              aria-expanded="false"
                                              aria-controls="collapseExample"
                                              onclick="change_btn(this)"
                                      >{% bs_icon "chevron-down" %}</button>
                                      <a class="btn btn-sm p-1
                                      {% if lane.type == 'PRE' %}btn-outline-dark {%else %} btn-outline-light {% endif %}
                                      p-1 small"
                                         role="button"
                                         href="{% url 'blockedit' tblock.pk %}">
                                        {% bs_icon 'pencil-fill' %}
                                      </a>
                                    </div>
                                </div>
                                        {% if tblock.notForRelease %}<span class="small">(SafeLaunch)</span> {% endif %}
                            </div>
                            <div class="card-body p-0">{% include 'blocktable.html'%}</div>
                            <div class="card-footer  p-1 m-0"><span class="text-muted small tblock_remarks">{{tblock.remarks|markdownify}}</span></div>
                        </div>
                        {% endfor %} {% comment %} tblocks {% endcomment %}
                    </div>
                    {% endfor%} {% comment %} tblock grouplist {% endcomment %}
                </div>
              </div>
            {% if lane.desc %}<div class="card-footer">{{lane.desc}}</div>{%endif%}
        </div>
        {% endfor %}
    </div>

解决方法

我不知道这是不是最好的解决方案,但我用下面的代码解决了。

<script>
  var btnUp = '{% bs_icon "chevron-up" %}';
  var btnDown = '{% bs_icon "chevron-down" %}';

  function change_btn(objButton)
  {
    var btnval = objButton.innerHTML;
    $(".collapse").on('hidden.bs.collapse',function(){ objButton.innerHTML = btnDown });
    $(".collapse").on('shown.bs.collapse',function(){ objButton.innerHTML = btnUp; });
  }

  function change_row_btn(objButton)
  {
    var lane_id = objButton.offsetParent.id;
    var btnval = objButton.innerHTML;
    var lane_element = "";
    var ids = document.querySelectorAll('*[id]:not([id=""])')
    Array.prototype.forEach.call( ids,function( element,i ) {
      if (element.id === lane_id) { lane_element = element; }
    });

    var new_state = "hide"
    var ids = lane_element.querySelectorAll('*[id^="collapsable-"]:not([id=""])');
    Array.prototype.forEach.call( ids,i ) {
      if (btnval===btnDown) {
        new_state = "show"
        objButton.innerHTML = btnUp;
        $(element).data('toggle','collapse').collapse('show');
      } else {
        new_state = "hide"
        objButton.innerHTML = btnDown;
        $(element).data('toggle','collapse').collapse('hide');
      }
    });

    var ids = lane_element.querySelectorAll('*[id^="btn-"]:not([id=""])');
    Array.prototype.forEach.call( ids,function( step_btn_element,i ) {
      if (new_state==="show") { step_btn_element.innerHTML = btnUp; }
      else { step_btn_element.innerHTML = btnDown; }
    });
  }
</script>