<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="/cjs/screen.xsl" media="screen"?>
<lecture>

<meta>
  <maintitle>HTML5</maintitle>
  <author>Jiří Novotný</author>
  <title>Formuláře</title>
  <date>2014-01-xx</date>
  <link><!--a href="http://vyuka.ookami.cz" rel="external">http://vyuka.ookami.cz</a--></link>
</meta>
<!--
  „“–
  ↵ aneb &#x21B5; aneb \r aneb CR aneb CarriageReturn
-->

<slide title="Úvod do formulářů">

    <h4 class="center">
        (přednášku připravil Jiří Novotný)
    </h4>
    
    <p>
      Formuláře neboli <em>forms</em> jsou něčím, bez čeho by se Internet (respektive <em>World Wide Web</em>) neobešel. Zajišťují totiž zásadní věc – odesílání dat na server, kde dojde k jejich zpracování, většinou nějakým skriptovacím jazykem (PHP, Python apod.).
    </p>
    <p>
        V této lekci nás ale bude primárně zajímat používání různých ovládacích prvků, které s sebou přinesl standard HTML5.
    </p>

</slide>
<slide title="Poznámka – značení prvků v těchto slajdech">

    <p>
        V textu budou jiným písmem, než má obyčejný text, odlišeny názvy elementů, atributů a jejich hodnot:
    </p>
    <ul>
        <li>
            <elmnt>&lt;element&gt;</elmnt>
        </li>
        <li>
            <attr>atribut</attr>
        </li>
        <li>
            <attrval>hodnota atributu</attrval>
        </li>
    </ul>
    <note>
        Pokud se bude mluvit o konkrétních ovládacích prvcích, zobrazených na výstupu, budou napsány <em>kurzívou</em>.
    </note>

</slide>
<slide title="O atributech s pravdivostní hodnotou">

    <p>
        Některé atributy jsou typu <strong>boolean</strong> a jejich použití může být lehce matoucí, takže tady je krátká vysvětlivka:
    </p>
    <ul>
        <li>
            <em>false</em> jsou tehdy, když <strong>nejsou</strong> zapsány u elementu;
        </li>
        <li>
            <em>true</em> jsou tehdy, když <strong>jsou</strong> zapsány u elementu.
        </li>
    </ul>
    <note>
        <em>false</em> jsou tedy automaticky všechny <strong>boolean</strong> atributy, které nezapíšete k danému elementu.
    </note>
    <p>
        A jak mohou být zapsány? Oficiálně by měly fungovat dva zápisy:
    </p>
    <ul>
        <li>
            <elmnt>&lt;element boolean_atribut=&quot;boolean_atribut&quot;&gt;</elmnt> – zřejmě nejkompatibilnější způsob zápisu;
        </li>
        <li>
            <elmnt>&lt;element boolean_atribut&gt;</elmnt> – tohle nefungovalo, ale mělo by (radši se tomu vyhnout ;).
        </li>
    </ul>
    <p>
        Konkrétní a fungující příklad: <elmnt>&lt;input name="bool" type="text" required=&quot;required&quot; /&gt;</elmnt>
    </p>

</slide>
<slide title="Struktura formulářů">
  
    <p class="enumerate">
      Základním elementem formulářů je element <elmnt>&lt;form&gt;</elmnt>. V něm můžou a nemusí být jednotlivé ovládací prvky formuláře (anglicky <em>widgets</em>, dále jen <strong>prvky</strong>). Prvky (např. <elmnt>&lt;input&gt;</elmnt>) je totiž, jak sami uvidíte, možné přidávat i mimo <elmnt>&lt;form&gt;</elmnt>. Dalo by se vlastně říci, že <elmnt>&lt;form&gt;</elmnt> je tu hlavně proto, aby skupině prvků přiřazoval stejné vlastnosti a také aby prohlížeč věděl, hodnoty kterých prvků má odeslat serveru.
    </p>
    
    <p class="enumerate">
      Pak tu máme některé další hlavní elementy, které <strong>slouží hlavně k přehledné navigaci ve formuláři</strong>. Je dobré zmínit, že <strong>tyto elementy nejsou povinné</strong>, nicméně je dobré je používat právě kvůli zmíněné přehlednosti. Hned <a href="?slajd=5">na dalším slajdu</a> si na příkladu ukážeme, jak vypadají :)
    </p>
    <ul>
        <li>
            <elmnt>&lt;fieldset&gt;</elmnt> – je to něco jako rámeček, který k sobě logicky sdružuje skupinu prvků (graficky)
            <ul>
                <li>
                    <elmnt>&lt;legend&gt;</elmnt> – nadpis rámečku, potomek <elmnt>&lt;fieldset&gt;</elmnt>
                </li>
                <li>
                    <attr>disabled</attr> – boolean atribut. Je-li nastaven na <em>true</em>, znepřístupní prvky uvnitř <elmnt>&lt;fieldset&gt;</elmnt>
                </li>
                <li>
                    <attr>form</attr>, <attr>name</attr>
                </li>
            </ul>
        </li>
        <li>
            <elmnt>&lt;label&gt;</elmnt> – používá se k popisu prvků
            <ul>
                <li>
                    <attr>for</attr>, <attr>form</attr>
                </li>
            </ul>
        </li>
    </ul>

