Dosyć dawno napisałem artykuł – http://piotrooo.com/2009/12/zalezne-od-siebie-select-listy/ – na temat wybierania na podstawie zależności w select list’ach. Pojawiły się komentarze, że fajnie by było oprzeć to o jakiś JS‘owy framework, więc obecnie miałem projekt, który wymagał zrobienia owej funkcjonalności to dobrym pomysłem będzie pokazanie jak to wygląda za pomocą (IMHO) najlepszego z dostępnych FW do JS‘a – jQuery. Zobaczcie, co? jak? dlaczego?

1. Wprowadzenie
Pozwólcie, że posłużę się przykładem tabel stworzonych we wcześniej wspomnianym artykule. W ramach przypomnienia:

Posiadamy tabelę list1 i list2:

 MySQL |  copy code |? 
CREATE TABLE IF NOT EXISTS `list1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nazwa` varchar(100) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8_polish_ci AUTO_INCREMENT=1;

 MySQL |  copy code |? 
CREATE TABLE IF NOT EXISTS `list2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nazwa_list2` varchar(100) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL,
  `id_list1` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8_polish_ci AUTO_INCREMENT=1 ;

Wylistowanie ich wygląda następująco:

 MySQL |  copy code |? 
mysql> SELECT * FROM list1;
+----+---------+
| id | nazwa   |
+----+---------+
|  1 | wybór_1 |
|  2 | wybór_2 |
|  3 | wybór_3 |
|  4 | wybór_4 |
+----+---------+

 MySQL |  copy code |? 
mysql> SELECT * FROM list2;
+----+-------------+----------+
| id | nazwa_list2 | id_list1 |
+----+-------------+----------+
|  1 | wybór_1_1   |        1 |
|  2 | wybór_1_2   |        1 |
|  3 | wybór_1_3   |        1 |
|  4 | wybór_2_1   |        2 |
|  5 | wybór_2_2   |        2 |
|  6 | wybór_3_1   |        3 |
|  7 | wybór_3_2   |        3 |
|  8 | wybór_3_3   |        3 |
|  9 | wybór_4_1   |        4 |
+----+-------------+----------+

Relacje są tworzone na podstawie list1.id=list2.id_list1. Chyba wszystko jasne. Przejdźmy dalej.

2. AJAX w jQuery
Do realizacji zapytań ajax’owych jQuery używa odpowiedniej metody: $.ajax({}). W dokumentacji wszystkie parametry jakie można wykorzystywać, nie będę się na ten temat rozpisywał. Pożądaną własnością jest używanie metody .live(), która będzie nam „przypinać” zdarzenia do nowo stworzonego selektora (kiedyś jak byłem młody i piękny nie znałem tej wspaniałej opcji do czasu aż zostałem oświecony przez nospor‘a – pozdrowienia :) – i od tego czasu używam jej wszędzie gdzie tylko widzę słowa AJAX i jQuery :) ). Dość teorii, czas na kod.

3. „Serce” naszego algorytmu
Zacznijmy od wyświetlenia naszych list:

 PHP |  copy code |? 
include ('mysql.php');
 
$list1_query = mysql_query('SELECT * FROM list1');
 
echo '<select name="list1" id="list1">';
while($row_list1 = mysql_fetch_array($list1_query))
{
	echo '<option value="'.$row_list1['id'].'">'.$row_list1['nazwa'].'</option>';
}
echo '</select>';
<div id="pokaz">
$list2_query = mysql_query('SELECT * FROM list2');
 
echo '<select name="list2" id="list2">';
while($row_list2 = mysql_fetch_array($list2_query))
{
	echo '<option value="'.$row_list2['id'].'">'.$row_list2['nazwa'].'</option>';
}
echo '</select>';
</div>

W ten sposób mamy wyświetlone wszystkie opcje z naszych list. Kolejnym krokiem jest stworzenie pliku, w którym będziemy sobie tworzyć naszą listę już z odpowiednim warunkiem wyświetlania.

Nasz plik nazwiemy ajax_funkcje.php. W nim znajdować będzie się znajdować include do pliku z połączeniem bazy i dane które będziemy wyświetlać użytkownikowi po wybraniu odpowiednich opcji.

Przejdźmy już do request’ów (zapytań) generowanych przez AJAX. Jak już wspomniałem jQuery korzysta z funkcji $.ajax(). Jak to może wyglądać, zobaczmy:

 Javascript |  copy code |? 
$('#list1').live('change', function(){ //1
	var value = $(this).val();//2
	$.ajax({//3
		type: 'GET',//4
		url: 'ajax_funkcje.php',//5
		data: 'show_list2=1&id='+value+'',//6
		success: function(data){//7a
			$('#pokaz').html(data);//7b
		}
	});
});

Zakładam, że czytający ma podstawową znajomość używania selektorów w jQuery. Jeśli nie zapraszam do dokumentacjo API jQuery

Omówmy po kolei co znaczy każda linia.

  1. Odwołanie się do pierwszej select listy na podstawie, której będziemy wyświetlać dane w drugiej, używamy tu event’u change (Ci co nie wiedzą zapraszam do dokumentacji)
  2. Do zmiennej value dodajemy wartość na podstawie której chcemy wyświetlić dane w drugiej select liście, w naszym przypadku – ID
  3. Odwołujemy się do metody $.ajax()
  4. Typ przesyłania request’ów via AJAX (GET/POST)
  5. Plik w którym następuje „obróbka” danych wysłanych przez AJAX
  6. Dane przesyłane do naszego pliku z obróbką zapytań
  7. Funkcja zwracająca nam – w chwili poprawnego otrzymania odpowiedzi od AJAX’a – danych i wyświetlenie ich w odpowiednim miejscu, w naszym przypadku w div’ie o id pokaz

Tak to wygląda po stronie JS, zobaczmy jak należy sformatować dane w pliku ajax_funkcje.php:

 PHP |  copy code |? 
if ($_GET['show_list2'])
{
	$id_list1 = mysql_real_escape_string($_GET['id']);
	$list2_query = mysql_query('SELECT * FROM list2 WHERE id_list1=$id_list1');
 
	echo '<select name="list2" id="list2">';
	while($row_list2 = mysql_fetch_array($list2_query))
	{
		echo '<option value="'.$row_list2['id'].'">'.$row_list2['nazwa'].'</option>';
	}
	echo '</select>';
}

W tym momencie dane (select lista) zostaje wysłana do AJAX’a jako odpowiedź, którą za pomocą funkcji success, wyświetlamy w odpowiednim linku.

4. Epilog
Czym różni się sposób opisany w tym artykule od sposobu z poprzedniego? Na pewno wizualnie krótszy, przejrzysty, czytelny. Jest to sposób elegancki, bo właśnie w ten sposób trzeba napisać mówiąc o programowaniu za pomocą frameworków. Kod ten jest skalowalny na wszelkie przeglądarki więc nie musimy się zamartwiać o to czy tu będzie działać, a tam już nie.