Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Рубрикатор по алфавиту (https://javascript.ru/forum/dom-window/63215-rubrikator-po-alfavitu.html)

MAzZYBiG 24.05.2016 10:46

Рубрикатор по алфавиту
 
Добрый день, коллеги.
Помогите решить задачку.

На страницу выводится список неких объектов в алфавитном порядке. Допустим, растений. И алфавитный указатель, в котором буквы, для которых на странице есть растения, оформлены ссылками, а остальные - просто текст.
Вопрос в том, какой на эти ссылки прикрепить код, чтобы по клику на них скрывались все растения, кроме начинающихся на эту букву.

Вот пример.
На страничке есть Арбуз, Алыча, Слива, Яблоко.
Соответственно, в указателе ссылками являются А, С, Я. По клику на А на страничке должны остаться только Арбуз и Алыча, всё остальное должно скрыться.

По идее, это не так сложно, но никак не соображу, как это сделать.

рони 24.05.2016 11:02

MAzZYBiG,
можно html, а ещё лучше обьект с данными.

MAzZYBiG 25.05.2016 20:47

Не очень понял.

Может есть какие-нибудь более-менее готовые варианты? А то поиском тяжело такое искать

рони 25.05.2016 21:17

MAzZYBiG,
скажем это обьект
{"А" : ["Арбуз","Алыча"], "С" : ["Слива"]}

или как оно у вас и обьект и html

Царь Леонид 25.05.2016 23:44

Если у вас данные представлены, как показал Рони, то вот так примерно (можно и покороче, но лень думать)
var data = {"А" : ["Арбуз","Алыча"], "С" : ["Слива"], "В" : ["Виноград", "Вишня"]};

function displayData(data){
  var body = document.body;
  for(var val in data){
     var span = document.createElement('span');
     span.innerHTML = val
     span.className = "selected"
     body.appendChild(span)
  }
}

function filterData(el){
  var r = document.getElementById('result')
  var arr = [];
    for(i in data) {
      i == el? arr.push(data[i]):'';
    }
  var e = arr.join(', ')
  r.innerHTML = e
}

displayData(data)
var clicked = document.querySelectorAll('.selected');

for(var i = 0; i<clicked.length; i++){
  clicked[i].addEventListener('click', function(event){
    filterData.call(null, event.target.innerHTML)
  })
}

=======================================
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div id="result"></div>
</body>
</html>


Вот ссылка на песочницу

laimas 26.05.2016 09:50

Цитата:

Сообщение от рони
а ещё лучше обьект с данными

Почему? По идее списки уже приходят сортированные по алфавиту, и если скрытые, то проще показать связанное или я чего-то не дополнял?

рони 26.05.2016 10:43

laimas,
а как узнать что скрывать? парсить какую-то data или выборку по классу икс делать? нужно же знать связанное или как то связать, от чего плясать-то :) ?

laimas 26.05.2016 10:55

Ну а как табуляторы, аккордеоны работают? Раскрывается же связанное с кнопкой и проблем нет. Я так думаю, что уж если списки и нужен рубрикатор, то это уже сортировано по алфавиту, а связать списки с литерами не проблема.

рони 26.05.2016 11:04

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

laimas 26.05.2016 11:20

рони, если клиент сам готовит списки, то да, но если списки отдает сервер, ну что сложного связать их с литерами. Пусть речь об UTF, код А = 1040, щелкнули по литере А, получили ее код, показали список, например list + А.charCodeAt.

MAzZYBiG 26.05.2016 12:11

Много информации, спасибо.

Буду думать

рони 26.05.2016 12:17

laimas,
вариант как я понял вас
<!DOCTYPE html>

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

</script>
  <script>
$(function() {
    $("a[data-cls]").each(function(indx, el) {
        var cls = "." + $(el).data("cls");
        $(el).on({
            click: function(event) {
                event.preventDefault();
                $("div").slideUp().filter(cls).slideDown()
            }
        })
    }).eq(0).click()
});
  </script>
</head>

<body>
<a href="" data-cls="А" class="А">А</a>
<a href="" data-cls="С" class="С">С</a>
<a href="" data-cls="Я" class="Я">Я</a>

<div class="А">Арбуз</div>
<div class="А">Алыча</div>
<div class="С">Слива</div>
<div class="Я">Яблоко</div>


</body>
</html>

вариант того что предлагаю я
<!DOCTYPE html>

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

</script>
  <script>
$(function() {
    var obj = [".А",".С",".Я"];
    $.each(obj,function(indx, el) {
        $("a"+el).on({
            click: function(event) {
                event.preventDefault();
                $("div").slideUp().filter(el).slideDown()
            }
        })
    })
    $("a"+obj[0]).click()
});
  </script>
