Lekce 10 - Editor tabulek v JavaScriptu
V minulé lekci, Manipulace s DOM v JavaScriptu, jsme se naučili pracovat s DOM a měnit tak obsah stránky.
Dnes by jsme měli umět již vše potřebné, abychom si vytvořili nějakou pravou webovou aplikaci. Jako příklad, na kterém se zároveň něco málo přiučíme, si v dnešním JavaScript tutoriálu naprogramujeme editor tabulek.
Tabulka je velmi zajímavý a specifický prvek webových stránek. Tabulka
má řádky <tr>
a buňky <td>
.
<td>
náleží <tr>
a
<tr>
náleží v nejjednodušším případě
<table>
.
HTML
Vytvořme si nějakou stránku, CSS soubor a JS soubor. CSS a JS do stránky v hlavičce naimportujeme a tím máme stránku hotovou, to že je body prázdné, nám spíše dokonce vyhovuje, protože si vše potřebné připravíme ve skriptu. Je to pro nás dokonce výhodné, nasadíme-li aplikaci na jiné stránce, nemusíme již vůbec zasahovat do HTML. Abychom měli kód nějakým způsobem jednotný, protože v dalších JS lekcích budeme skript zdokonalovat, HTML stránka vypadá následovně. Všímejte si názvu souborů.
<!DOCTYPE html> <html lang="cs"> <head> <title>Editor tabulek</title> <meta charset="utf-8" /> <script src="editor-tabulek.js"></script> <link rel="stylesheet" href="editor-tabulek.css" type="text/css" /> </head> <body> </body> </html>
JavaScript
V souboru editor-tabulek.js
si vytvoříme 3 proměnné.
Proměnná tabulka
bude obsahovat samotnou tabulku a poté budeme
mít proměnné vychoziVelikostX
a vychoziVelikostY
pro výchozí velikost tabulky. Tabulku necháme bez hodnoty a proměnným pro
výchozí velikost dosadíme nějaká 2 kladná rozumně velká čísla.
Např.:
let tabulka; let vychoziVelikostX = 5; let vychoziVelikostY = 3;
Později budeme potřebovat ještě jednu proměnnou, ale tou se nyní nebudeme zabývat. Vytvoříme funkce pro vygenerování ovládacích tlačítek a samotné tabulky. Funkci pro vygenerování tlačítek si necháme na později.
Funkce pro vytvoření tabulky (pojmenujeme si ji
vytvorVychoziTabulku()
) vytvoří tabulku a vloží ji do body.
Dvěma vnořenými cykly vytvoříme její buňky. Aby byly buňky
editovatelné, vložíme do nich klasické textové pole – element
<input>
. Protože buňky budeme vytvářet na více místech,
vytvoříme si pro jejich tvorbu funkci vytvorBunku()
. Ta vytvoří
element <td>
a <input>
.
<input>
vloží do <td>
a buňku vrátí.
Jelikož budeme programovat funkce, které v tabulce předpokládají označenou
buňku, při označení buňky si tuto buňku musíme někam uložit. Existuje
událost focus
, která je vyvolána ve chvíli, kdy uživatel
vybere nějaký prvek, ať již do něj klikne nebo se na něj třeba přesune
tabulátorem. Při vytváření buňky událost tedy zároveň nově
vytvořenému inputu obsloužíme a do proměnné aktivniBunka
(kterou deklarujeme před deklarací funkce) buňku uložíme v případě, že
je označená. Je třeba pamatovat na to, že při obsluhování události se
mění obsah klíčového slova this
na prvek, který událost
vyvolal. Do proměnné aktivniBunka
uložíme právě
this
(což bude element <input>
, protože on
vyvolal událost).
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; }
Vraťme se k funkci, která vytvoří výchozí tabulku. Nejprve se vrhneme na vytvoření samotné tabulky.
function vytvorVychoziTabulku() { tabulka = document.createElement("table"); document.body.appendChild(tabulka); }
Do proměnné tabulka
uložíme nově vytvořený element
<table>
a ten vložíme do elementu
<body>
. Všimněte si, že když se chceme dostat
k <body>
, nemusíme složitě přes
getElementsByTagName()
nebo podobné, ale element je
předpřipravený v document.body
.
Nyní se podívejme na samotné cykly. Nejprve vytvoříme elementy řádku
(cyklus y
) a každý nový řádek ihned vložíme do tabulky
(ostatně vkládání je lepší vždy dělat dříve, než na to později
zapomenout). Poté vnořeným cyklem vytvoříme jednotlivé buňky a přidáme
je do řádku. Využijeme k tomu metodu vytvorBunku()
, kterou jsme
si připravili před chvílí. Cyklům jako horní hodnoty předáme proměnné
vychoziVelikostX
a vychoziVelikostY
tak, aby se
vytvořil správný počet řádků a sloupců.
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()); } } }
Nyní již máme základ hotový. V obsluze události onload
na
objektu window
tuto funkci zavoláme.
window.onload = function () { vytvorVychoziTabulku(); }
Takováto obsluha událostí by vám již měla být dobře známa. Jedná se o anonymní funkci přiřazenou do obsluhy události po načtení stránky. Když aplikaci spustíme, uvidíme tabulku (nejspíše bez ohraničení) a v ní inputy.
CSS
Gratuluji, vytvořili jste první aplikaci, která vygenerovala tabulku. Než se pustíme do další části, ostylujme si ji, ať vypadá trochu k světu. CSS nebudu popisovat. Pokud nějaké vlastnosti nerozumíte, naleznete ji popsanou v českém 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%; }
Tabulka bude vypadat přibližně takto.
Další funkce
Nyní budeme implementovat další funkce našeho editoru. Půjdeme na to
postupně. Aby naše funkce mohl uživatel používat, musíme mu přidat
nějaké ovládací prvky, kterými je vyvolá. Prakticky jsem chtěl říci,
že budeme potřebovat tlačítka , ale teoreticky bychom mohli využít i jiných prvků.
Protože funkcí bude více, byl by nesmysl neustále psát
...createElement("button")
. Vytvoříme si na to funkci
vytvorTlacitkoAVlozHo()
. Funkce bude brát dva parametry - popisek
a předka. Vytvoří tlačítko, nastaví mu popisek, vloží ho do předka a
vrátí ho. Tlačítko vracíme jen kvůli tomu, abychom mu mohli nastavit
obsluhu události. I tu bychom teoreticky mohli předat jako callback, ale tím
bychom zbytečně znepřehlednili zdrojový kód.
function vytvorTlacitkoAVlozHo(popisek, rodic) { let btn = document.createElement("button"); btn.textContent = popisek; rodic.appendChild(btn); return btn; }
Nyní vytvoříme samotná tlačítka funkcím. Cílem tohoto projektu bude
naprogramovat funkce pro přidání sloupce a řádku podle vybrané buňky (tu
máme uloženou v proměnné aktivniBunka
) a funkci pro
odstranění řádku a sloupce. Vytvoříme si funkci
vytvorOvladaciTlacitka()
. Ve funkci budeme volat metodu pro
vytvoření tlačítka. Vrácená tlačítka si ani nemusíme ukládat, protože
obsluhu události můžeme přiřadit rovnou vrácené hodnotě. Prozatím si
necháme tlačítka takto:
function vytvorOvladaciTlacitka() { vytvorTlacitkoAVlozHo("Přidat řádek dolů", document.body); vytvorTlacitkoAVlozHo("Přidat řádek nahoru", document.body); vytvorTlacitkoAVlozHo("Přidat sloupec vlevo", document.body); vytvorTlacitkoAVlozHo("Přidat sloupec vpravo", document.body); vytvorTlacitkoAVlozHo("Odstranit řádek", document.body); vytvorTlacitkoAVlozHo("Odstranit sloupec", document.body); }
Funkci zavoláme v obsluze události window.onload
:
window.onload = function () { vytvorOvladaciTlacitka(); vytvorVychoziTabulku(); }
Výsledek:
Přidat řádek
Začneme tím jednodušším – řádkem. Protože máme dvě funkce
editoru, které nějakým způsobem vytvoří řádek a někam ho vloží,
napíšeme si funkci, která nám vytvoří element <tr>
a
vloží do něj tolik buněk, aby jich bylo jako u nějakého z již
existujících řádků. Počet buněk bude nejjednodušší vzít hned
z prvního řádku.
function vytvorRadek() { let novyRadek = document.createElement("tr"); for (let i = 0; i < tabulka.firstElementChild.childNodes.length; i++) { novyRadek.appendChild(vytvorBunku()); } return novyRadek; }
Je třeba si uvědomit co je v které proměnné. Jako maximální hodnota
pro i
v cyklu je totiž
table.firstElementChild.childNodes.length
a na první pohled jsme
pouze schopni říci, že to má něco společného s tabulkou
(table
) a délkou (length
). Ostatní již na první
pohled není až tak jasné. Ideální je, když si formou komentáře
zapíšeme co kde je nebo si hodnoty postupně rozložíme do proměnných, ať
se nám v zápisu lépe orientuje.
Element <table>
má elementy <tr>
.
Víme tedy, že table.firstElementChild
je element
<tr>
, childNodes
jsou všechny elementy
<td>
, tedy pole elementů <td>
a
length
je délka tohoto pole. Výsledkem tedy je, že
table.firstElementChild.childNodes.length
obsahuje počet buněk
prvního řádku tabulky. Zápis je na vás, buď si to můžete postupně
ukládat do proměnných.
let prvniRadek = tabulka.firstElementChild;
let bunkyPrvnihoRadku = prvniRadek.childNodes;
let pocetBunekVPrvnimRadku = bunkyPrvnihoRadku.length;
Nebo si to nějak zjednodušeně poznamenáte formou komentáře, ať i příští rok víte co 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 zkusit procvičovat orientaci v kódu, jako ochutnávku si zkuste nějak promyslet co kde bude, když budeme mít tuto podmínku (v příští lekci tam skutečně bude):
if (table.childNodes[i].childNodes[indexOfSelected] == table.childNodes[i].lastElementChild) { }
V další lekci, Dokončení editoru tabulek v JavaScriptu, se naučíme do editoru tabulek vkládat sloupce a řádky před, za, nad, pod a taky je mazat.
Stáhnout
Staženo 901x (1.97 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript
Komentáře


Zobrazeno 10 zpráv z 43. Zobrazit vše