Search code examples
jqueryjquery-uijquery-ui-sortable

Make li element collapse elements below when using ui-sortable


Okay, this is a somewhat exotic attempt...

I have a ui-sortable list, where elements can have different classes, for example

<ul id="items"> //sortable
    <li class="topCollapsible">...</li>
    <li class="content">...</li>
    <li class="content">...</li>
    <li class="mediumCollapsible">...</li>
    <li class="content">...</li>
    <li class="content">...</li>
    <li class="topCollapsible">...</li>
    <li class="content">...</li>
</ul>

I want to retain the ability to drag and drop any element to any position, but at the same time I would like a click on a topCollapsible class to collapse all elements below it, down to the next topCollapsible element. So in the example above, the first topCollapsible li element should collapse the elements 2-6.

The same goes for the mediumCollapsible element, which in the example above should collapse elements 5 and 6.

Is there any way to achieve this? Here's the code in codepen: https://codepen.io/tenshis/pen/jOaeRPg


Solution

  • Consider the following.

    $(function() {
      $("#items").sortable({
        items: ".content"
      }).disableSelection();
      $(".topCollapsible, .mediumCollapsible").click(function() {
        $(this).nextUntil(":not(.content)").toggle();
      });
    });
    .box {
      width: 150px;
      height: 20px;
      border-width: 2px;
      border-style: solid;
      padding: 2px;
      cursor: move;
    }
    
    ul {
      list-style-type: none;
    }
    <link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
    <script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
    <ul id="items">
      <li class="topCollapsible">
        <div class="box"><b>topCollapsible</b></div>
      </li>
      <li class="content">
        <div class="box">--</div>
      </li>
      <li class="content">
        <div class="box">--</div>
      </li>
      <li class="mediumCollapsible">
        <div class="box">mediumCollapsible</div>
      </li>
      <li class="content">
        <div class="box">--</div>
      </li>
      <li class="content">
        <div class="box">--</div>
      </li>
      <li class="topCollapsible">
        <div class="box"><b>topCollapsible</b></div>
      </li>
      <li class="content">
        <div class="box">--</div>
      </li>
    </ul>

    This uses Items instead of Cancel. See Demo: https://jqueryui.com/sortable/#items

    The advantage here is that items cannot be put outside of a "parent". Whereas if you used Cancel, you could drop content above the top.

    For the collapse, we use .nextUntil() and .toggle(). See more: