Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

10. diel - Editor tabuliek v JavaScripte

V minulej lekcii, Cyklus while v JavaScripte , sme sa venovali cyklom. Ukázali sme si prácu s while cyklom a vytvorili jednoduchú kalkulačku.

V minulej lekcii, Cyklus while v JavaScripte , sme sa naučili pracovať s DOM a meniť tak obsah stránky. Už vieme všetko potrebné, aby sme si vytvorili nejakú pravú webovú aplikáciu. Ako príklad, na ktorom sa zároveň niečo málo priučím, si v dnešnom JavaScript tutoriálu naprogramujeme editor tabuliek.

Tabuľka je veľmi zaujímavý a špecifický prvok webových stránok. Tabuľka má riadky <tr> a bunky <td>. <td> náleží <tr> a <tr> náleží v najjednoduchšom prípade <table>.

Html

Vytvorme si nejakú stránku, CSS súbor a JS súbor. CSS a JS do stránky v hlavičke importujete a tým máme stránku hotovú, to že je bodmi prázdne, nám skôr dokonca vyhovuje, pretože si všetko potrebné pripravíme v skripte. Je to pre nás dokonca výhodné, nasadíme chcete aplikáciu na inej stránke, nemusíme už vôbec zasahovať do HTML. Aby sme mali kód nejakým spôsobom jednotný, pretože v ďalších JS lekciách budeme skript zdokonaľovať, HTML stránka vyzerá nasledovne. Všímajte si názvu súborov.

<!DOCTYPE html>
<html lang="cs">
    <head>
        <title>Editor tabuliek</title>
        <meta charset="utf-8" />
        <script src="editor-tabulek.js"></script>
        <link href="editor-tabulek.css" rel="stylesheet" />
    </head>
    <body>

    </body>
</html>

Javascript

V súbore editor-tabulek.js si vytvoríme 3 premenné. Premenná tabulka bude obsahovať samotnú tabuľku a potom budeme mať premenné vychoziVelikostX a vychoziVelikostY pre predvolenú veľkosť tabuľky. Tabuľku necháme bez hodnoty a premenným pre predvolenú veľkosť dosadíme nejaká 2 kladné rozumne veľké čísla. napr .:

let tabulka;
let vychoziVelikostX = 5;
let vychoziVelikostY = 3;

Neskôr budeme potrebovať ešte jednu premennú, ale tou sa teraz nebudeme zaoberať. Vytvoríme funkcie pre vygenerovanie ovládacích tlačidiel a samotnej tabuľky. Funkciu pre vygenerovanie tlačidiel si necháme na neskôr.

Funkcie pre vytvorenie tabuľky (pomenujeme si ju vytvorVychoziTabulku()) vytvorí tabuľku a vloží ju do body. Dvoma vnorenými cykly vytvoríme jej bunky. Aby boli bunky editovateľné, vložíme do nich klasické textové pole - element <input>. Pretože bunky budeme vytvárať na viacerých miestach, vytvoríme si pre ich tvorbu funkciu vytvorBunku(). Tá vytvorí element <td> a <input>. <input> vloží do <td> a bunku vráti. Keďže budeme programovať funkcie, ktoré v tabuľke predpokladajú označenú bunku, pri označení bunky si túto bunku musíme niekam uložiť. Existuje udalosť focus, ktorá je vyvolaná vo chvíli, keď používateľ vyberie nejaký prvok, či už do neho klikne alebo sa naň treba presunie tabulátorom. Pri vytváraní bunky udalosť teda zároveň novo vytvorenému inputu obslúžime a do premennej aktivniBunka (ktorú deklarujeme pred deklaráciou funkcie) bunku uložíme v prípade, že je označená. Treba pamätať na to, že pri obsluhovaní udalosti sa mení obsah kľúčového slova this na prvok, ktorý udalosť vyvolal. Do premennej aktivniBunka uložíme práve this (čo bude element <input>, pretože on vyvolal udalosť).

let aktivniBunka;

function vytvorBunku() {
    let td = document.createElement("td");

    let tdInput = document.createElement("input");

    tdInput.type = "text";
    tdInput.onfocus = function () {
        aktivniBunka = this;
    }
    td.appendChild(tdInput);

    return td;
}