</slide>
<slide title="Příklad">

    <example layout="html5">
      <html src="_files/forms/form_fieldset_label.html"/>
      <css src="_files/forms/form_fieldset_label.css"/>
      <output src="_files/forms/form_fieldset_label.src.html"/>
    </example>
    <ul>
        <li>
            Element <elmnt>&lt;form&gt;</elmnt> nám ohraničuje formulář „kódově“.
            <note>Přímo ve specifikaci HTML je přísně zakázáno používat vnořené <elmnt>&lt;form&gt;</elmnt>! Některé prohlížeče to totiž nemusí rozdýchat.</note>
        </li>
        <li>
            Ve <elmnt>&lt;form&gt;</elmnt> vnořené <elmnt>&lt;fieldset&gt;</elmnt> nám ohraničují skupinu prvků graficky.
            <note>Do sebe vnořené <elmnt>&lt;fieldset&gt;</elmnt> (jak vidno) nejsou problém.</note>
        </li>
        <li>
            Po <elmnt>&lt;fieldset&gt;</elmnt> by měl následovat <elmnt>&lt;legend&gt;</elmnt>, protože jen tak bude nadpis rámečku tam, kde by měl být, tj. v čáře rámečku ohraničujícího příslušný <em>fieldset</em>.
        </li>
        <li>
            <elmnt>&lt;label&gt;</elmnt> se dá napsat vlastně kamkoliv, a nebo se do něj prvek dá uzavřít, jak je vidět ve vnořeném rámečku v příkladu.
            <note>
              V případě vnoření prvku do <elmnt>&lt;label&gt;</elmnt> zde funguje podobná vlastnost jako v případě <elmnt>&lt;label&gt;</elmnt> spojeného s určitým prvkem (atribut <attr>for</attr>, uvidíte na dalším slajdu).
            </note>
        </li>
        <li>
            Samotné prvky (v našem případě <elmnt>&lt;input&gt;</elmnt> typu <attrval>number</attrval>) jsou tedy umístěny uvnitř <elmnt>&lt;fieldset&gt;</elmnt>.
        </li> 
        <li>
            Je zde jednoduchý Javascript: <elmnt>&lt;output&gt;</elmnt> i <elmnt>&lt;input&gt;</elmnt> mají v <em>DOM</em>ovské reprezentaci atribut <attr>value</attr>. Při změně <attr>value</attr> v jednom z <em>inputů</em> (atribut <attr>oninput</attr>) se součet hodnot v <em>inputech</em> nastaví jako <attr>value</attr> <em>outputu</em> a hned se vypíše.
        </li>
        <li>
            Poslední <elmnt>&lt;fieldset&gt;</elmnt> má nastaven <attr>disabled</attr> na <em>true</em>. Výsledek je jasný :)
        </li>
    </ul>

</slide>
<slide title="Struktura formulářů – @id, @form, @for">

    <p>
        Teď se podíváme na logické propojování prvků a <elmnt>&lt;form&gt;</elmnt>.
    </p>
    
    <p class="enumerate">
        Jak jistě víte, každý element v HTML má atribut <attr>id</attr>, který ho jednoznačně identifikuje v rámci dokumentu. Formulářové elementy nejsou výjimkou. Některé mají atribut <attr>form</attr>, který je přiřazuje k určitému <elmnt>&lt;form&gt;</elmnt>. Hodnotou atributu <attr>form</attr> je hodnota <attr>id</attr> příslušného <elmnt>&lt;form&gt;</elmnt>. Díky <attr>form</attr> mohou prvky být mimo <elmnt>&lt;form&gt;</elmnt>, ale stále s ním být „ve spojení“, tj. <strong>data z těchto prvků jsou zpracována příslušným</strong> <elmnt>&lt;form&gt;</elmnt>. Bohužel to neznamená, že by prvky virtuálně ležely uvnitř <elmnt>&lt;form&gt;</elmnt> a sdílely tak např. jeho stylování – jde jen o jejich zpracování.
    </p>
    <note>
        Nicméně např. <em>reset button</em> dělá to, co by normálně dělal, kdyby ležel uvnitř <elmnt>&lt;form&gt;</elmnt>, a to obnovování formuláře do původní podoby.
    </note>
    
    <p class="enumerate">
      Element <elmnt>&lt;label&gt;</elmnt> má speciální atribut <attr>for</attr>, který ho přiřazuje k určitému prvku. Jeho hodnotou je hodnota <attr>id</attr>
      příslušného prvku. <strong>Pokud uživatel klikne na takto přiřazený <em>label</em>, aktivuje se s ním spojený prvek</strong>.
    </p>

</slide>
<slide title="Struktura formulářů – @id vs @name">

    <p>
        Možná Vás napadlo, jaký je rozdíl mezi atributy <attr>id</attr> a <attr>name</attr>, když oba pojmenovávají elementy (prvky) – celkem zásadní, protože oba slouží k jiným účelům:
    </p>
    <ul>
        <li>
            <attr>id</attr> – jak už bylo řečeno, tento atribut poskytuje <strong>jednoznačnou identifikaci elementu v rámci dokumentu</strong>, a musí proto být jedinečný. Odkazují se na něj atributy <attr>form</attr> a <attr>for</attr>.
        </li>
        <li>
            <attr>name</attr> – tento atribut <strong>identifikuje prvek při odesílání na server</strong> a nemusí být jedinečný.
        </li>
    </ul>
    <p>
        Malý příklad, proč hodnota <attr>name</attr> nemusí být jedinečná:
    </p>
    <example layout="html5">
      <html src="_files/forms/id_name.html"/>
      <css src="_files/forms/id_name.css"/>
      <output src="_files/forms/id_name.src.html"/>
    </example>
    <ul>
        <li>
            V tomto příkladu máme tři <em>checkboxy</em> – mají jiné hodnoty <attr>value</attr>, ale stejné hodnoty <attr>name</attr>.
        </li>
        <li>
            Při odeslání na server může přijít informace, že uživatel zvolil <em>checkboxy</em> s hodnotami <attr>value</attr> <attrval>jablko</attrval> a <attrval>hruska</attrval>.
        </li>
        <li>
            Oba tyto zvolené <em>checkboxy</em> mají stejnou hodnotu <attr>name</attr>, takže server ví, do jaké kategorie oba zvolené <em>checkboxy</em> patří.
        </li>
    </ul>
    <p>
        Dá se tedy říct, že v případě prvků spadajících do stejné kategorie je hodnota <attr>name</attr> něco jako „krabice“ a hodnoty <attr>value</attr> pak její „obsah“.
    </p>

</slide>
<slide title="Příklad – přiřazování prvků">

    <example layout="html5">
      <html src="_files/forms/id_form_for.html"/>
      <css src="_files/forms/id_form_for.css"/>
      <output src="_files/forms/id_form_for.src.html"/>
    </example>
    <p>
        Tento formulář obsahuje tři samostatné bloky:
    </p>
    <ol>
        <li>
            <elmnt>&lt;form&gt;</elmnt>, v němž leží <elmnt>&lt;fieldset&gt;</elmnt> s prvky a mimo <elmnt>&lt;fieldset&gt;</elmnt> ještě <elmnt>&lt;label&gt;</elmnt>:
            <ul>
                <li>
                    Uvnitř <elmnt>&lt;fieldset&gt;</elmnt> máme jednoduchý <elmnt>&lt;input&gt;</elmnt> typu <attrval>text</attrval> a hned u něj <elmnt>&lt;input&gt;</elmnt> typu <attrval>reset</attrval> (<em>reset button</em>), který obnoví formulář do původní podoby.
                </li>
                <li>
                    Pak následuje <elmnt>&lt;label&gt;</elmnt> s atributem <attr>for</attr>="<attrval>reset_button</attrval>", čímž je k tomuto prvku přiřazen.
                    <note>
                        Na tohle jsem upozorňoval v předchozím slajdu – pokud je prvek uzavřen do <elmnt>&lt;label&gt;</elmnt>, chová se <elmnt>&lt;label&gt;</elmnt> stejně, jako by měl atribut <attr>for</attr>="<attrval>id_prvku</attrval>"
                    </note>
                </li>
            </ul>
        </li>
        <li>
            Samostatný <elmnt>&lt;fieldset&gt;</elmnt>, neležící uvnitř <elmnt>&lt;form&gt;</elmnt>:
            <ul>
                <li>
                    Zde máme uvnitř <elmnt>&lt;fieldset&gt;</elmnt> <elmnt>&lt;input&gt;</elmnt> typu <attrval>reset</attrval> přiřazený k našemu <elmnt>&lt;form&gt;</elmnt>, a proto po kliknutí normálně obnoví formulář.
                    <note>
                        Logicky mě napadlo, že pokud bych tento <elmnt>&lt;fieldset&gt;</elmnt> přiřadil k našemu <elmnt>&lt;form&gt;</elmnt>, byly by k němu přiřazeny i všechny prvky ležící uvnitř tohoto <elmnt>&lt;fieldset&gt;</elmnt>. Bohužel se zdá, že tato podle mě celkem užitečná věc zatím funguje jen v Opeře...
                    </note>
                </li>
            </ul>
        </li>
        <li>
            Úplně samostatný <em>label</em> a <em>reset button</em>, přiřazený k <elmnt>&lt;form&gt;</elmnt>:
            <ul>
                <li>
                    Všimněte si, že <elmnt>&lt;label&gt;</elmnt> není přiřazen k <elmnt>&lt;input&gt;</elmnt> a po kliknutí tedy <em>reset button</em> neaktivuje.
                </li>
            </ul>
        </li>
    </ol>

</slide>
<slide title="Možné využití atributu @form">

    <p>
      Odkazování na <elmnt>&lt;form&gt;</elmnt> může mít jedno zajímavé využití:
    </p>
    <example layout="html5">
      <html src="_files/forms/vyuziti_form_atributu.html"/>
      <css src="_files/forms/vyuziti_form_atributu.css"/>
      <output src="_files/forms/vyuziti_form_atributu.src.html"/>
    </example>
    <ul>
        <li>
            V tomto příkladu máme dva <elmnt>&lt;form&gt;</elmnt>. Jeden by zpracovával objednávky, druhý by vyhledával zboží.
        </li>
        <li>
            Pak zde máme několik prvků, které využívají naše dva <elmnt>&lt;form&gt;</elmnt>.
        </li>
    </ul>
    <p>
        A co z toho plyne? :) Můžeme si vytvořit několik „šablonových“ <elmnt>&lt;form&gt;</elmnt>, jednotlivé prvky mít rozesety po stránce a odkazovat je podle potřeby na příslušné <elmnt>&lt;form&gt;</elmnt>.
    </p>

</slide>
<slide title="Element &lt;form&gt;">

    <p>
      Jak už bylo řečeno dříve, <elmnt>&lt;form&gt;</elmnt> je naším základním formulářovým elementem. Pojďme se nyní podívat
      na jeho hlavní atributy:
    </p>
    <ul>
        <li>
            <attr>action</attr> – hodnotou je URI adresa, na kterou budou odeslána data.
        </li>
        <li>
            <attr>autocomplete</attr> – může nabývat hodnot <em>on</em> nebo <em>off</em>, přičemž <em>on</em> je výchozí hodnota. Je to vlastně automatické vyplňování formulářů prohlížečem na základě údajů zadaných uživatelem v minulosti.
            <note>
                Logicky funguje jen s textovými prvky. <em>Checkboxy</em> se Vám samy nevyplní ;)
            </note>
        </li>
        <li>
            <attr>enctype</attr> – určuje způsob, jakým mají být data zakódována před odesláním na server. Možné hodnoty:
            <ul>
                <li>
                    <attrval>application/x-www-form-urlencoded</attrval> – defaultní hodnota. Všechny znaky jsou zakódovány, mezery převedeny na „+“, speciální znaky na hexadecimální ASCII kódy.
                </li>
                <li>
                    <attrval>multipart/form-data</attrval> – znaky se nekódují. Tato hodnota se musí použít u formulářů, kde se uploadují soubory.
                </li>
                <li>
                    <attrval>text/plain</attrval> – mezery jsou převedeny na „+“, speciální znaky se nekódují.
                </li>
            </ul>
        </li>
        <li>
            <attr>method</attr> – možné hodnoty jsou <em>get</em> nebo <em>set</em>. Určuje způsob, jakým se data mají posílat na server.
        </li>
        <li>
            <attr>name</attr> – název <elmnt>&lt;form&gt;</elmnt>. Musí být v rámci dalších <elmnt>&lt;form&gt;</elmnt> na stránce unikátní a nesmí obsahovat prázdný řetězec.
        </li>
        <li>
            <attr>novalidate</attr> – boolean atribut. Je-li nastaven na <em>true</em>, nebudou se kontrolovat prvky, které nějakým způsobem vyžadují kontrolu. Může se jednat o prvek <em>number</em>, kde jsou defaultně vyžadována čísla, nějaký prvek, který má nastaven atribut <attr>required</attr> na <em>true</em> nebo třeba <em>text</em>, kde může být vyžadován určitý formát vstupu pomocí atributu <attr>pattern</attr>.
        </li>
        <li>
            <attr>target</attr> – říká, kam se má vypsat odpověď po odeslání formuláře. Může nabývat hodnot:
            <ul>
                <li>
                    <attrval>_blank</attrval> – odpověď v novém okně;
                </li>
                <li>
                    <attrval>_self</attrval> – odpověď v tom samém okně (výchozí hodnota);
                </li>
                <li>
                    <attrval>_parent</attrval> – odpověď v nadřazeném rámu;
                </li>
                <li>
                    <attrval>_top</attrval> – odpověď v celém okně prohlížeče (tedy v hierarchicky nejvyšším prvku, tudíž ne v rámu);
                </li>
                <li>
                    <attrval>jméno_rámu</attrval> – odpověď v pojmenovaném rámu na stránce.
                </li>
            </ul>
        </li>
    </ul>

</slide>
<slide title="Prvky, samé prvky">

    <p>
      Největší „sborník“ prvků je <elmnt>&lt;input&gt;</elmnt> se svým atributem <attr>type</attr> (přehledný výpis
      <a href="http://www.w3schools.com/tags/att_input_type.asp" class="external" _target="_blank">zde</a> a také <a href="forms-input.xml">zde na webu</a>).
    </p>
    <p>
      Pak zde však máme i jiné prvky, reprezentované vlastními elementy: <strong><elmnt>&lt;button&gt;</elmnt></strong>, <elmnt>&lt;select&gt;</elmnt>, <elmnt>&lt;datalist&gt;</elmnt>, <elmnt>&lt;optgroup&gt;</elmnt>, <elmnt>&lt;option&gt;</elmnt>, <strong><elmnt>&lt;textarea&gt;</elmnt></strong>, <elmnt>&lt;output&gt;</elmnt>, <elmnt>&lt;progress&gt;</elmnt>, <elmnt>&lt;meter&gt;</elmnt>.
    </p>
    <p>
        Postupně si je všechny probereme.
    </p>

</slide>
<slide title="&lt;input&gt;, &lt;button&gt; a &lt;textarea&gt;">

    <p>
      Určitě Vás hned napadl rozdíl mezi <elmnt>&lt;input type="button"&gt;</elmnt> a <elmnt>&lt;button&gt;</elmnt> na jedné straně a <elmnt>&lt;input type="text"&gt;</elmnt> a <elmnt>&lt;textarea&gt;</elmnt> na druhé. Pojďme si to trochu osvětlit:
    </p>
    <ul>
        <li>
            Hlavní výhodou <elmnt>&lt;button&gt;</elmnt> je to, že <strong>mezi jeho tagy se dají umístit další HTML elementy</strong>, což u <elmnt>&lt;input&gt;</elmnt> nejde. Tudíž <em>buttonem</em> se může stát text či obrázek, „vystajlovaný“ pomocí CSS. Později si ukážeme několik pěkných příkladů ;)
            <note>
                Jediná možnost, jak z obrázku pomocí <elmnt>&lt;input&gt;</elmnt> udělat <em>submit button</em> je <attr>type</attr>="<attrval>image</attrval>".
            </note>
        </li>
        <li>
            <elmnt>&lt;textarea&gt;</elmnt> umožňuje zadávat víceřádkový text a navíc je plocha na psaní roztažitelná uživatelem (což ani jedno <elmnt>&lt;input type="text"&gt;</elmnt> neumí).
        </li>
    </ul>

</slide>

</lecture>