</head>

<body>
<a href="" class="А">А</a>
<a href="" class="С">С</a>
<a href="" class="Я">Я</a>

<div class="А">Арбуз</div>
<div class="А">Алыча</div>
<div class="С">Слива</div>
<div class="Я">Яблоко</div>


</body>
</html>
оба варианта в минимальном исполнении

laimas 26.05.2016 13:02

Цитата:

Сообщение от рони
вариант как я понял вас

Нет, я это иначе представляю :)
Я исхожу из того, что сервер отдает списки, которые уже отсортированы по алфавиту, иначе смысла нет. Родителю этих списков можно давать ID связанные по литере рубрикатора при формировании этих списков, собственно это не сложно даже и для UTF:

<ul id="list<?=current(unpack('N', mb_convert_encoding($letter, 'UCS-4BE', 'UTF-8')))?>">
<li>...</li>
</ul>


Обработка щелчка по литере рубрикатора, это получение ее текста, и кода литеры по ней, с показом списка с ID равным list + charCode литеры. Или в data-code держать уже готовой ее код, серверу ведь все равно и список литер формировать.

А если объект, то это если клиент списками занимается, да если они еще и разбросаны, да еще по классам их собирать, разве это выгоднее?

рони 26.05.2016 13:23

laimas,
спасибо, но я вас не понимаю :( от слова совсем ... особенно это
Цитата:

Сообщение от laimas
Обработка щелчка по литере рубрикатора, это получение ее текста, и кода литеры по ней, с показом списка с ID равным list + charCode литеры. Или в data-code держать уже готовой ее код, серверу ведь все равно и список литер формировать.

А если объект, то это если клиент списками занимается, да если они еще и разбросаны, да еще по классам их собирать, разве это выгоднее?


laimas 26.05.2016 13:50

Цитата:

Сообщение от рони
я вас не понимаю

Тогда зайдем с огорода. :)
Пусть изначально на странице есть только список литер рубрикатора, запрос по которым, это асинхронный запрос и возврат клиенту запрошенного. Понятное дело, что сервер вернет список только тех данных, что отвечают нажатой литеры.

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

Мне представляется, что и в этом случае выгодно отдавать уже отсортированные по литерам списки, связав их со списком литер по по их коду. То есть на клиенте будет так:

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<style>
.list ul {
    display: none;
}
#choice li {
    display: inline;
}
</style> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script> 
$(function() {
    $('#choice').on('click', 'li', function() {
        $('#list'+$(this).data('code')).show()
    })
});
</script>     
</head> 

<body>
<ul id="choice"><li data-code="1040">А</li><li data-code="1041">Б</li></ul>
<div class="list">
<ul id="list1040">
<li>А</li>
</ul>
<ul id="list1041">
<li>Б</li>
</ul>
</div>
</body> 
</html>

рони 26.05.2016 13:56

laimas,
хорошо но это же
Цитата:

Сообщение от рони
вариант как я понял вас

1 в 1

laimas 26.05.2016 14:31

Цитата:

Сообщение от рони
1 в 1

По сути да, но я не хочу "собирать детей", у меня "за всех отвечает родитель". Да и класс "Я" для меня, это нечто неудобоваримое. :)

MAzZYBiG 27.05.2016 05:20

Спасибо за помощь. Первый вариант из этого поста мне больше всего понравился.
Я его немного доработал - теперь он разворачивает весь список при первом открытии и разворачивает его же при нажатии пункта "Все". Посмотреть можно здесь. Если есть предложения по улучшению - буду рад.

И да. Список в моём случае, это не ul-li, а просто набор div. Т.е. всё как в примере.

рони 27.05.2016 07:46

MAzZYBiG,
одинаковые id это неправильно, и выбирать все дивы тоже, на странице наверняка есть много других ...ограничте нужные одним классом ...

MAzZYBiG 27.05.2016 17:47

Да, согласен.
Так даже лучше

MAzZYBiG 28.05.2016 00:19

На рабочем коде выяснилось, что это не работает. Проблема в том, что скрываются вообще все div на странице.
Вот пример - только добавил div для алфавита и всё, его нет.

В таком виде, вроде, работает

DynkanMaclaud 28.05.2016 12:42

MAzZYBiG,
https://jsfiddle.net/2mdv5rkp/1/

MAzZYBiG 29.05.2016 15:05

А в чём существенное отличие?

DynkanMaclaud 29.05.2016 18:28

MAzZYBiG, не посмотрел что у вас есть рабочий пример...


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