W serwisie
dhtmlgoodies.com dostępny jest skrypt "AJAX chained select" - otrzymujemy dwa pola typu SELECT, z tym że opcje dostępne dla drugiego pola SELECT zależą od opcji wybranej w pierwszym polu i są pobierane dynamicznie za pomocą AJAXa.
- Tworzymy pusty katalog na serwerze
- Umieszczamy tam plik ajax.js
- Tworzymy plik index.php i getCities.php o kodzie odpowiednio:
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript">
var ajax = new sack();
function getCityList(sel)
{
var countryCode = sel.options[sel.selectedIndex].value;
document.getElementById('dhtmlgoodies_city').options.length = 0; // Empty city select box
if(countryCode.length>0){
ajax.requestFile = 'getCities.php?countryCode='+countryCode; // Specifying which file to get
ajax.onCompletion = createCities; // Specify function that will be executed after file has been found
ajax.runAJAX(); // Execute AJAX function
}
}
function createCities()
{
var obj = document.getElementById('dhtmlgoodies_city');
eval(ajax.response); // Executing the response from Ajax as Javascript code
}
</script>
<form action="" method="post">
<table>
<tr>
<td>Country: </td>
<td><select id="dhtmlgoodies_country" name="dhtmlgoodies_country" onchange="getCityList(this)">
<option value="">Select</option>
<option value="dk">Denmark</option>
<option value="no">Norway</option>
<option value="us">US</option>
</select>
</td>
</tr>
<tr>
<td>City: </td>
<td><select id="dhtmlgoodies_city" name="dhtmlgoodies_city">
</select>
</td>
</tr>
</table>
</form>
getCities.php:
<?php
<?php
if(isset($_GET['countryCode'])){
switch($_GET['countryCode']){
case "no":
echo "obj.options[obj.options.length] = new Option('Bergen','1');
";
echo "obj.options[obj.options.length] = new Option('Haugesund','2');
";
echo "obj.options[obj.options.length] = new Option('Oslo','3');
";
echo "obj.options[obj.options.length] = new Option('Stavanger','4');
";
break;
case "dk":
echo "obj.options[obj.options.length] = new Option('Aalborg','11');
";
echo "obj.options[obj.options.length] = new Option('Copenhagen','12');
";
echo "obj.options[obj.options.length] = new Option('Odense','13');
";
break;
case "us":
echo "obj.options[obj.options.length] = new Option('Atlanta','21');
";
echo "obj.options[obj.options.length] = new Option('Chicago','22');
";
echo "obj.options[obj.options.length] = new Option('Denver','23');
";
echo "obj.options[obj.options.length] = new Option('Los Angeles','24');
";
echo "obj.options[obj.options.length] = new Option('New York','25');
";
echo "obj.options[obj.options.length] = new Option('San Fransisco','26');
";
echo "obj.options[obj.options.length] = new Option('Seattle','27');
";
break;
}
}
?>
I gotowe. Otwarcie w przeglądarce
index.php wyświetli testowy formularz. Wybranie wartości w pierwszym polu udostępni określone opcje w drugim.
W powyższym przykładzie w pierwszym polu wybieramy kraj, a w drugim wyświetlają się miasta z danego kraju. Tak więc potrzebujemy tabeli zawierającej miasta przypisane do danego kraju. Oto kod SQL tworzący w MySQL potrzebną tabelę:
CREATE TABLE test (
id int(10) unsigned NOT NULL auto_increment,
kraj varchar(20) default NULL,
miasto varchar(100) default NULL,
PRIMARY KEY (id))
ENGINE=MyISAM DEFAULT CHARSET=utf8;
Dodajemy kilka wpisów:
INSERT INTO test (kraj, miasto) VALUES ('Polska', 'Warszawa');
INSERT INTO test (kraj, miasto) VALUES ('Polska', 'Kraków');
INSERT INTO test (kraj, miasto) VALUES ('Polska', 'Wisła');
INSERT INTO test (kraj, miasto) VALUES ('Niemcy', 'Berlin');
INSERT INTO test (kraj, miasto) VALUES ('Niemcy', 'Bishofshofen');
Modyfikujemy
index.php do postaci:
W poniższych przykładach wykorzystano prostą klasę do obsługi połączenia z bazą danych.
Jeżeli chcesz zastosować komponent we własnych skryptach odpowiednio zmodyfikuj kod odpowiedzialny za pobieranie danych z bazy danych.
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript">
var ajax = new sack();
function getCityList(sel)
{
var countryCode = sel.options[sel.selectedIndex].value;
document.getElementById('dhtmlgoodies_city').options.length = 0; // Empty city select box
if(countryCode.length>0){
ajax.requestFile = 'getCities.php?countryCode='+countryCode; // Specifying which file to get
ajax.onCompletion = createCities; // Specify function that will be executed after file has been found
ajax.runAJAX(); // Execute AJAX function
}
}
function createCities()
{
var obj = document.getElementById('dhtmlgoodies_city');
eval(ajax.response); // Executing the response from Ajax as Javascript code
}
</script>
<form action="" method="post">
<table>
<tr>
<td>Country: </td>
<td><select id="dhtmlgoodies_country" name="dhtmlgoodies_country" onchange="getCityList(this)">
<option value="">Wybierz</option>
<?PHP
include 'mysql.class.php';
$a = new mysql_db();
$a->connect('localhost', 'root', '', 'test2');
$q = $a->query_select("SELECT DISTINCT kraj FROM test");
foreach($q as $i)
{
echo '<option value="'.$i['kraj'].'">'.$i['kraj'].'</option>';
}
$a->destruct();
?>
</select>
</td>
</tr>
<tr>
<td>City: </td>
<td><select id="dhtmlgoodies_city" name="dhtmlgoodies_city">
</select>
</td>
</tr>
</table>
</form>
Zamiast statycznej listy opcji dla pierwszego pola SELECT pobraliśmy je z bazy danych. W tym przypadku mamy zapytanie:
SELECT DISTINCT kraj FROM test
Pobieramy unikalną (bez powtórzeń) listę krajów z tabeli. Zastosowana przeze mnie prosta klasa nakładkowa od razu zwraca tablicę asocjacyjną z wynikiem więc możemy wyświetlić poszczególne kraje w pętli. Reszta bez zmian. Natomiast
getCities.php wygląda tak:
<?php
<?php
if(isset($_GET['countryCode']))
{
include 'mysql.class.php';
$a = new mysql_db();
$a->connect('localhost', 'root', '', 'test2');
$q = $a->query_select("SELECT id,miasto FROM test WHERE kraj = '".mysql_real_escape_string($_GET['countryCode'])."'");
foreach($q as $i)
{
echo "obj.options[obj.options.length] = new Option('".$i['miasto']."','".$i['id']."');
";
}
$a->destruct();
}
?>
Żądanie AJAXa przekaże zmienną
$_GET['countryCode'] zawierającą nazwę miasta, tak więc możemy napisać odpowiednie zapytanie, a następnie w pętli wyświetlić odpowiedni kod JavaScript dodający opcje do drugiego SELECTa.
Powyższy kod łatwo dostosować do innych powiązanych danych np. kategoria-podkategoria może być zrobiona identycznie (kategoria - kraj, podkategoria - miasto):
CREATE TABLE kategorie (
id int(10) unsigned NOT NULL auto_increment,
nazwa varchar(20) default NULL,
parent_cat int(10) unsigned NOT NULL,
PRIMARY KEY (id))
ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO kategorie (nazwa, parent_cat) VALUES ('Główna 1', 0);
INSERT INTO kategorie (nazwa, parent_cat) VALUES ('Główna 2', 0);
INSERT INTO kategorie (nazwa, parent_cat) VALUES ('Pod1 Główna 1', 1);
INSERT INTO kategorie (nazwa, parent_cat) VALUES ('Pod2 Główna 1', 1);
INSERT INTO kategorie (nazwa, parent_cat) VALUES ('Pod3 Główna 2', 2);
index.php:
<?PHP
header('Content-Type: text/html; charset=utf-8');
?>
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript">
var ajax = new sack();
function getCityList(sel)
{
var countryCode = sel.options[sel.selectedIndex].value;
document.getElementById('dhtmlgoodies_city').options.length = 0; // Empty city select box
if(countryCode.length>0){
ajax.requestFile = 'getCities.php?countryCode='+countryCode; // Specifying which file to get
ajax.onCompletion = createCities; // Specify function that will be executed after file has been found
ajax.runAJAX(); // Execute AJAX function
}
}
function createCities()
{
var obj = document.getElementById('dhtmlgoodies_city');
eval(ajax.response); // Executing the response from Ajax as Javascript code
}
</script>
<form action="" method="post">
<table>
<tr>
<td>Country: </td>
<td><select id="dhtmlgoodies_country" name="dhtmlgoodies_country" onchange="getCityList(this)">
<option value="">Wybierz</option>
<?PHP
include 'mysql.class.php';
$a = new mysql_db();
$a->connect('localhost', 'root', '', 'test2');
$q = $a->query_select("SELECT id, nazwa FROM kategorie WHERE parent_cat = 0");
foreach($q as $i)
{
echo '<option value="'.$i['id'].'">'.$i['nazwa'].'</option>';
}
$a->destruct();
?>
</select>
</td>
</tr>
<tr>
<td>City: </td>
<td><select id="dhtmlgoodies_city" name="dhtmlgoodies_city">
</select>
</td>
</tr>
</table>
</form>
getCities.php:
<?php
<?php
header('Content-Type: text/html; charset=utf-8');
if(isset($_GET['countryCode']))
{
include 'mysql.class.php';
$a = new mysql_db();
$a->connect('localhost', 'root', '', 'test2');
$q = $a->query_select("SELECT id, nazwa FROM kategorie WHERE parent_cat = '".mysql_real_escape_string($_GET['countryCode'])."'");
foreach($q as $i)
{
echo "obj.options[obj.options.length] = new Option('".$i['nazwa']."','".$i['id']."');
";
}
$a->destruct();
}
?>
Tutaj przyjeliśmy że kategoriom głównym przypisujemy wartość "0" dla pola parent_cat. Dla podkategori pole parent_cat zawiera numer ID kategorii nadrzędnej.
- Dodane: 23.07.2008 przez riklaunim
- Aktualizacja: Dodanie informacji o wykorzystywanej klasie do MySQL