Lekce 10 - Dokončení objektového diáře v JavaScriptu
V minulé lekci, OOP diář v JavaScriptu - Formátování a mazání záznamů, jsme do našeho objektového diáře v JavaScriptu přidali několik dalších funkcí.
Dnes do našeho diáře přidáme tlačítko na splnění úkolu, validaci
data a jednoduché CSS styly
Změna splněnosti záznamů
Poslední tlačítko, které nám chybí, je tlačítko na splnění úkolu.
Parametrizace
Protože tlačítko na splnění úkolu bude vypadat a fungovat velmi podobně jako mazací tlačítko, nebudeme do aplikace zbytečně vkládat duplicitní kód, ale upravíme ten stávající. Vytvoříme si pomocnou metodu na vložení tlačítka k úkolu:
_pridejTlacitko(titulek, callback, element) { const button = document.createElement("button"); button.onclick = callback; button.innerText = titulek; element.appendChild(button); }
Metoda _pridejTlacitko()
dělá přesně to, co jsme měli u
přidání mazacího tlačítka. Titulek a obslužnou metodu tlačítka ovšem
nastavuje z parametru, takže ji můžeme použít pro vložení různých
tlačítek s různými titulky a funkcemi. Jako navíc si uvedeme i třetí
parametr pro specifikování elementu, kde bude tlačítko vloženo.
Místo veškerého kódu pro mazací tlačítko nyní stačí do metody
vypisZaznamy()
vložit jen:
this._pridejTlacitko("Smazat", () => { if (confirm("Opravdu si přejete odstranit úkol?")) { this.zaznamy = this.zaznamy.filter(z => z !== zaznam); // Ponechá vše co není rovné proměnné zaznam this.ulozZaznamy(); this.vypisZaznamy(); } }, this.vypisElement);
Pomocnou metodu jsme si vytvořili záměrně až nyní a ne již před přidáním prvního tlačítka. To abychom si ukázali, jak se v praxi řeší situace, když potřebujete do aplikace vložit nějaký velmi podobný kód. Kód stávající vyčleníte do pomocné metody a parametrizujete jej. Prezence duplicitního kódu porušuje princip DRY, jedno z nejdůležitějších pravidel kvalitního objektového návrhu.
Privátní metody
Všimněte si, že název metody začíná na podtržítko. Pomocné metody, které by na naší třídě neměl zvenčí nikdo volat, by se měly ideálně skrýt. JavaScript v současné době bohužel neumožňuje metody rozumně zapouzdřit. Dále v kurzu si sice ukážeme, že je to možné, ale jen pomocí hacků, což kód ve výsledku znepřehlední. Označení privátních vlastností a metod pomocí podtržítka je poměrně dobrý návyk a dělá se tak často i v ostatních jazycích, které nepodporují modifikátory přístupu.
Aby byl náš kód opravdu dobře napsaný, označme si podtržítkem i
metodu _nastavUdalosti()
. Rovněž se jedná jen o pomocnou
funkcionalitu, která by zvenčí neměla být volána.:
_nastavUdalosti() { // ... }
Nezapomeňte přejmenovat i volání metody v konstruktoru:
constructor(jazyk = "cs-CZ") { // ... this._nastavUdalosti(); }
Tlačítko na splnění záznamu
Po malé odbočce se vraťme zpět k novému tlačítku. To nyní vložíme
pomocí připravené metody _pridejTlacitko()
:
this._pridejTlacitko("Označit jako " + (zaznam.splneno ? "nesplněný" : "splněný"), () => { zaznam.splneno = !zaznam.splneno; this.ulozZaznamy(); this.vypisZaznamy(); }, this.vypisElement);
Výsledek si můžete vyzkoušet
Ošetření vstupu
Máme tedy plně funkční diář s ukládáním do
localStorage
. Jediné, co nám ještě chybí, je ošetřit vstup,
protože pokud uživatel nezadá datum, bude se nám vypisovat jako "Invalid
Date". Upravíme si tedy metodu _nastavUdalosti()
a uděláme zde
jednoduchou validaci. Díky tomu, že <input type="date">
vrací value
jako prázdný string
, když je datum
neúplné, není těžké uživatele na tento stav upozornit. Podobně to
můžeme udělat u názvu, pro jednoduchost zabráníme uživateli pouze
prázdný řetězec, čili délka hodnoty inputu nesmí být 0
:
_nastavUdalosti() { this.potvrditButton.onclick = () => { // this zůstane nyní stále this console.log(this.nazevInput.value.length); if (this.datumInput.value !== "" && this.nazevInput.value.length !== 0) { const zaznam = new Zaznam(this.nazevInput.value, this.datumInput.value); this.zaznamy.push(zaznam); this.ulozZaznamy(); this.vypisZaznamy(); } else alert("Musíte vyplnit datum a název!"); }; }
Takže pokud nebude zadáno datum správně, upozorníme uživatele funkcí
alert()
, že ho má zadat správně. Pokud však nezadal alespoň 1
znak do názvu úkolu, záznam neuložíme. V opačném případě nový záznam
uložíme
Design
Nyní již zbývá jen nějaký design, který si rychle prolétneme a jen
minimálně upravíme v JS. Vytvoříme si v projektu složku css/
,
a nový soubor styly.css
. Jeho obsah bude následující:
* { font-family: Segoe UI Light, "Calibri Light", sans-serif; } button { padding: 10px 16px; font-weight: 600; background: #2792e0; color: #fff; border: none; cursor: pointer; transition: .5s; } button:hover { background: #2954c2; } button:active { background: #204199; } input { min-width: 250px; padding: 8px; border: 1px solid #909090; height: 20px; } button, input { margin-top: 1rem; outline: none; } .ukol { width: 75%; padding: 2rem; margin: 1rem auto; border: 1px solid #c5c5c5; box-shadow: 2px 2px 4px #b1b1b1; } .zelene { color: green; } .cervene { color: red; } .tucne { font-weight: bold; }
Styly nalinkujeme v index.html
:
<link href="css/styly.css" rel="stylesheet">
A nyní jen lehce upravíme výpis každého záznamu. Začneme tím, že
vytvoříme element <div>
do proměnné ukol
.
Úkolu nastavíme třídu .ukol
. Vše nyní budeme ukládat do
úkolu, čili místo this.vypisElement
bude ukol
.
Obarvíme splněnost úkolu a nakonec úkol uložíme do záznamů:
vypisZaznamy() { this.seradZaznamy(); this.vypisElement.innerHTML = ""; let posledniDatum = null; for (const zaznam of this.zaznamy) { const ukol = document.createElement("div"); ukol.className = "ukol"; if (zaznam.datum !== posledniDatum) { const datum = new Date(zaznam.datum).toLocaleDateString(this.jazyk, { weekday: "long", day: "numeric", month: "short", year: "numeric" }); ukol.insertAdjacentHTML("beforeend", `<h3>${datum}</h3>`); } posledniDatum = zaznam.datum; ukol.insertAdjacentHTML("beforeend", `<h4>${zaznam.nazev}</h4> <p>úkol ${!zaznam.splneno ? "<span class='cervene tucne'>ne" : "<span class='zelene tucne'>"}splněn</span></p>`); this._pridejTlacitko("Smazat", () => { if (confirm("Opravdu si přejete odstranit úkol?")) { this.zaznamy = this.zaznamy.filter(z => z !== zaznam); // Ponechá vše co není rovné proměnné zaznam this.ulozZaznamy(); this.vypisZaznamy(); } }, ukol); this._pridejTlacitko("Označit jako " + (zaznam.splneno ? "nesplněný" : "splněný"), () => { zaznam.splneno = !zaznam.splneno; this.ulozZaznamy(); this.vypisZaznamy(); }, ukol); ukol.insertAdjacentHTML("beforeend", "</div>"); this.vypisElement.appendChild(ukol); } }
Výsledek:
Tak a je hotovo! Máme tedy
celkem pěkně vypadající diář, který ukládá data a lze jej reálně
používat
Pokud jste měli s
čímkoli problém, pod článkem si můžete stáhnout kompletní zdrojové
kódy a najít si chybu.
V příští lekci, AJAX v JavaScriptu - Základní dotazy, na nás čeká populární technologie AJAX!
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkamiStaženo 1278x (4.21 kB)