Как сгруппировать <li> в спойлер на js или jquery

271
07 января 2018, 07:57

Здравствуйте. В общем, есть такой html:

<li>310_Васильев.А.А.</li>
<li>310_Иванов.Г.Г.</li>
<li>310_Новиков.С.С.</li>
<li>310_Баринова.Ю.М.</li>
<li>215_Белов.В.П.</li>
<li>215_Путин.В.В.</li>

... Их много... Как можно сгруппировать данные элементы по первым символам в названии в так называемый спойлер, чтобы по щелчку список с подходящими элементами раскрывался?

То есть примерно что-то такое:

<ul>
<li onclick="$('#310').slideToggle('slow');" href="javascript://">Кабинет 310</li>
<ul id="310" style="display: none;">
<li>310_Васильев.А.А.</li>
<li>310_Иванов.Г.Г.</li>
<li>310_Новиков.С.С.</li>
<li>310_Баринова.Ю.М.</li>
</ul>
<li onclick="$('#215').slideToggle('slow');" href="javascript://">Кабинет 215</li>
<ul id="215" style="display: none;">
<li>215_Белов.В.П.</li>
<li>215_Путин.В.В.</li>
</ul>
</ul>
Answer 1

при условии того, что ваш желаемый результат не особо то валидный html,то пример построения списка может быть следующим.

