Jak w JavaScript uzależnić wartości dwóch pól select od siebie?
Treść dodana: 10 listopada 2017. Ostatnia modyfikacja: 10 listopada 2017.
Dość częstym problemem spotykanym w trakcie generowania kodu HTML są zależne od siebie różne wartości pól `select` lub `checkbox`. Kombinacji może być kilka:
- ta sama wartość w identycznych polach, w kilku miejscach na stronie
- zmiana jednego pola `select` spowoduje wybranie innej wartości w kolejnym polu
- zmiana pola `select` spowoduje wygenerowanie nowych wartości w drugim polu
Dla ułatwienia posłużę się popularną biblioteką jQuery w najnowszej wersji (obecnie v3). Przyda się również znajomość delegacji zdarzeń.
Wariant 1
Wariant ten zakłada sytuację w której na stronie jest kilka identycznych pól `select` i zmiana któregokolwiek z nich spowoduje zmiany w pozostałych polach. Przykładowy kod HTML może wyglądać następująco:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Przykład - wariant 1</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(function() {
// kod w tym miejscu zostanie wykonany po załadowaniu drzewa DOM
});
</script>
</head>
<body>
<main>
<select name="v1" class="wariant1">
<option value="1">Opcja 1</option>
<option value="2">Opcja 2</option>
<option value="3">Opcja 3</option>
</select>
<select name="v2" class="wariant1">
<option value="1">Opcja 1</option>
<option value="2">Opcja 2</option>
<option value="3">Opcja 3</option>
</select>
</main>
</body>
</html>
Najłatwiej w takiej sytuacji będzie nadać obu polom taką samą klasę – w naszym przypadku `.wariant1`. Następnie przypinamy do wszystkich pól reakcję na zdarzenie `change`:
$(function() {
var select = $('select.wariant1');
select.on('change', function(event) {
event.preventDefault();
select.prop('selectedIndex', $(this).prop('selectedIndex'));
});
});
Właściwość `selectedIndex` zawiera numeryczną wartość wybranego indeksu (pola `option`). Pobieramy ją z danego pola `select` i ustawiamy identyczną pozostałym. Jest to najprostszy przykład użycia.
Wariant 2
Drugi wariant zakłada sytuację, w której wybór wartości w pierwszym polu `select` spowoduje wybranej innej wartości w polu drugim. Przykładowy HTML:
<main>
<select name="v1" class="wariant2">
<option value="1">Opcja 1</option>
<option value="2">Opcja 2</option>
<option value="3">Opcja 3</option>
</select>
<select name="v2" class="wariant2">
<option data-bind="1" value="1">Opcja 1</option>
<option data-bind="2" value="2">Opcja 2</option>
<option data-bind="0" value="3">Opcja 3</option>
</select>
</main>
Oprócz tego że nadana została inna klasa `wariant2`, drugi `select` zawiera atrybut `data-bind` definiujący wartość powiązaną z pierwszym polem. Innymi słowy, wybrana wartość z pierwszego selecta spowoduje wybranie wartości odpowiadającej atrybutowi `data-bind` w selekcie numer dwa. Wartość `selectedIndex` zaczyna się od 0.
$(function() {
var select1 = $('select[name="v1"].wariant2');
var select2 = $('select[name="v2"].wariant2');
select1.on('change', function(event) {
event.preventDefault();
select2.children('option[data-bind='+ $(this).prop('selectedIndex') +']').prop('selected', true);
});
});
Przy zmianie wartości `selectedIndex` pierwszego selekta, wybieramy pole `option` posiadające odpowiadającą mu wartość atrybutu `data-bind` z selekta drugiego i ustawiamy jako wybrane.
Wariant 3
Wariant trzeci jest najtrudniejszy pod względem kodu. Zakłada sytuację w której posiadamy tylko jeden `select` oraz po stronie JS tablicę wartości, która utworzy dynamicznie drugi `select`.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Przykład - wariant 3</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
var select2Data = {
1: [
{value: '1_1', text: 'Wartość 1_1'},
{value: '1_2', text: 'Wartość 1_2'},
{value: '1_3', text: 'Wartość 1_3'}
],
2: [
{value: '2_1', text: 'Wartość 2_1'},
{value: '2_2', text: 'Wartość 2_2'},
{value: '2_3', text: 'Wartość 2_3'}
],
3: [
{value: '3_1', text: 'Wartość 3_1'},
{value: '3_2', text: 'Wartość 3_2'},
{value: '3_3', text: 'Wartość 3_3'}
]
}
$(function() {
});
</script>
</head>
<body>
<main>
<select name="v1" class="wariant3">
<option value="1">Opcja 1</option>
<option value="2">Opcja 2</option>
<option value="3">Opcja 3</option>
</select>
</main>
</body>
</html>
Zmienna `select2Data` zawiera tablicę obiektów dla poszczególnych wybranych opcji. Dla odmiany zastosowaliśmy indeks liczony od 1 co oznacza, iż należy to dodatkowo uwzględnić w kodzie.
$(function() {
var generateSelect = function(index) {
$('#generated').remove();
var select = $('<select/>', {
id: 'generated',
name: 'v2',
html: $.map(select2Data[index], function(v) {
return $('<option/>', {
text: v.text,
value: v.value
});
})
});
select.appendTo('body > main');
};
$('select[name="v1"].wariant3').on('change', function(event) {
event.preventDefault();
generateSelect($(this).prop('selectedIndex')+1);
});
});
Kodu tym razem jest trochę więcej. Po zmianie wartości naszego pola `select` wywoływana jest funkcja `generateSelect` do której przekazujemy aktualny indeks powiększony o 1. Jest to indeks obiektu `select2Data` czyli tablica wartości dla danego indeksu. Sama funkcja `generateSelect` na początku usuwa dynamicznie wygenerowany element (#generated), następnie tworzy nowy `select` o takim identyfikatorze, nadaje mu `name` = v2. Jako HTML generujemy pola `option` bazujące na tablicy `select2Data`. Jeśli nie wiesz Czytelniku co dane zmienne zawierają pamiętaj, że w każdym miejscu w kodzie możesz wywołać polecenie:
console.log(zmienna);
które wyświetli w konsoli przeglądarki wartość zmiennej. Cały nowo utworzony `select` dodawany jest do elementu `body > main`.
Podsumowanie
Mam nadzieję że artykuł wyjaśnił trochę zawiłości tworzenia i oddziaływania pól na siebie. Przy niewielkim nakładzie pracy można uzyskać naprawdę ciekawe efekty. Jeśli masz Czytelniku pytania albo nasunął Ci się pomysł na kolejny wariant zapraszam do komentowania.
Dodaj komentarz
- php
- spl
- composer
- sieć
- http
- apache
- ssl
- javascript
- jquery
- html
- ajax
- css
- pdo
- sql
- mysql
- postresql
- mongodb
- sql server
- programowanie
- regex
- psr
Wyszukaj interesujące Cię słowa kluczowe pośród istniejących porad.
Komentarze
Nie ma jeszcze żadnych komentarzy do wyświetlenia. Może chcesz zostać pierwszą osobą która podzieli się swoją opinią?