Начальная загрузка: несколько целей: разрушается больше, чем ожидалось

#twitter-bootstrap #collapse #expand

Вопрос:

Я искал способ свернуть/развернуть несколько таблиц одновременно, и я нашел следующий метод на этом сайте:

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

В принципе, это работает нормально, но я заметил, что он также сворачивает/расширяет другие таблицы с другим идентификатором родителя. Что мне нужно, так это две кнопки, каждая из которых разворачивает/сворачивает несколько таблиц.
Поскольку таблицы генерируются динамически, все они получают имя класса с одинаковым началом.

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

Каков наилучший способ решить эту проблему?

Некоторая справочная информация, я получил веб-инструмент, созданный с использованием комбинации 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>
 

Ответ №1:

Я не знаю, является ли это лучшим решением, но я решил его с помощью следующего кода.

 <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, function( element, 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>