Formularze w dobrej formie cz. I – XHTML


Nie będzie tu przełomów, od razu ostrzegam. Ten wpis to podsumowanie i przypomnienie, które zrobiłem nie tylko dla Was, ale i dla siebie. Choć w tej chwili to HTML 5 jest na fali, to nie raz jeszcze przyjdzie nam pracować z witrynami i aplikacjami w XHTML. A że ciężko o choćby nieco bardziej rozbudowaną aplikację internetową bez formularza, to przechodzimy do realizacji formularzy w tym właśnie standardzie.

Ten wpis jest częścią pierwszą cyklu Formularze w dobrej formie, który rozpocząłem (!) od części trzeciej – na temat jQuery

Co wiemy o XHTMLu? Kilka rzeczy:

  • ma straszny doctype np. taki:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  • dokument musi mieć strukturę zgodną z XML
    • musi istnieć tylko jeden element najwyższego poziomu,
    • element potomny musi zostać zamknięty przed zamknięciem rodzica,
    • wszystkie elementy muszą zostać zamknięte, nawet puste
  • znaczniki i nazwy atrybutów muszą być pisane małą literą
  • wartości atrybutów muszą być otoczone cudzysłowami
  • każdy atrybut musi mieć wartość
  • trzymamy się z daleka od znaczników formatujących – z przymusu w specyfikacji Strict, a z dobrej woli wszędzie indziej

Niektórzy wskazują też na konieczność wyciągnięcia CSSów i skryptów do osobnych plików, ale to raczej kwestia estetyki i łatwości utrzymania, niż standardu XHTML – jeśli się uprzeć, to mamy przecież w XML CDATA, gdzie możemy takie rzeczy trzymać.

Z pośród wskazanych zasad większość jest, moim zdaniem, w porządku – pomaga trzymać porządek w kodzie i było doskonałym lekarstwem na schorzenie zwane spaghetti HTML. Ale przy jednej z nich robię się nerwowy – każdy atrybut musi mieć wartość. Samo w sobie nie jest to problemem. Gorzej, kiedy dotrzemy do atrybutów logicznych. Ktoś uznał, że najwłaściwszym sposobem ich realizacji będzie np. checked=”checked”. Drażni mnie to okrutnie. Tym bardziej, że w takich przypadkach nie ma żadnej innej wartości. Czy nie można było zrealizować tego choćby w oparciu o true i false? OK, wystarczy wylewania jadu, więcej znajdziecie w telewizji. Tutaj mówimy trudno i zabieramy się do rzeczy.

Form

Formularz tworzymy elementem form. Według specyfikacji musimy nadać mu przynajmniej jeden atrybut – action, który wskaże, do jakiego miejsca mają zostać wysłane dane z tego formularza. Ominięcie go jest niewłaściwe, a poskutkuje przejściem z powrotem na bieżącą stronę. Inne atrybuty formularza to:

  • methodpost lub get,
  • enctype – metoda kodowania danych przed wysłaniem metodą post – szczególnie istotne przy przesyłaniu plików – wtedy ten atrybut powinien być ustawiony na multipart/form-data

Istnieją jeszcze accept i accept-charset – do zabawy, jeśli mamy jakieś ograniczenia po stronie serwera. Oczywiście możemy też wykorzystać atrybuty id oraz class, mniej chętnie style, a także zapomniane przez parser i ludzi dir, lang, title, xml:lang

Pojemnik

Mamy otwarty (i najlepiej od razu zamknięty, żeby później tego zamknięcia nie przegapić) element formularza, pora nawrzucać do niego pól. Nie tak prędko! Pomiędzy formularzem a polami musi znaleźć się pojemnik. Możemy tu użyć np. div, p albo fieldset. Fieldset w domyślnym stylowaniu stworzy wokół pól ramkę, a jeśli wstawimy do niego element legend, to ta legenda stanie się opisem na górnej krawędzi ramki. Jest to ciekawe rozwiązanie semantyczne, dobrze sprawdza się też w „roboczych” formularzach, gdzie style nie są tak istotne.

Pola formularza

Teraz, wewnątrz kontenera możemy wreszcie wstawić pola formularza – będą to głównie elementy typu input oraz select i textarea. Zacznijmy od końca.

<textarea rows="2" cols="10"></textarea>

Element textarea tworzy ramkę, w której użytkownik może wpisać większą ilość tekstu np. komentarz, uwagi do zamówienia etc. Musimy zdefiniować jej rozmiar podając liczbę kolumn i wierszy tekstu w atrybutach col i rows. Definiuje to tylko rozmiar ramki, ale nie ogranicza długości tekstu możliwego do wprowadzenia. Z dodatkowych atrybutów możemy wykorzystać dwa logiczne: readonly, disabled, a także przydałoby się nadać elementowi nazwę w atrybucie name, która będzie kluczem w wysłanej przez ten element parze klucz => wartość.

<select>
	<option>Opcja</option>
</select>

