18 Kwi 2019

Kolumny w css oraz szukanie w html

Powiedzmy że mamy bardzo długą listę linków. Chciałbym aby ta lista łamała się na 2, 3 a może więcej kolumn. W naszym przykładzie lista będzie składać się z 20 elementów.

Taką listę można uzyskać przez emmet aby nie klepać tego samodzielnie wystarczy wpisać ul#ul>li{text $}*20

<ul id="ul">
  <li>text 1</li>
  <li>text 2</li>
  <li>text 3</li>
  <li>text 4</li>
  <li>text 5</li>
  <li>text 6</li>
  <li>text 7</li>
  <li>text 8</li>
  <li>text 9</li>
  <li>text 10</li>
  ...
</ul>

Chciałby aby ta lista została podzielona na dwie kolumny. Do tego użyjemy column-count Które jest wpierane nawet przez IE od wersji 10
Oczywiście też trochę upiększymy wygląd naszej listy.

ul {
  border: 1px solid #cacaca;
  list-style: none;
  max-width: 50%;
  margin: 0;
  padding: 0;
  column-count: 2;
  column-width: 50%;
  padding: 10px;
  margin: auto;
}

ul li {
  padding: 10px;
  margin-bottom: 2px;
}

ul li:nth-child(even) {
  background-color: #f0f0f0;
}

Multi-column składa się nie tylko z samego column-count ale także z kilku innych przydatnych własności. Oczywiście każde z tych właściwości ma prefix dla różnych przeglądarek ale że nie wyobrażam sobie pracy bez biblioteki autoprefixer to nawet nie wspominam o tym 😉

  • column-count – ilość kolumn (number|auto|initial|inherit)
  • column-fill – sposób wypełniania kolumn (balance|auto|initial|inherit)
  • column-gap – odstęp między kolumnami (length|normal|initial|inherit)
  • column-rule-style – styl między kolumnami (none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset|initial|inherit)
  • column-rule-width – szerokość między kolumnami (medium|thin|thick|length|initial|inherit)
  • column-rule-color – kolor między kolumnami (color|initial|inherit)
  • column-rule – skrócona nazwa dla wszystkich column-rule-* (column-rule-width column-rule-style column-rule-color|initial|inheri)
  • column-span – na ile kolumn powinien rozciągać się element (none|all|initial|inherit)
  • column-width – określa szerokość kolumny (auto|length|initial|inherit)
  • columns – skrócona wersja określająca szerokość i ilość kolumn (auto|column-width column-count|initial|inherit)

Mamy już naszą listę składająca się z 2 kolumn. Wyobraźmy sobie że ta lista składa się z 400 elementów a nie 20 😉
W dodatku nie jest posortowana alfabetycznie. Ciężko by było znaleźć treść w takiej ilości tekstu chyba że przez ctrl + F w przeglądarce ale na telefonie było by to znacznie trudniejsze.

Dodamy możliwość wyszukiwania po takiej ilości elementów.
Na początek zwykły html

<div class="form">
    <input type="text" id="search" name="search" placeholder="szukaj ...">
</div>

Trochę upiększenia by się przydało 😉

input[type=text] {
  width: 100%;
  padding: 12px 20px;
  margin: 8px 0;
  display: inline-block;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}

.form {
  border-radius: 5px;
  background-color: #f2f2f2;
  padding: 10px;
  max-width: 50%;
  margin: 0 auto 20px;
}

Ok mamy już wygląd, dodamy teraz trochę javascriptu.

function searchText() {
  const input = document.getElementById('search');
  const filter = input.value.toUpperCase();
  const ul = document.getElementById('ul');
  const lists = ul.getElementsByTagName('li');

  if (input.value.length) {
    ul.setAttribute('style', 'column-count: 1;');
  } else {
    ul.setAttribute('style', 'column-count: 2');
  }

  for (i = 0; i < lists.length; i++) {
    item = lists[i].textContent;
    if (item.toUpperCase().indexOf(filter) > -1) {
      lists[i].style.display = '';
    } else {
      lists[i].style.display = 'none';
    }
  }
};

window.addEventListener('keyup', searchText);

Na początku funkcji pobieramy dane z pola inpu o id search i zmieniamy na duże litery przez toUpperCase
W związku z tym że do kolorowania co drugiego rekordu użyłem odd po wyszukaniu nieparzystej liczy elementów dziwnie zachowuje się kolor z 2 kolumnami. Tutaj przy wyszukiwaniu zmieniam na jedną kolumnę a gdy brak tekstu w polu input ustawiam ponownie column-count na 2

W pętli pobieram tekst który oczywiście również musimy zmienić na duże litery przez toUpperCase i sprawdzić czy tekst jest taki sam jak wpisany w nasze pole search.
Za pomocą display ustawiamy style na none

Ostatnia rzecz do zrobienia to chcę aby moja funkcja zadziałała na zdarzenie keyup.

window.addEventListner('keyup', searchText);