Powiązane pola Select wykorzystujące Ajaxa
23 July 2008
Comments
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.Jak tego użyć
- 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>
<?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;
}
}
?>
Generowanie opcji z wykorzystaniem bazy danych
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;
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');
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>
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
if(isset($_GET['countryCode']))
{
include 'mysql.class.php';
$a = new mysqli_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();
}
?>
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);
<?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>
<?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();
}
?>
RkBlog
Comment article