WWW-lomakkeet

Näissä tehtävissä opetellaan WWW-lomakkeisiin liittyviä asioita. Esimerkkejä lomake-elementtien käytöstä löydät lomakeluennolta.

Oppimistavoitteet

Tämän ohjauksen jälkeen sinun pitäisi osata:

1. Sähköpostilomake

Tehdään viestin lähettämiseen tarkoitettu lomake. Ulkoasu tehdään vasta lomakkeen rakenteen jälkeen, joten aluksi ei kannata välittää siitä miltä lomake näyttää.

Lomakkeen malli ilman tyylejä

1.1 Pohja

  1. Luo hakemistoon W:\www\ alihakemisto ohjaus6.
  2. Tallenna lomake.css ohjaus6-hakemistoon.
  3. Aloita uusi HTML-dokumentti, tallenna se nimellä index.html samaan hakemistoon ja lisää viite tyylitiedostoon:
    <link rel="stylesheet" href="lomake.css" />
  4. Muokkaa title- ja h1-elementit sopiviksi.
  5. Lisää sivulle lomake. Jätä action-attribuutti toistaiseksi tyhjäksi:

    <form action="" method="post">
    
    </form>

1.2 Tekstikenttä ja label

  1. Lisää lomakkeelle ensin label-elementti otsikkotekstillä Aihe ja sen jälkeen tekstikenttä. Laita molemmat saman p-elementin sisään ja anna sille luokka kentta, jota tarvitaan myöhemmin asettelussa:

    <p class="kentta">
      <label for="aihe">Aihe</label>
      <input type="text" name="aihe" id="aihe" />
    </p>
  2. name-attribuutti kertoo lomakkeen käsittelijälle kentän nimen. Jokaisella kentällä on oltava järkevä name, muuten kentän sisältöä ei lähetetä lainkaan.

  3. Otsikko ja kenttä liitetään toisiinsa näin:

    • input-elementin id-attribuutin arvoksi aihe. Arvon on oltava yksilöllinen koko dokumentissa: millään muulla elementillä ei saa olla samaa.
    • label-elementin for-attribuutin arvoksi sama aihe.
  4. Kokeile selaimella. Jos kytkentä toimii, voit napsauttaa otsikkotekstiä ja kenttä aktivoituu. Tämä on nopein tapa tarkistaa, että for ja id täsmäävät.

  5. Lisää lähetyspainike:

    <p>
      <input type="submit" value="Lähetä viesti" name="laheta" />
    </p>
  6. Lisää lomakkeelle käsittelijä:

    <form action="https://appro.mit.jyu.fi/cgi-bin/view.cgi" method="post">
    • action kertoo, mikä ohjelma käsittelee lähetetyt tiedot. view.cgi vain näyttää ne, joten se sopii harjoitteluun.
    • method kertoo, miten tiedot lähetetään. Arvo on tässä post.
  7. Kokeile lomaketta. Mitä tapahtuu, kun napsautat painiketta? Syötä kenttään tekstiä ja kokeile uudestaan.

    Kokeile

    Muuta aihe-kentän name-attribuutin arvoa ja lähetä lomake uudelleen. Mikä muuttuu view.cgi-sivulla? Poista sitten name-attribuutti kokonaan ja katso mitä tapahtuu.

1.3 Kentän tyyppi

Kaikki tekstikentät eivät ole samanlaisia. type-attribuutilla kerrotaan selaimelle, millaista tietoa kenttään odotetaan.

  1. Lisää lomakkeelle sähköpostikenttä lähettäjää varten:

    <p class="kentta">
      <label for="sahkoposti">Sähköpostiosoitteesi</label>
      <input type="email" name="sahkoposti" id="sahkoposti"
             autocomplete="email" />
    </p>
  2. Kokeile lähettää lomake osoitteella, jossa ei ole ät-merkkiä. Selain estää lähetyksen ja näyttää virheilmoituksen itse — tämä tulee type="email"-määrityksestä ilman yhtään riviä koodia.

  3. Kokeile samaa kenttää puhelimella tai laitenäkymässä. Oikea type-arvo vaihtaa myös näppäimistön: sähköpostikentässä näkyy ät-merkki, numerokentässä numeronäppäimistö.

Tavallisimmat tekstikentän tyypit.
ArvoKäyttö
textTavallinen teksti. Oletus
emailSähköpostiosoite
telPuhelinnumero. Selain ei tarkista muotoa, koska numeroiden muoto vaihtelee maittain
urlVerkko-osoite
numberLuku. Rajat min- ja max-attribuuteilla
datePäivämäärä. Selain tarjoaa kalenterivalitsimen
passwordSalasana. Merkit eivät näy. Ei salaa mitään, vaan piilottaa ne vain katselijalta
autocomplete säästää käyttäjän vaivaa

Nimetty autocomplete-arvo kertoo selaimelle, mitä kenttään kuuluu, jolloin se osaa tarjota käyttäjän omia tietoja. Tavallisimmat arvot ovat name, email, tel, street-address, postal-code ja organization. Tämä on erityisen tärkeää käyttäjälle, jolla on motorisia rajoitteita. Katso lomakeluennon luku 5.4.

1.4 Valintalistat

  1. Lisää prioriteetin valinta:

    <p class="kentta">
      <label for="prioriteetti">Prioriteetti</label>
      <select name="prioriteetti" id="prioriteetti">
        <option>Korkea</option>
        <option selected="selected">Normaali</option>
        <option>Alhainen</option>
      </select>
    </p>

    label yhdistetään select-elementtiin täsmälleen samalla tavalla kuin tekstikenttään. Vaihtoehto Normaali on valittuna oletuksena, ja XHTML-yhteensopivuuden vuoksi attribuutille annetaan arvo: selected="selected".

  2. Lisää vastaanottajan valinta monimutkaisemmalla listalla:

    <p class="kentta">
      <label for="vastaanottaja">Vastaanottaja</label>
      <select name="vastaanottaja" id="vastaanottaja" size="7" multiple="multiple">
        <optgroup label="Opettajat">
          <option value="ville.virtanen@example.invalid">Ville Virtanen</option>
          <option value="sanna.salminen@example.invalid">Sanna Salminen</option>
          <option value="jussi.jarvinen@example.invalid">Jussi Järvinen</option>
        </optgroup>
        <optgroup label="Tuntiopettajat">
          <option value="aino.aalto@example.invalid">Aino Aalto</option>
          <option value="eero.eskola@example.invalid">Eero Eskola</option>
        </optgroup>
      </select>
    </p>
    • optgroup ryhmittelee vaihtoehtoja.
    • multiple sallii useamman valinnan. Kokeile pitämällä Ctrl- tai Shift-näppäintä pohjassa.
    • size määrää, montako riviä listasta näkyy kerralla. Kokeile eri arvoja.
    • value on se arvo, joka lähetetään. Jos sitä ei anneta, lähetetään option-elementin sisältö.
    multiple on hankala käyttää

    Monivalintalista on tässä hyvä harjoitus, mutta oikeassa lomakkeessa se on huono valinta. Käyttäjä ei arvaa, että pitää painaa Ctrl-näppäintä, ja kosketuslaitteella valitseminen on lähes mahdotonta. Käytä oikeissa lomakkeissa mieluummin valintaruuturyhmää: se on itsestään selvä, toimii kaikkialla ja näyttää kaikki vaihtoehdot kerralla.

  3. Kokeile lomakkeen toimintaa. Valitse useampi vastaanottaja ja katso, miten ne näkyvät view.cgi-sivulla.

1.5 Valintanapit ja valintaruudut

Valintanappiryhmä tarvitsee aina fieldset-elementin

Yksittäisellä valintanapilla on oma label-elementtinsä, mutta ryhmällä kokonaisuutena ei ole mitään otsikkoa, ellei sitä käärittä fieldset-elementtiin ja anneta sille legend-otsikkoa. Ruudunlukijan käyttäjä kuulee muuten pelkät vaihtoehdot tietämättä, mitä on valitsemassa. Tehdään se siis heti.

  1. Lisää formaatin valinta valintanapeilla:

    <fieldset>
      <legend>Formaatti</legend>
      <p>
        <label>
          <input type="radio" name="formaatti" value="teksti" checked="checked" />
          Teksti
        </label>
      </p>
      <p>
        <label><input type="radio" name="formaatti" value="html" /> HTML</label>
      </p>
      <p>
        <label><input type="radio" name="formaatti" value="xml" /> XML</label>
      </p>
    </fieldset>
    • Tässä label-elementtiä käytetään toisella tavalla: kenttä on label-elementin sisällä, jolloin for- ja id-attribuutteja ei tarvita.
    • Kaikilla saman ryhmän napeilla on sama name. Juuri se pitää ne samassa ryhmässä, jolloin vain yksi voi kerrallaan olla valittuna.
    • checked="checked" asettaa oletusvalinnan.
    Kumpaa label-tapaa käyttää?

    Kääriminen on kätevä valintanapeille ja -ruuduille. Muissa kentissä for ja id on varmempi: se toimii luotettavammin apuvälineiden kanssa ja sallii otsikon sijoittamisen mihin tahansa kohtaan sivua.

  2. Lisää lisäasetukset valintaruutuina omaan ryhmäänsä:

    <fieldset>
      <legend>Lisäasetukset</legend>
      <p>
        <label>
          <input type="checkbox" name="extra" value="Tekstiviesti" />
          Lähetä myös tekstiviesti
        </label>
      </p>
      <p>
        <label>
          <input type="checkbox" name="extra" value="Kirje" />
          Lähetä myös tavallinen kirje
        </label>
      </p>
    </fieldset>
    name-attribuutilla on merkitystä myös valintaruuduissa

    Toisin kuin joskus väitetään, valintaruutujen nimillä on väliä. Ero on siinä, mitä käsittelijä saa:

    • Sama nimi kaikilla: valitut arvot lähetetään yhtenä listana saman nimen alla. Tämä sopii, kun kyseessä on yksi kysymys, johon voi valita monta vastausta — kuten tässä.
    • Eri nimet: jokainen ruutu on oma kenttänsä. Tämä sopii, kun kyseessä on useita erillisiä kyllä/ei-kysymyksiä.

    Toisin kuin valintanapeissa, sama nimi ei estä valitsemasta useampaa kerralla. Kokeile: valitse molemmat ruudut ja katso, miltä lähetys näyttää view.cgi-sivulla.

1.6 Tekstialue

  1. Lisää varsinainen viestikenttä:

    <p class="kentta">
      <label for="viesti">Viesti</label>
      <textarea id="viesti" name="viesti" rows="10" cols="50"></textarea>
    </p>
    • rows määrää rivien ja cols sarakkeiden määrän.
    • textarea-elementillä on aina erillinen lopetustagi, vaikka se olisi tyhjä. Se ei ole void-elementti.

1.7 Ryhmittely

  1. Ryhmittele lomakkeen loputkin osat fieldset- ja legend-elementeillä. Tee Otsikkotiedot ja Viestiosa omiksi ryhmikseen. Formaatti- ja Lisäasetukset-ryhmät tulevat Viestiosan sisään, eli ryhmiä voi olla sisäkkäin.
  2. Kaikki ryhmittelyt tulevat form-elementin sisään.
  3. Validoi HTML-tiedostosi validaattorilla ja korjaa virheet.

2. Selaimen sisäänrakennettu tarkistus

Selain osaa tarkistaa kenttien sisällön ennen lähetystä ilman yhtään riviä ohjelmakoodia. Se ei korvaa palvelimen puolella tehtävää tarkistusta, mutta auttaa käyttäjää heti.

  1. Merkitse pakolliset kentät. Lisää required-attribuutti aihe-, sähköposti- ja viestikenttiin:

    <input type="text" name="aihe" id="aihe" required="required" />
  2. Kokeile lähettää tyhjä lomake. Selain estää lähetyksen, siirtää kohdistuksen ensimmäiseen puutteelliseen kenttään ja näyttää oman ilmoituksensa.
  3. Lisää aihe-kentälle pituusrajat ja vihjeteksti:

    <input type="text" name="aihe" id="aihe"
           required="required" minlength="3" maxlength="60"
           placeholder="Esimerkiksi: Kysymys harjoitustyöstä" />
    placeholder ei korvaa otsikkoa

    Vihjeteksti katoaa heti, kun käyttäjä alkaa kirjoittaa, eikä hän enää näe mitä kenttään piti laittaa. Sen kontrasti on myös usein liian heikko. Käytä sitä vain esimerkkinä, älä koskaan otsikon korvikkeena. Jokaisella kentällä on oltava label.

  4. Lisää lomakkeelle numerokenttä ja päivämääräkenttä omine rajoineen:

    <p class="kentta">
      <label for="kiireellisyys">Kiireellisyys (1–5)</label>
      <input type="number" name="kiireellisyys" id="kiireellisyys"
             min="1" max="5" value="3" />
    </p>
    
    <p class="kentta">
      <label for="takaraja">Vastausta viimeistään</label>
      <input type="date" name="takaraja" id="takaraja" />
    </p>
  5. Kokeile syöttää numerokenttään arvo 9 ja lähettää lomake.
  6. Kokeile vielä pattern-attribuuttia, jolla kentän sisältöä voi rajata säännöllisellä lausekkeella. Vaadi, että sähköpostiosoite on yliopiston osoite:

    <input type="email" name="sahkoposti" id="sahkoposti"
           required="required"
           pattern=".+@([a-z]+[.])?jyu[.]fi"
           autocomplete="email" />

    Huomaa, että piste on säännöllisessä lausekkeessa erikoismerkki, joka vastaa mitä tahansa merkkiä. Siksi oikea piste on suojattu hakasulkeilla muodossa [.].

Kerro vaatimus myös näkyvästi

pattern-attribuutti ei kerro käyttäjälle mitään siitä, millainen arvon pitäisi olla. Kirjoita vaatimus näkyväksi tekstiksi kentän yhteyteen, älä pelkästään title-attribuuttiin: se ei näy kosketuslaitteilla eikä näppäimistökäytössä.

3. Lomakkeen muotoilu

Lomakkeen ulkoasumalli

Lomake-elementtien ulkoasua voi muokata vain rajallisesti: selaimet piirtävät kentät pitkälti omalla tavallaan. Kenttien sijaintia voi kuitenkin säätää vapaasti, ja juuri se tekee lomakkeesta siistin.

Muokkaa tyylitiedostoa selaimen tyylieditorissa (Shift+F7) ja tallenna muutokset lopuksi lomake.css-tiedostoon.

3.1 Värit ja kirjasimet

  1. Anna fieldset-elementille taustasta poikkeava väri. Määritä aina myös tekstin väri, ja tarkista kontrasti: vähintään 4,5:1.
  2. Anna sisemmälle fieldset-lohkolle eri taustaväri asiayhteyden mukaan määräytyvällä valitsimella fieldset fieldset.
  3. Vaihda lomake-elementtien kirjasin tasalevyiseksi:

    input, select, textarea, button {
      font-family: "Courier New", monospace;
    }

    Huomaa, että luettelossa on select eikä option: yksittäisen vaihtoehdon kirjasinta ei voi luotettavasti vaihtaa, mutta koko valintalistan voi.

  4. Kentät eivät peri kirjasinta body-elementiltä itsestään, vaan selain antaa niille oman oletuksensa. Jos haluat kenttien käyttävän sivun kirjasinta, se on sanottava erikseen:

    input, select, textarea, button {
      font: inherit;
    }

3.2 Asettelu gridillä

Tasataan otsikot ja kentät kahteen sarakkeeseen niin, että kentät alkavat samalta kohdalta. Tämä on juuri sellainen kaksiulotteinen rakenne, johon grid on tehty.

  1. Tee jokaisesta kentta-luokan lohkosta kaksisarakkeinen ruudukko:

    .kentta {
      display: grid;
      grid-template-columns: 12em 1fr;
      gap: 0.5em;
      align-items: start;
      margin: 0.5em 0;
    }

    Ensimmäinen sarake on kiinteä 12 em ja toinen vie loput tilasta. gap tekee välin sarakkeiden väliin, ja align-items: start tasaa otsikon kentän yläreunaan — muuten otsikko venyisi korkean tekstialueen mittaiseksi.

  2. Kokeile selaimella. Kaikki kentät alkavat nyt samalta kohdalta ilman liu'utusta, leveysprosentteja tai clear-määrityksiä.

    Vertaa

    Sama asettelu tehtiin ennen liu'uttamalla: label-elementille annettiin display: block, width: 30%, float: left ja clear: left, ja tekstialueelle vielä erikseen clear: both ja display: block. Laske, montako riviä siihen tarvittiin ja montako nyt.

  3. Tekstialue on korkea, joten sen otsikko kannattaa siirtää kentän yläpuolelle. Anna sille oma sääntönsä, jossa ruudukko on yksisarakkeinen:

    .kentta.pitka {
      grid-template-columns: 1fr;
    }

    ja lisää HTML-koodissa viestikentän p-elementille toinen luokka: class="kentta pitka". Valitsin .kentta.pitka osuu elementteihin, joilla on molemmat luokat.

  4. Varmista, ettei tekstialue vuoda ulos ruudustaan:

    textarea {
      width: 100%;
      box-sizing: border-box;
    }
  5. Lisää lopuksi kapean näytön sääntö, jossa ruudukko puretaan yhteen sarakkeeseen:

    @media (max-width: 30em) {
      .kentta {
        grid-template-columns: 1fr;
      }
    }
  6. Validoi tyylitiedostosi CSS-validaattorilla.

4. Lomakkeen testaaminen

Lomake on sivuston osa, jota käytetään eniten näppäimistöllä, joten se on myös testattava näppäimistöllä.

  1. Liiku sarkaimella koko lomakkeen läpi. Tarkista neljä asiaa:

    • Näetkö koko ajan, missä kentässä olet?
    • Eteneekö järjestys ylhäältä alas samassa järjestyksessä kuin kentät näkyvät?
    • Pääsetkö jokaiseen kenttään ja lähetyspainikkeeseen?
    • Toimivatko valintanapit nuolinäppäimillä ja valintaruudut välilyönnillä?
    Älä yritä korjata järjestystä tabindex-attribuutilla

    Vanhoissa ohjeissa neuvotaan numeroimaan kentät tabindex-attribuutilla. Älä tee niin. Positiivinen tabindex nostaa elementin koko sivun sarkainjärjestyksen kärkeen, jolloin lomake tulee ennen sivun navigointia, ja numerointi menee sekaisin heti kun lomakkeeseen lisätään kenttä.

    Oikea järjestys syntyy itsestään, kun kentät ovat HTML-tiedostossa siinä järjestyksessä kuin ne on tarkoitettu täytettäviksi. Jos järjestys on väärä, korjaa HTML-koodi älä tabindex-attribuuttia.

  2. Varmista, että kohdistus näkyy. Jos olet poistanut sen jostain, palauta se:

    input:focus, select:focus, textarea:focus, button:focus {
      outline: 3px solid #b34700;
      outline-offset: 2px;
    }
  3. Napsauta jokaista otsikkotekstiä. Aktivoituuko oikea kenttä? Jos ei, for ja id eivät täsmää.
  4. Kokeile lomaketta kapealla näytöllä laitenäkymässä.
  5. Aja sivulle WAVE-tarkistus ja korjaa löytyneet puutteet.

5. Haku omalle sivulle

Googlen avulla on helppoa lisätä haku omalle sivulle. Google ei kovin avoimesti mainosta, että haun voi kohdistaa vain tiettyyn osoitteeseen, mutta tapa toimii edelleen.

  1. Lisää sivullesi uusi lomake:

    <form action="https://www.google.com/search" method="get">
      <div>
        <label for="hakusanat">Hakusanat</label>
        <input type="search" size="20" id="hakusanat" name="q" value="" />
        <input type="submit" value="Hae" />
      </div>
    </form>
    • action viittaa Googlen hakuohjelmaan.
    • Kentän name="q" viittaa hakusanoihin, jotka välitetään hakuohjelmalle.
    • method="get", koska haku ei muuta mitään ja hakutuloksen osoitteen pitää olla jaettavissa. Katso lomakeluennon luku 14.
  2. Kokeile, miten haku toimii.
  3. Rajoitetaan haku vain omaan osoitteeseen. Lisää lomakkeen sisään piilokenttä:

    <input type="hidden" name="as_q"
           value="site:users.jyu.fi/~omatunnuksesi/www/" />
    • hidden-tyyppistä kenttää ei näytetä sivulla.
    • as_q lisää muiden hakusanojen lisäksi uuden hakutermin.
    • site:-määreellä haku rajataan tiettyyn sivustoon. Osoitteen on tultava heti kaksoispisteen jälkeen ilman välilyöntiä.
  4. Kokeile hakua. Luultavasti Google ei löydä mitään, koska se ei ole ehtinyt indeksoida harjoitussivujasi: niille ei ole linkkejä mistään, ja hakuroboteilla kestää aikansa.

    Voit todeta toiminnan vaihtamalla haun kohteeksi väliaikaisesti site:appro.mit.jyu.fi/itkp1011/.

  5. Validoi lopuksi HTML- ja CSS-tiedostot ja korjaa virheet.
Piilokenttä ei ole salainen

type="hidden" tarkoittaa vain, ettei kenttää piirretä näkyviin. Sen arvo näkyy sivun lähdekoodissa ja lähtee lomakkeen mukana sellaisenaan, ja käyttäjä voi muuttaa sitä kehittäjätyökaluilla. Älä koskaan laita piilokenttään mitään, mitä käyttäjä ei saisi nähdä tai muuttaa.

6. Lisätehtäviä

  1. Lisää lomakkeelle reset-tyyppinen painike ja mieti, onko siitä oikeasti hyötyä. Mitä tapahtuu, jos käyttäjä osuu siihen vahingossa täytettyään pitkän lomakkeen?
  2. Kokeile datalist-elementtiä, jolla tekstikenttään saa ehdotuksia rajoittamatta vastausta niihin:

    <input type="text" name="aihe" id="aihe" list="aiheet" />
    <datalist id="aiheet">
      <option value="Kysymys harjoitustyöstä"></option>
      <option value="Kysymys arvostelusta"></option>
    </datalist>
  3. Muuta vastaanottajan monivalintalista valintaruuturyhmäksi fieldset-elementteineen. Kumpi on mielestäsi helpompi käyttää?
  4. Kokeile, miltä lomake kuulostaa ruudunlukijalla. Windowsissa Lukija käynnistyy näppäimillä Ctrl+Win+Enter. Kuuletko jokaisen kentän otsikon? Kerrotaanko sinulle, että kenttä on pakollinen?

Käyttäjien kommentit

Kommentoi Lisää kommentti