Select stworzy nam listę wyboru. Będzie składała się z elementów option, które możemy dodatkowo pogrupować w pojemnikach optgroup. Z ciekawych atrybutów, które możemy nadać elementowi select te dwa są unikatowe – czy to w nazwie, czy znaczeniu:

  • multiple – lista wielokrotnego wyboru – atrybut logiczny,
  • size – liczba widocznych elementów. Jeśli pozostawimy domyślną wartość 1, będzie to select jaki znamy i lubimy. Każda większa wartość zmieni listę w prostokąt z suwakiem. Dla wariantu wielokrotnego wyboru, domyślna wielkość to 4.

Poszczególne opcje wstawia się do listy wyboru wspomnianymi elementami option. Zawartość takiego elementu jest etykietą na liście, zaś wartość tej opcji możemy umieścić w atrybucie value. Jeśli atrybut value się nie pojawi, to wartość będzie równa zawartości elementu – śmiało wystarczy, jeśli w liście rozwijanej mają się pojawić same liczby (i mamy jako taką pewność, że się to niedługo nie zmieni).

Aby stworzyć grupę opcji, zamykamy je w elemencie optgroup z atrybutem label – będzie to pogrubiony element na liście, niemożliwy do wybrania (nie jest opcją, a tylko grupą), zaś jego dzieci będą odsunięte od krawędzi.

<input />

Teraz pora na element, a raczej całą rodzinę elementów input. Mają szerokie zastosowanie, które możemy rozróżnić atrybutem type. Przyjmuje on następujące wartości:

  • text – wartość domyślna, małe pole tekstowe
  • password – pole tekstowe, w którym zamiast liter pojawią się „gwiazdki”
  • file – umożliwia przesłanie pliku
  • hidden – element jest ukryty, lecz jeśli posiada name, to zostanie wysłany razem z innymi danymi (może służyć np. do zapobiegania fałszerswtu formularza przez inną aplikację)
  • button – tworzy przycisk
  • radio – element listy jednokrotnego wyboru
  • checkbox – tworzy element listy wielokrotnego wyboru
  • reset – przywraca wszystkie dane w formularzu do ustawień początkowych
  • submit – wysyła formularz
  • image – wstawia obrazek, którego kliknięcie wywołuje wysłanie formularza (fajne, jeśli chcemy mieć własny przycisk wysyłania, np. kopertę lub lupę)

Większość z tych pól powinna zostać wyposażona w atrybut name, podobnie jak select i textarea. Aby przyciski radio funkcjonowały jak należy, czyli pozwalały na wybór jednego z grupy, należy każdemu w tej grupie nadać taki sam name. Z kolei checkboxy o takiej samej nazwie zakończonej znakami [] stworzą w przesłanych danych tablicę, której elementy to wartości zaznaczonych pozycji.

Właśnie – wartość. Atrybut value dostępny dla typów text, checkbox, radio, hidden i password ustawia ich wartość. Z kolei dla button i submit będzie to nazwa widoczna na przycisku (pamiętacie czasy, gdy domyślną wartością dla submit bodajże w IE było „wyślij kwerendę”? 😉 )

Zależnie od typu, pola mogą lub muszą zawierać dodatkowe atrybuty

  • image
    • src – url do obrazka – wymagany
    • alt – tekst alternatywny – wymagany
  • radio, checkbox
    • checked – logiczny: czy pole jest zaznaczone
  • file
    • accept – typ MIME akceptowanych plików
  • text, password
    • size – długość pola
    • maxlength – maksymalna liczba znaków, jaką można wpisać do danego pola
<label>Etykieta</label>

Label nie jest co prawda elementem formularza, ale dzięki etykietom możemy poprawić interfejs – kliknięcie etykiety uaktywnia odpowiednią kontrolkę. Pełny kod razem z kontekstem:

<label for="idElementu">Input text</label>
<input type="text" id="idElementu" value="wartość początkowa"/>

Klawisz skrótu

Elementy formularza mogą również posiadać atrybut accesskey, który określa klawisz skrótu do danego pola. To, jak wygląda cały skrót klawiszowy, zależy od przeglądarki: http://en.wikipedia.org/wiki/Access_key

Wszystko to, co tu opisałem, możecie podejrzeć w działaniu na stronie http://wkh24.pl/showcase/forms/xhtml.html – proponuję zajrzeć do źródła, jeśli ktoś gubi się w dostępnych opcjach.

To chyba wszystko, co wypada wiedzieć o formularzach w XHTML. Jeśli uważacie, że coś jeszcze powinno się tu znaleźć, lub – a nawet tym bardziej – jeśli znajdziecie jakieś błędy, dajcie znać w komentarzach, sprawdzimy, poprawimy, ulepszymy. A już niedługo kolejne części cyklu o formularzach. Na tapecie są elementy formularzy w HTML 5, walidacja a na koniec rodzynek dla tych, którzy mają już nieco dość frontendu i chcieliby poczytać o PHP – formularze w Zend Framework.