Lekcja 8.5: Listy rozwijane (<select>, <option>, <optgroup>)
Wybór z predefiniowanej listy opcji
Gdy chcemy dać użytkownikowi możliwość wyboru jednej (lub wielu) opcji z dłuższej, predefiniowanej listy, zamiast używać wielu przycisków opcji (radio) lub pól wyboru (checkbox), często wygodniej jest zastosować listę rozwijaną. W HTML tworzy się ją za pomocą znaczników <select>
i <option>
.
Znacznik <select>
Znacznik <select>
tworzy samą kontrolkę listy rozwijanej (lub pole listy, jeśli ma atrybut size
większy od 1). Działa jako kontener dla poszczególnych opcji (<option>
).
Kluczowe atrybuty <select>:
name
: Niezbędny do wysłania wybranej wartości na serwer.id
: Unikalny identyfikator, do powiązania z etykietą<label>
.multiple
: Atrybut logiczny. Jeśli jest obecny, użytkownik może wybrać wiele opcji z listy (zazwyczaj przytrzymując klawisz Ctrl lub Shift podczas klikania). Bez tego atrybutu można wybrać tylko jedną opcję.size
: Określa, ile opcji ma być widocznych jednocześnie. Jeślisize="1"
(domyślnie) lub brak atrybutu, tworzona jest lista rozwijana. Jeślisize
jest większy od 1, tworzone jest pole listy o określonej wysokości.required
: Wymaga wybrania przynajmniej jednej opcji (innej niż opcja z pustą wartością, jeśli taka istnieje).disabled
: Wyłącza całą listę rozwijaną.
Znacznik <option>
Znacznik <option>
definiuje pojedynczą opcję wewnątrz listy <select>
.
Kluczowe atrybuty <option>:
value
: Określa wartość, która zostanie wysłana na serwer, jeśli ta opcja zostanie wybrana. Jeśli atrybutvalue
zostanie pominięty, wysłana zostanie treść tekstowa zawarta między<option>
a</option>
. Zaleca się jednak jawne podawanievalue
.selected
: Atrybut logiczny. Jeśli jest obecny, ta opcja będzie domyślnie wybrana przy załadowaniu strony. W liście jednostkowego wyboru (bezmultiple
) tylko jedna opcja może mieć atrybutselected
. W liście wielokrotnego wyboru może być ich więcej.disabled
: Wyłącza możliwość wybrania tej konkretnej opcji.
Tekst widoczny dla użytkownika na liście umieszcza się pomiędzy znacznikami <option>
a </option>
.
Przykład prostej listy rozwijanej (jednostkowy wybór):
<form action="/submit" method="post">
<label for="wybor-kraju">Wybierz kraj:</label>
<select id="wybor-kraju" name="kraj">
<option value="">-- Wybierz --</option> <!-- Opcja pusta, często używana jako placeholder -->
<option value="pl">Polska</option>
<option value="de">Niemcy</option>
<option value="cz" selected>Czechy</option> <!-- Czechy wybrane domyślnie -->
<option value="sk">Słowacja</option>
</select>
<button type="submit">Wyślij</button>
</form>
Jeśli użytkownik zostawi wybrane "Czechy" i wyśle formularz, na serwer trafi para kraj=cz
.
Przykład listy z możliwością wielokrotnego wyboru:
<label for="wybor-jezykow">Wybierz języki (przytrzymaj Ctrl/Shift):</label>
<select id="wybor-jezykow" name="jezyki_programowania[]" multiple size="4">
<option value="html">HTML</option>
<option value="css" selected>CSS</option>
<option value="js" selected>JavaScript</option>
<option value="php">PHP</option>
<option value="python">Python</option>
</select>
W tym przykładzie atrybut multiple
pozwala na wybór wielu opcji, a size="4"
sprawia, że widoczne są 4 opcje naraz (tworząc pole listy). Domyślnie zaznaczone są CSS i JavaScript. Jeśli użytkownik zaznaczy dodatkowo HTML i wyśle formularz, serwer może otrzymać coś w rodzaju jezyki_programowania = ["html", "css", "js"]
.
Grupowanie opcji: <optgroup>
Gdy lista opcji jest bardzo długa, można ją podzielić na logiczne grupy za pomocą znacznika <optgroup>
. Każda grupa może mieć własny tytuł.
<optgroup>
umieszcza się wewnątrz<select>
.- Zawiera on znaczniki
<option>
należące do danej grupy. - Wymaga atrybutu
label
, który określa tytuł grupy widoczny na liście. Tytuł grupy (<optgroup>
) nie jest wybieralny. - Może mieć atrybut
disabled
, aby wyłączyć wszystkie opcje w danej grupie.
Przykład użycia <optgroup>:
<label for="wybor-auta">Wybierz samochód:</label>
<select id="wybor-auta" name="samochod">
<option value="">-- Wybierz --</option>
<optgroup label="Niemieckie">
<option value="vw">Volkswagen</option>
<option value="bmw">BMW</option>
<option value="audi">Audi</option>
</optgroup>
<optgroup label="Japońskie">
<option value="toyota">Toyota</option>
<option value="honda">Honda</option>
<option value="mazda">Mazda</option>
</optgroup>
<optgroup label="Francuskie" disabled>
<option value="renault">Renault</option>
<option value="peugeot">Peugeot</option>
</optgroup>
</select>
W tym przykładzie opcje są pogrupowane według kraju pochodzenia, a grupa "Francuskie" jest wyłączona.
Dostępność
Podobnie jak w przypadku innych pól formularza, kluczowe jest użycie znacznika <label>
powiązanego z <select>
za pomocą atrybutów for
i id
. Dzięki temu użytkownicy czytników ekranu dowiedzą się, czego dotyczy dana lista rozwijana.
Zadanie praktyczne (z rozwiązaniem)
Zadanie: Dodaj do formularza kontaktowego listę rozwijaną (<select>
) pozwalającą wybrać dział, do którego ma trafić wiadomość (np. Sprzedaż, Pomoc techniczna, Reklamacje). Dodaj opcję pustą "-- Wybierz dział --" jako pierwszą. Użyj etykiety i powiąż ją z listą.
Rozwiązanie:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Formularz Kontaktowy - Select</title>
<style>
/* Style z poprzednich lekcji */
label { display: block; margin-top: 10px; }
input[type="text"], input[type="password"], textarea, select { width: 90%; max-width: 300px; padding: 8px; margin-top: 5px; border: 1px solid #ccc; }
button { margin-top: 15px; padding: 10px 15px; }
fieldset { border: 1px dashed #aaa; padding: 15px; margin-bottom: 20px; }
legend { font-weight: bold; color: navy; padding: 0 5px; }
fieldset div { margin-bottom: 8px; }
input[type="radio"], input[type="checkbox"] { margin-right: 5px; }
fieldset > div > label { display: block; margin-top: 10px; } /* Etykiety pól tekstowych */
fieldset > div > input + label { display: inline-block; margin-top: 0; } /* Etykiety radio/checkbox */
</style>
</head>
<body>
<h1>Kontakt</h1>
<form action="/wyslij-wiadomosc" method="POST">
<fieldset>
<legend>Dane wiadomości</legend>
<div>
<label for="contact-imie">Imię:</label>
<input type="text" id="contact-imie" name="imie_uzytkownika" required>
</div>
<!-- Dodane pole select -->
<div>
<label for="contact-dzial">Dział:</label>
<select id="contact-dzial" name="dzial" required>
<option value="">-- Wybierz dział --</option>
<option value="sprzedaz">Sprzedaż</option>
<option value="pomoc">Pomoc techniczna</option>
<option value="reklamacje">Reklamacje</option>
<option value="inne">Inne</option>
</select>
</div>
<div>
<label for="contact-wiadomosc">Wiadomość:</label>
<textarea id="contact-wiadomosc" name="tresc_wiadomosci" rows="4" required></textarea>
</div>
</fieldset>
<!-- Reszta formularza (np. fieldset z preferencjami) -->
<button type="submit">Wyślij wiadomość</button>
</form>
</body>
</html>
Dodatkowe zadania do samodzielnego wykonania:
- Dodaj atrybut
selected
do opcji "Pomoc techniczna", aby była wybrana domyślnie. - Stwórz listę rozwijaną z możliwością wielokrotnego wyboru (
multiple
) i ustaw jej widoczny rozmiar (size
) na 5. - Użyj znacznika
<optgroup>
, aby pogrupować opcje w liście wyboru działu (np. "Obsługa klienta" -> Sprzedaż, Pomoc; "Sprawy formalne" -> Reklamacje).
Najczęściej zadawane pytania
Jak stworzyć listę rozwijaną w HTML?
Użyj znacznika <select> jako kontenera. Wewnątrz umieść poszczególne opcje za pomocą znaczników <option>...</option>. Pamiętaj o atrybutach name dla <select> i value dla <option>.
Jak ustawić domyślnie wybraną opcję w liście?
Dodaj atrybut logiczny selected do znacznika <option>, który ma być domyślnie wybrany.
Jak pozwolić na wybór wielu opcji z listy?
Dodaj atrybut logiczny multiple do znacznika <select>. Użytkownicy będą mogli wybierać wiele opcji, zazwyczaj przytrzymując klawisz Ctrl lub Shift.
Do czego służy <optgroup>?
Znacznik <optgroup> pozwala grupować powiązane opcje (<option>) wewnątrz listy <select>. Wymaga atrybutu label, który określa tytuł grupy widoczny na liście.
Co jest wysyłane na serwer z listy <select>?
Wysyłana jest para: nazwa (z atrybutu name znacznika <select>) = wartość (z atrybutu value wybranej opcji <option>). Jeśli wybrano wiele opcji (przy multiple), serwer otrzyma wiele wartości pod tą samą nazwą.