Při zobrazování tabulkových údajů je pro uživatele pohodlnější, pokud si může zvolit řazení řádků podle vybraného sloupce. V článku si ukážeme univerzální klientský skript, který můžeme aplikovat na běžně používané typy tabulek.

Naším cílem je, aby se kliknutím na záhlaví (element TH) tabulky data v ní uvedená seřadila podle daného sloupce, střídavě vzestupně a sestupně. V prvním sloupci našeho příkladu je řazení číselné, v dalších abecední (a v prohlížečích plně podporujících metodu localeCompare pro řetězce i správně podle české abecedy). Jakým postupem docílíme kýženého efektu?

  1. JavaScriptový kód předpokládá, že tabulka (s atributem id=“tb“) má záhlaví (část THEAD) a dále jedinou část TBODY, v níž jsou všechny řádky, které se budou třídit. Dále předpokládá, že obsahem buněk je jen prostý text bez HTML tagů (v řeči DOMu jediný dceřinný uzel typu Text), a to buď text nebo celé číslo.
  2. Prvním krokem je procházení všech řádků v TBODY metodou getElementsByTagName a vytvoření jejich kopií v poli virtualni_radky mimo strom dokumentu klonováním uzlů (metoda cloneNode DOM). K jednotlivým řádkům v TBODY by bylo možné přistupovat i jako k dceřinným uzlům tohoto elementu (childNodes), ale metoda getElementsByTagName je jednak rychlejší, jednak eliminuje prázdné textové uzly mezi řádky TR v Mozille.
  3. Veškeré zpracování probíhá na „virtuálních řádcích“, nikoli se skutečnými uzly řádků v dokumentu – důvodem je opět rychlost. Nejprve se načte obsah všech buněk do vícerozměrného pole hodnot udaje: udaje[i][0] je původní číslo i-tého řádku, udaje[i][1] pak obsahuje data jeho první buňky, udaje[i][2] druhé a tak dále.
  4. Pole udaje se setřídí metodou sort podle hodnot v daném sloupci, s použitím porovnávací funkce srovnej – tato funkce porovnává řetězce s použitím metody localeCompare JavaScriptu, čísla běžným způsobem. Metoda localeCompare pro řetězce umí třídit správně česky (včetně dvojhlásky „ch“) v MSIE 5.5, MSIE 6 a Mozille. Opera ji sice podporuje (nehlásí chybu při jejím volání), ale netřídí česky, MSIE 5 tuto metodu nezná.
  5. V dalším kroku se seřadí virtuální řádky podle výsledku řazení pole udaje.
  6. Vytvoří se nový prázdný uzel TBODY – proměnná nove_telo_tabulky – (metoda createElement DOMu).
  7. Seřazené virtuální řádky se metodou appendChild DOMu připojí k novému virtuálnímu uzlu nove_telo_tabulky. Všimněte si, že veškeré manipulace s řádky probíhají zatím mimo strom dokumentu, takže jsou velice rychlé.
  8. Ze skutečné tabulky se odstraní uzel (element) TBODY metodou removeChild DOMu.
  9. Konečně v posledním kroku se do vzniklé „díry“ vloží zatím virtuální uzel nove_telo_tabulky s přeskládanými řádky. Přesněji řečeno – metodou appendChild DOMu se připojí k tabulce. Tabulka je setříděna.

Níže uvádím JavaScriptový kód, vytvořený podle probraných bodů. Jednotlivé jeho části jsou pro snazší pochopení komentovány:

var sloupec, metoda_trideni;
var tabulka = document.getElementById(„tb“);
var telo_tabulky = tabulka.getElementsByTagName(„tbody“)[0];
var radky = telo_tabulky.getElementsByTagName(„tr“);
var pocetradku = radky.length;
var pocetsloupcu = radky[0].getElementsByTagName(„td“).length;
var smer_trideni = new Array();
for (var i=0;i<pocetsloupcu;i++) smer_trideni[i] = -1;
var udaje = new Array();
var virtualni_radky = new Array();
/*
1 / Načtení kopií řádků do pole virtualni_radky, načtení obsahu buněk do
vícerozměrného pole udaje
*/
for (var i=0;i<pocetradku;i++) {
  virtualni_radky[i] = radky[i].cloneNode(true);
  var bunky = virtualni_radky[i].getElementsByTagName(„td“);
  udaje[i] = new Array();
  udaje[i][0] = i;
  for (var j=0;j<pocetsloupcu;j++) {
    udaje[i][j+1] = bunky[j].firstChild.data;
  }
}
/*
2 / Funkce srovnej, kterou používá metoda sort (viz níže).
*/
function srovnej(i,j) {
  var hodnota1 = i[sloupec+1];
  var hodnota2 = j[sloupec+1];
  switch (metoda_trideni) {
    case 0: return smer_trideni[sloupec]*hodnota1.localeCompare(hodnota2);
    case 1: return smer_trideni[sloupec]*(hodnota1-hodnota2);
  }
}
/*
3 / Funkce serad, provádí vlastní seřazení a výpis pro daný sloupec. První
argument je číslo sloupce podle kterého se má tabulka řadit (první sloupec je 0),
druhý pak metoda pro řazení (0 – abedecní české, 1 – celočíselné)
*/
function serad(s,m) {
  var j;
  sloupec = s;
  metoda_trideni = m;
  smer_trideni[sloupec] = -smer_trideni[sloupec];
  udaje.sort(srovnej);
  var nove_telo_tabulky = document.createElement(„tbody“);
  for (var i=0;i<pocetradku;i++) {
    j = udaje[i][0];
    nove_telo_tabulky.appendChild(virtualni_radky[j]);
  }
  tabulka.removeChild(tabulka.getElementsByTagName(„tbody“)[0]);
  tabulka.appendChild(nove_telo_tabulky);
}

Související články

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět