NOVINKA: Staň se datovým analytikem od 0 Kč a získej jistotu práce, lepší plat a nové kariérní možnosti. Více informací:

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í.

V dnešním tutoriálu objektově orientovaného programování v JavaScriptu do našeho diáře přidáme tlačítko pro splnění úkolu a jednoduchou validaci dat. Diář nakonec i celý dokončíme doplněním pár CSS stylů.

Změna splnění záznamů

Poslední funkcionalita, která nám chybí, je možnost označit úkoly jako splněné. Pro tuto funkcionalitu přidáme do diáře nové tlačítko.

Obecná metoda pro tvorbu tlačítek

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í. Nejprve si do třídy Diar přidáme novou pomocnou metodu #vytvorTlacitko():

#vytvorTlacitko(titulek, obsluha) {
    const button = document.createElement("button");
    button.onclick = obsluha;
    button.innerText = titulek;
    return button;
}

Metoda dělá přesně to, co naše metoda #vytvorMazaciTlacitko(). Titulek a obslužnou metodu tlačítka ovšem nastavuje z parametru, takže ji můžeme použít pro vytvoření různých tlačítek s různými titulky a funkcemi.

Úprava metody #vytvorMazaciTlacitko()

Nově vytvořenou metodu můžeme uplatnit ve zmíněné metodě #vytvorMazaciTlacitko(). Upravíme ji následujícím způsobem:

#vytvorMazaciTlacitko(zaznam) {
    return this.#vytvorTlacitko("Smazat", () => {
        if (confirm("Opravdu si přejete odstranit úkol?")) {
            this.#zaznamy = this.#zaznamy.filter(z => z !== zaznam);
            this.#ulozZaznamy();
            this.vypisZaznamy();
        }
    });
}

Tělo metody #vytvorMazaciTlacitko() je nyní tvořeno pouze jedním voláním metody #vytvorTlacitko(). Té jsme jako první parametr zadali popisek tlačítka Smazat a jako druhý anonymní funkci s logikou pro smazání záznamu.

Don't Repeat Yourself

Pomocnou metodu #vytvorTlacitko() 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řebujeme do aplikace vložit nějaký velmi podobný kód. Stávající kód vyčleníme do pomocné metody a parametrizujeme jej.

Prezence duplicitního kódu porušuje princip DRY (Don't Repeat Yourself), jedno z nejdůležitějších pravidel kvalitního objektového návrhu. Více se o něm dočteme v lekci Best practices pro vývoj softwaru - Základní praktiky.

Tlačítko na splnění záznamu

Po malé odbočce se vraťme zpět k novému tlačítku. To budeme vytvářet pomocí nové pomocné metody #vytvorTlacitkoSplneni(). Přidejme si ji do třídy Diar:

#vytvorTlacitkoSplneni(zaznam) {
    const titulek = "Označit jako " + (zaznam.splneno ? "nesplněný" : "splněný");

    return this.#vytvorTlacitko(titulek, () => {
        zaznam.splneno = !zaznam.splneno;
        this.#ulozZaznamy();
        this.vypisZaznamy();
    });
}

Metoda se moc neliší od metody #vytvorMazaciTlacitko(). Má pouze jeden parametr, kterým přijímá označovaný záznam. Na základě hodnoty vlastnosti splneno vytváříme titulek tlačítka. Titulek následně spolu s obslužnou funkcí tlačítka předáváme metodě #vytvorTlacitko().

Vytvoření tlačítka

Nyní už jen zbývá rozšířit metodu vypisZaznamy(). Tlačítko na splnění zde stejně jako mazací tlačítko vytvoříme ke každému záznamu a vložíme jej do elementu pro výpis:

vypisZaznamy() {
    this.#seradZaznamy();
    this.#vypisElement.innerHTML = "";
    let posledniDatum = null;

    for (const zaznam of this.#zaznamy) {
        /* Zbývající kód cyklu... */

        const smazatButton = this.#vytvorMazaciTlacitko(zaznam);
        this.#vypisElement.appendChild(smazatButton);
        const splnitButton = this.#vytvorTlacitkoSplneni(zaznam);
        this.#vypisElement.appendChild(splnitButton);

        this.#vypisElement.insertAdjacentHTML("beforeend", "<hr>");
    }
}

Výsledek si můžeme vyzkoušet:

Tvoje stránka
localhost

Ošetření vstupu

Máme tedy plně funkční diář s ukládáním do úložiště localStorage. Jediné, co nám ještě chybí, je ošetřit vstupy. Pokud totiž uživatel nezadá datum, bude se nám vypisovat jako Invalid Date a diář nebude správně fungovat.

Doplníme proto obslužnou funkci v metodě #nastavUdalosti() naší třídy Diar o jednoduchou validaci:

#nastavUdalosti() {
    this.#potvrditButton.onclick = () => {
        if (this.#nazevInput.value.length === 0) {
            alert("Musíte vyplnit název!");
            return;
        }

        if (this.#datumInput.value === "") {
            alert("Musíte vyplnit datum!");
            return;
        }

        const zaznam = new Zaznam(this.#nazevInput.value, this.#datumInput.value);
        this.#zaznamy.push(zaznam);
        this.#ulozZaznamy();
        this.vypisZaznamy();
    };
}

Díky tomu, že <input type="date"> vrací value jako prázdný řetězec, když je datum neúplné, není těžké uživatele na tento stav upozornit. Podobně to děláme u názvu, kde pro jednoduchost bráníme uživateli vložit pouze prázdný řetězec, čili délka hodnoty inputu nesmí být 0.

Pokud nyní nebude zadáno datum správně, nebo uživatel nezadá alespoň jeden znak do názvu úkolu, upozorníme uživatele funkcí alert(). V opačném případě nový záznam uložíme :)

Design

Nakonec zbývá už jen design, který si rychle prolétneme a jen minimálně upravíme v JavaScriptu. V projektu si nejprve vytvoříme složku css/ a přidáme do ní soubor styly.css. Jeho obsah bude následující:

* {
    font-family: Segoe UI Light, "Calibri Light", sans-serif;
}

body {
    margin-inline: auto;
    padding-inline: 1.5rem;
    max-width: 960px;
}

button {
    padding: 0.75rem 1rem;
    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: 0.5rem;
    border: 1px solid #c5c5c5;
}

button, input {
    margin-top: 1rem;
    outline: none;
}

.ukol {
    padding: 1rem;
    margin: 1rem auto;
    border: 1px solid #c5c5c5;
}

.ukol h3 {
    margin-top: 0;
    margin-bottom: 0.75rem;
}

.zelene {
    color: green;
}

.cervene {
    color: red;
}

.tucne {
    font-weight: bold;
}

Styly nalinkujeme v hlavičce stránky index.html:

<head>
    <meta charset="UTF-8">
    <title>Diář</title>
    <link href="css/styly.css" rel="stylesheet">
</head>

Poslední úpravy výpisu

A nyní jen lehce upravíme výpis záznamů. Přesuneme se tedy naposledy do metody vypisZaznamy() a obsah každého záznamu obalíme elementem <article>:

vypisZaznamy() {
    this.#seradZaznamy();
    this.#vypisElement.innerHTML = "";
    let posledniDatum = null;

    for (const zaznam of this.#zaznamy) {
        if (zaznam.datum !== posledniDatum) {
            const naformatovaneDatum = this.#naformatujDatum(zaznam.datum);
            this.#vypisElement.insertAdjacentHTML("beforeend", `<h2>${naformatovaneDatum}</h2>`);
        }
        posledniDatum = zaznam.datum;

        // Následující kód byl upraven
        const ukol = document.createElement("article");
        ukol.className = "ukol";

        ukol.insertAdjacentHTML(
            "beforeend",
            `<h3>${zaznam.nazev}</h3>
            <span>
                úkol ${!zaznam.splneno ? "<span class='cervene tucne'>ne" : "<span class='zelene tucne'>"}splněn</span>
            </span>
            <br>`);

        const smazatButton = this.#vytvorMazaciTlacitko(zaznam);
        ukol.appendChild(smazatButton);
        const splnitButton = this.#vytvorTlacitkoSplneni(zaznam);
        ukol.appendChild(splnitButton);

        this.#vypisElement.appendChild(ukol);
    }
}

Ihned po případném vypsání data vytváříme zmiňovaný element <article> s nastavenou CSS třídou .ukol. Do něj pak vkládáme všechen obsah záznamu včetně názvu, splněnosti a obou tlačítek. Za zmínku zde stojí upravený výpis splněnosti úkolu, který obarvujeme buď červeně, anebo zeleně. Samotný element <article> nakonec vkládáme do elementu pro výpis.

Výsledek

Podívejme se na náš vylepšený diář v prohlížeči:

Diář
index.html

Tak a je hotovo! :) Máme celkem pěkně vypadající diář, který ukládá data a lze jej reálně používat.

V příští lekci, AJAX v JavaScriptu - Základní dotazy, na nás čeká populární technologie AJAX a tvorba malého projektu.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 1354x (4.1 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
OOP diář v JavaScriptu - Formátování a mazání záznamů
Všechny články v sekci
Objektově orientované programování v JavaScriptu
Přeskočit článek
(nedoporučujeme)
AJAX v JavaScriptu - Základní dotazy
Článek pro vás napsal Šimon Raichl
Avatar
Uživatelské hodnocení:
248 hlasů
Autor se věnuje především vývoji v JavaScriptu
Aktivity