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.
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.
Ď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:
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