Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Набор, массив, slideToggle (https://javascript.ru/forum/jquery/70673-nabor-massiv-slidetoggle.html)

miRrage 24.09.2017 14:41

Набор, массив, slideToggle
 
Здравствуйте!
Только разбираюсь с jQuery, и не могу понять что-то базовое.
С целью изучения языка хочу сделать, и в общем, можно сказать, что сделал на базе виджета sortable простенький визуальный инструмент для управления иерархической структурой (пример - меню сайта, категории товаров, статей).
Что-то типа accordion, только с dragndrop, контекстным меню добавления и удаления , разным уровнем раскрытия.
Возникают вопросы со скрытием/раскрытием подпунктов.

Пример списка, над которым производятся действия:
<div class="row">
      <div class="col-md-3">
        <ul id="sortable">
            <li class="catList defaultLi" data-level="1" data-row-id="1"> one</li>
            <li class="catList defaultLi" data-level="2" data-row-id="2"> two</li>
            <li class="catList defaultLi" data-level="2" data-row-id="3"> three</li>
            <li class="catList defaultLi" data-level="3" data-row-id="4"> four</li>
            <li class="catList defaultLi" data-level="3" data-row-id="5"> five</li>
            <li class="catList defaultLi" data-level="1" data-row-id="6"> six</li>
            <li class="catList defaultLi" data-level="2" data-row-id="7"> seven</li>
            <li class="catList defaultLi" data-level="1" data-row-id="8"> eight</li>
        </ul>
      </div>
</div>


Первая проблема в том, что не получается выбрать нужные пункты и скрыть (slideToggle()) их вместе одним набором. Например, при клике на 1-м элементе списка, хочу свернуть все лежащие ниже и у которых [level] больше "1" (здесь это 2,3,4,5). Сделать селектором не знаю как, т.к. еще ниже опять есть элементы с уровнем "1" и их не нужно затрагивать.
Сделал функцией:
<script>
//сворачивание
     $('.catList').click(function(){
            var arr=[];
            //значение уровня кликнутого элемента
            var le = +( $(this).attr('data-level'));
            //получение массива значений уровня элементов, которые лежат ниже,
            //и имеют уровень меньший, чем тот, на котором произведен клик.
            arr= getArr($(this), arr, le);
            
            //сворачивание/разворачивание
            for(i=0; i<arr.length; i++){
                var selector = '[data-row-id='+arr[i]+']';
                $(selector).slideToggle();
            }

     });
         
      function getArr(item, arr, le){
        if (
               ( +item.next().attr('data-level') >=  +item.attr('data-level')) &&
               ( +item.next().attr('data-level') > le)
           )
            {
                arr.push(item.next().attr('data-row-id'));
                getArr(item.next(), arr, le);
            }
        return arr;
      };
    
</script>


Это работает. Но не так как хотелось бы. Здесь в коде, $(this) представляет собой элемент jQuery. Правильно? Вызываю функцию getArr, которая принимает этот элемент, пустой массив, и значение и возвращает этот же массив заполненным.
В функции методом .next() получаю следующий элемент и значение [row-id] заношу в массив. А хотелось бы получить на выходе функции набор элементов jQuery к которому потом можно применить slideToggle.
Пытаюсь делать
arr.add(item.next())
- не выполняется.
Приходится в массив сохранять значение атрибута [row-id], а затем в цикле по значению поочередно выбирать элемент и к нему применять slideToggle.
Хочется сделать групповой операцией типа
arr.slideToggle();

Кто-нибудь может подсказать как?

рони 24.09.2017 14:58

Цитата:

Сообщение от miRrage
у которых [level] больше "1" (здесь это 2,3,4,5).

а 7 почему не в наборе?

miRrage 24.09.2017 15:11

Перед ним есть №6, у которого уровень такой же как и у №1, который кликнули. И его не нужно сворачивать.

рони 24.09.2017 15:21

miRrage,
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
 $('.catList').on('click', function(){
 var level = $(this).data('level'), stop = true;
 $(this).nextUntil().filter(function() {
 if($(this).data('level') <= level) stop = false;
 return stop && $(this).data('level') > level
 }).slideToggle();
 })
});
  </script>
</head>

<body>
<div class="row">
      <div class="col-md-3">
        <ul id="sortable">
            <li class="catList defaultLi" data-level="1" data-row-id="1"> one</li>
            <li class="catList defaultLi" data-level="2" data-row-id="2"> two</li>
            <li class="catList defaultLi" data-level="2" data-row-id="3"> three</li>
            <li class="catList defaultLi" data-level="3" data-row-id="4"> four</li>
            <li class="catList defaultLi" data-level="3" data-row-id="5"> five</li>
            <li class="catList defaultLi" data-level="1" data-row-id="6"> six</li>
            <li class="catList defaultLi" data-level="2" data-row-id="7"> seven</li>
            <li class="catList defaultLi" data-level="1" data-row-id="8"> eight</li>
        </ul>
      </div>
</div>

</body>
</html>

miRrage 24.09.2017 17:18

Большое спасибо! То что нужно.


Часовой пояс GMT +3, время: 05:32.