Vráťme sa k funkcii, ktorá vytvorí predvolené tabuľku. Najprv sa vrhneme na vytvorenie samotnej tabuľky.

function vytvorVychoziTabulku() {
    tabulka = document.createElement("table");
    document.body.appendChild(tabulka);
}

Do premennej tabulka uložíme novovytvorený element <table> a ten vložíme do elementu <body>. Všimnite si, že keď sa chceme dostať k <body>, nemusíme zložito cez getElementsByTagName() alebo podobné, ale element je predpripravený v document.body.

Teraz sa pozrime na samotné cykly. Najprv vytvoríme elementy riadku (cyklus y) a každý nový riadok ihneď vložíme do tabuľky (ostatne vkladanie je lepšie vždy robiť skôr, než na to neskôr zabudnúť). Potom vnoreným cyklom vytvoríme jednotlivé bunky a pridáme ich do riadku. Využijeme na to metódu vytvorBunku(), ktorú sme si pripravili pred chvíľou. Cyklom ako horná hodnoty odovzdáme premennej vychoziVelikostX a vychoziVelikostY tak, aby sa vytvoril správny počet riadkov a stĺpcov.

function vytvorVychoziTabulku() {
    tabulka = document.createElement("table");
    document.body.appendChild(tabulka);
    for (let y = 0; y < vychoziVelikostY; y++) {
        let tr = document.createElement("tr");
        tabulka.appendChild(tr);

        for (let x = 0; x < vychoziVelikostX; x++) {
            tr.appendChild(vytvorBunku());
        }
    }
}

Teraz už máme základ hotový. V obsluhe udalosti onload na objekte window túto funkciu zavoláme.

window.onload = function () {
    vytvorVychoziTabulku();
}

Takáto obsluha udalostí by vám už mala byť dobre známa. Ide o anonymný funkciu priradenú do obsluhy udalosti po načítaní stránky. Keď aplikáciu spustíme, uvidíme tabuľku (pravdepodobne bez ohraničenia) a v nej input.

Editor tabuliek
localhost

CSS

Gratulujem, vytvorili ste prvú aplikáciu, ktorá vygenerovala tabuľku. Než sa pustíme do ďalšej časti, ostylujme si ju, nech vyzerá trochu k svetu. CSS nebudem popisovať. Ak nejaké vlastnosti nerozumiete, nájdete ju popísanú v českom CSS 3 manuálu.

table {
    border-spacing:0;
    border: 1px solid black;
    width: 500px;
}
table, table td {
    padding:0;
    margin: 0;
}
table td {
    border: 1px solid black;
}
table td input {
    padding:0;
    margin: 0;
    width: 100%;
    border: 0px solid transparent;
    height: 100%;
}

Tabuľka bude vyzerať približne takto.

Editor tabuliek
localhost

Ďalšie funkcie

Teraz budeme implementovať ďalšie funkcie nášho editora. Pôjdeme na to postupne. Aby naše funkcie mohol používateľ používať, musíme mu pridať nejaké ovládacie prvky, ktorými je vyvolá. Prakticky som chcel povedať, že budeme potrebovať tlačidla :) , Ale teoreticky by sme mohli využiť aj iných prvkov.

Pretože funkcií bude viac, bol by nezmysel neustále písať ... createElement("button"). Vytvoríme si na to funkciu vytvorTlacitkoAVlozHo(). Funkcia bude brať dva parametre - popisek a predka. Vytvorí tlačidlo, nastaví mu popisok, vloží ho do predka a vráti ho. Tlačidlo vraciame len kvôli tomu, aby sme mu mohli nastaviť obsluhu udalosti. Aj tu by sme teoreticky mohli odovzdať ako callback, ale tým by sme zbytočne znepřehlednili zdrojový kód.

function vytvorTlacitkoAVlozHo(popisek, rodic) {
    let btn = document.createElement("button");
    btn.textContent = popisek;
    rodic.appendChild(btn);
    return btn;
}