$(function(){ 
   $("#src-list li").each(function(idx, li){ 
      var txt = $(li).text(); 
      var data = txt.split('_'); 
      var cNum = data[0]; 
      var name = data[1]; 
       
      var cId = "#cab-" +  cNum; 
      if($(cId).length == 0){ 
         $("<ul>").attr("id", "cab-" + cNum) 
                  .appendTo("#result") 
                  .append($("<li>").addClass("toggle").text(cNum)) ; 
      } 
      $("<li>").text(name).appendTo($(cId));             
   });     
    
   $("#result").on('click', ".toggle", function(){ 
      $(this).nextAll().toggle(); 
   }); 
});
li.toggle { font-weight: bold; color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<ul id="src-list"> 
  <li>310_Васильев.А.А.</li> 
  <li>310_Иванов.Г.Г.</li> 
  <li>310_Новиков.С.С.</li> 
  <li>310_Баринова.Ю.М.</li> 
  <li>215_Белов.В.П.</li> 
  <li>215_Путин.В.В.</li> 
</ul> 
 
<hr/> 
 
<ul id="result"> 
</ul>

Answer 2

У вас хороший код. Могу предложить как его улучшить.

Сейчас вы в каждую такую функцию передаёте id, поэтому вызовы везде разные. Можно же вообще ничего не передавать, а получать ul как следующий элемент. Тогда везде будет одна и таже функция.

function Toggle() {
   var ul = this.nextSibling;
   if(ul.style.display == "none") {
      ul.style.display = "block"
   }
   else {
      ul.style.display = "none";
   }
   return false;
}

Далее все функции можно прямо в HTML коде повесить

<li onclick="Toggle()">Кабинет 215</li>

Или через JavaScript код HTML:

<li class="spoiler-link">Кабинет 215</li>

JavaScript:

var els = document.getElementsByClassName("spoiler-link");
for(var el of els) {
   el.addEventListener("click",Toggle);
}
Answer 3

Большое спасибо за помощь!! К сожалению, от своего кода пришлось отказаться, потому как элементы li подгружаются динамически из базы данных, сплошняком. Распределить их по контейнерам <li onclick="Toggle()">Кабинет XXX</li> как раз и заключалось основной проблемой.

Отдельное спасибо teran! Внес небольшие коррективы в его скрипт. Ну точнее адаптировал под свои нужды. Единственное, что мне не понятно это замена элементов на jquery. Я сделал просто $("#src-list").empty(); в самом конце скрипта. В целом, работает, но правильно ли это? Вот полный html:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<script> 
$(function(){ 
   $("#src-list li").each(function(idx, li){ 
   var html = $(li).html(); 
      var txt = $(li).text(); 
      var data = txt.split('_'); 
      var cNum = data[0]; 
       
      var cId = "#cab-" +  cNum; 
      if($(cId).length == 0){ 
         $("<ul>").attr("id", "cab-" + cNum) 
                  .appendTo("#result") 
                  .append($("<li>").addClass("toggle").text("Кабинет " + cNum)) ; 
      } 
      $("<li>").css({"display":"none"}).html(html).appendTo($(cId));             
   });     
    
   $("#result").on('click', ".toggle", function(){ 
      $(this).nextAll().toggle('normal'); 
   }); 
   $("#src-list").empty(); 
}); 
</script> 
<style> 
li.toggle { font-weight: bold; color: red; } 
</style> 
<ul id="src-list"> 
<li><a href="chatsb.php?client=208_Жукова.Т.С.">208_Жукова.Т.С.</a></li> 
<li><a href="chatsb.php?client=208_Лахаткина.А.Л.">208_Лахаткина.А.Л.</a></li> 
<li><a href="chatsb.php?client=208_Мишулина.Ж.В.">208_Мишулина.Ж.В.</a></li> 
<li><a href="chatsb.php?client=208_Моисеева.Т.С.">208_Моисеева.Т.С.</a></li> 
<li><a href="chatsb.php?client=208_Никитина.О.Н.">208_Никитина.О.Н.</a></li> 
<li><a href="chatsb.php?client=208_Румянцева.О.А.">208_Румянцева.О.А.</a></li> 
<li><a href="chatsb.php?client=209_Афанасьева.М.В.">209_Афанасьева.М.В.</a></li> 
<li><a href="chatsb.php?client=209_Бакулина.О.А.">209_Бакулина.О.А.</a></li> 
<li><a href="chatsb.php?client=209_Баранова.Л.В.">209_Баранова.Л.В.</a></li> 
<li><a href="chatsb.php?client=209_Лукьянова.В.А.">209_Лукьянова.В.А.</a></li> 
<li><a href="chatsb.php?client=209_Фокина.Г.Г.">209_Фокина.Г.Г.</a></li> 
<li><a href="chatsb.php?client=209_Хлюстова.А.Н.">209_Хлюстова.А.Н.</a></li> 
<li><a href="chatsb.php?client=210_Абносова.Е.В.">210_Абносова.Е.В.</a></li> 
<li><a href="chatsb.php?client=210_Афонина.Т.А.">210_Афонина.Т.А.</a></li> 
<li><a href="chatsb.php?client=210_Борисова.О.А.">210_Борисова.О.А.</a></li> 
<li><a href="chatsb.php?client=210_Грушина.О.И.">210_Грушина.О.И.</a></li> 
<li><a href="chatsb.php?client=210_Дворникова.А.В.">210_Дворникова.А.В.</a></li> 
<li><a href="chatsb.php?client=210_Карцева.Е.А.">210_Карцева.Е.А.</a></li> 
<li><a href="chatsb.php?client=210_Коршунова.В.В.">210_Коршунова.В.В.</a></li> 
<li><a href="chatsb.php?client=210_Курина.Д.М.">210_Курина.Д.М.</a></li> 
<li><a href="chatsb.php?client=210_Лихова.И.В.">210_Лихова.И.В.</a></li> 
<li><a href="chatsb.php?client=210_Мозголова.Н.А.">210_Мозголова.Н.А.</a></li> 
<li><a href="chatsb.php?client=210_Новикова.М.Н.">210_Новикова.М.Н.</a></li> 
<li><a href="chatsb.php?client=210_Павличук.А.Н.">210_Павличук.А.Н.</a></li> 
<li><a href="chatsb.php?client=210_Петунина.Н.М.">210_Петунина.Н.М.</a></li> 
<li><a href="chatsb.php?client=210_Прокофьева.М.А.">210_Прокофьева.М.А.</a></li> 
<li><a href="chatsb.php?client=210_Тимофеева.Е.В.">210_Тимофеева.Е.В.</a></li> 
<li><a href="chatsb.php?client=210_Трофимова.О.Г.">210_Трофимова.О.Г.</a></li> 
<li><a href="chatsb.php?client=210_Чигорина.Е.А.">210_Чигорина.Е.А.</a></li> 
<li><a href="chatsb.php?client=210_Шило.Е.Ф.">210_Шило.Е.Ф.</a></li> 
<li><a href="chatsb.php?client=217_Валерьянова.Л.В.">217_Валерьянова.Л.В.</a></li> 
<li><a href="chatsb.php?client=217_Генш.М.В.">217_Генш.М.В.</a></li> 
<li><a href="chatsb.php?client=217_Кржижановский.М.Е.">217_Кржижановский.М.Е.</a></li> 
<li><a href="chatsb.php?client=217_Филиппова.С.А.">217_Филиппова.С.А.</a></li> 
<li><a href="chatsb.php?client=301_КарасевВА">301_КарасевВА</a></li> 
<li><a href="chatsb.php?client=301_КлоповаТО">301_КлоповаТО</a></li> 
<li><a href="chatsb.php?client=301_КовалеваЮО">301_КовалеваЮО</a></li> 
<li><a href="chatsb.php?client=301_МаксимоваАА">301_МаксимоваАА</a></li> 
<li><a href="chatsb.php?client=301_Младова ЮА">301_Младова ЮА</a></li> 
<li><a href="chatsb.php?client=301_ТелегинаВА">301_ТелегинаВА</a></li> 
<li><a href="chatsb.php?client=301_ТепловаНС">301_ТепловаНС</a></li> 
<li><a href="chatsb.php?client=301_ФотинаКВ">301_ФотинаКВ</a></li> 
<li><a href="chatsb.php?client=301_ШуралеваНВ">301_ШуралеваНВ</a></li> 
<li><a href="chatsb.php?client=321_Белов.К.А.">321_Белов.К.А.</a></li> 
<li><a href="chatsb.php?client=321_Игнатьева.Н.С.">321_Игнатьева.Н.С.</a></li> 
<li><a href="chatsb.php?client=321_Мелкова.А.А.">321_Мелкова.А.А.</a></li> 
<li><a href="chatsb.php?client=321_Рушнов.И.А.">321_Рушнов.И.А.</a></li> 
<li><a href="chatsb.php?client=321_Свистунова.С.В.">321_Свистунова.С.В.</a></li> 
</ul> 
 
<ul id="result"> 
</ul>

PS: У меня есть еще некоторые <li> не подходящие под общую группировку, например <li><a href="chatsb.php?client=!Программисты!">!Программисты!</a></li> можно ли как-нибудь их исключить из обработки данным скриптом? Пусть будут они необработанные, отдельно...

UPD Проблема решена. Сделал проверку переменной cNum на наличие текста

if(isNaN(cNum)){
         $("<li>").html(html).appendTo("#result");
         }else{
          var cId = "#cab-" +  cNum;
       ...
          $("<li>").css({"display":"none"}).html(html).appendTo($(cId));            
    }  
READ ALSO
Правильно ли сделан индикатор загрузки?

Правильно ли сделан индикатор загрузки?

У меня есть приложение, каждая страница которого состоит из нескольких компонентовпосле некоторого события происходит большой асинхронный...

239
Как отключать и включать slick-carousel на разных разрешениях?

Как отключать и включать slick-carousel на разных разрешениях?

Использую слайдер slick-carouselЧасто бывает необходимо отключать слайдер на определенных разрешениях, помогает в этом такая конструкция:

836
PayPal мультивалютный приём платежей

PayPal мультивалютный приём платежей

Возможно ли сделать приём платежей на сайте через кнопку PayPal "Купить сейчас" мультивалютным, в зависимости от страны покупателя? Те

222
Получение записи по id

Получение записи по id

Создал не большой ProductList, заполнил таблицу данными, отобразил их на общей страницыНе могу получить единственную запись по ключу

1994