Teraz vytvoríme samotné tlačidlá funkciám. Cieľom tohto projektu bude naprogramovať funkcie pre pridanie stĺpca a riadku podľa vybranej bunky (tu máme uloženú v premennej aktivniBunka) a funkciu na odstránenie riadku a stĺpca. Vytvoríme si funkciu vytvorOvladaciTlacitka(). Vo funkcii budeme volať metódu pre vytvorenie tlačidla. Vrátená tlačidla si ani nemusíme ukladať, pretože obsluhu udalosti môžeme priradiť rovno vrátenej hodnote. Zatiaľ si necháme tlačidlá takto:

function vytvorOvladaciTlacitka() {
    vytvorTlacitkoAVlozHo("Pridať riadok nadol", document.body);
    vytvorTlacitkoAVlozHo("Pridať riadok hore", document.body);
    vytvorTlacitkoAVlozHo("Pridať stĺpec vľavo", document.body);
    vytvorTlacitkoAVlozHo("Pridať stĺpec vpravo", document.body);
    vytvorTlacitkoAVlozHo("Odstrániť riadok", document.body);
    vytvorTlacitkoAVlozHo("Odstrániť stĺpec", document.body);
}

Funkciu zavoláme v obsluhe udalosti window.onload:

window.onload = function () {
    vytvorOvladaciTlacitka();
    vytvorVychoziTabulku();
}

výsledok:

Editor tabuliek
localhost

Pridať riadok

Začneme tým jednoduchším - riadkom. Pretože máme dve funkcie editora, ktoré nejakým spôsobom vytvoria riadok a niekam ho vloží, napíšeme si funkciu, ktorá nám vytvorí element <tr> a vloží do neho toľko buniek, aby ich bolo ako u nejakého z už existujúcich riadkov. Počet buniek bude najjednoduchšie vziať hneď z prvého riadku.

function vytvorRadek() {
    let novyRadek = document.createElement("tr");

    for (let i = 0; i < tabulka.firstElementChild.childNodes.length; i++) {
        novyRadek.appendChild(vytvorBunku());
    }
    return novyRadek;
}

Je potrebné si uvedomiť čo je v ktorej premennej. Ako maximálna hodnota pre i v cykle je totiž table.firstElementChild.childNodes.length a na prvý pohľad sme len schopní povedať, že to má niečo spoločné s tabuľkou (table) a dĺžkou (length). Ostatné už na prvý pohľad nie je až tak jasné. Ideálne je, keď si formou komentáre zapíšeme čo kde je, alebo si hodnoty postupne rozložíme do premenných, nech sa nám v zápise lepšie orientuje.

Element <table> má elementy <tr>. Vieme teda, že table.firstElementChild je element <tr>, childNodes sú všetky elementy <td>, teda pole elementov <td> a length je dĺžka tohto poľa. Výsledkom teda je, že table.firstElementChild.childNodes.length obsahuje počet buniek prvého riadku tabuľky. Zápis je na vás, buď si to môžete postupne ukladať do premenných.

let prvniRadek = tabulka.firstElementChild;
let bunkyPrvnihoRadku = prvniRadek.childNodes;
let pocetBunekVPrvnimRadku = bunkyPrvnihoRadku.length;

Alebo si to nejako zjednodušene poznamenáte formou komentáre, nech aj budúci rok viete čo výraz znamená.

/*
 * table = <TABLE>
 * table.firstElementChild = <TR>
 * table.firstElementChild.childNodes = [<TD>]
 * table.firstElementChild.childNodes.length = number
 *
 * table.   firstElementChild.  childNodes  .length
 * <TABLE>. <TR>.           [<TD>]      .length
 */

Môžete si skúsiť precvičovať orientáciu v kóde, ako ochutnávku si skúste nejako premyslieť čo kde bude, keď budeme mať túto podmienku (v nasledujúcej lekcii tam skutočne bude):

if (table.childNodes[i].childNodes[indexOfSelected] == table.childNodes[i].lastElementChild) { }

V ďalšej lekcii, Dokončenie editora tabuliek v JavaScripte , budeme pokračovať.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 1834x (1.63 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Cyklus while v JavaScripte
Všetky články v sekcii
Základné konštrukcie jazyka JavaScript
Preskočiť článok
(neodporúčame)
Dokončenie editora tabuliek v JavaScripte
Článok pre vás napísal Michal Žůrek - misaz
Avatar
Užívateľské hodnotenie:
3 hlasov
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.
Aktivity