April 9,2009
[AJAX] jQuery的多重下拉式選單應用:Select box manipulation
從本網誌回應數最高的文章得知,大家似乎對多重下拉式選單的功能情有獨鍾啊!Ajax 能夠在不換頁的情況下,達到資料庫連結,是許多人夢寐以求的功能;而 jQuery 易上手與輕鬆操作的特性,讓我們能更簡單的運用 Ajax 達成目的。然而隨著時間的推移,過去介紹的 cascade 已經有很長一段時間沒有更新,而且在使用上其實存在不少綁手綁腳的地方;距離 jQuery 的宗旨「Write Less, Do More」似乎是還差那麼一小段距離...
經由公司的 jQuery 教育訓練,Jace 介紹了一個超讚的 jQuery Plugin:Select box manipulation。透過這個外掛的幫助,可以更輕鬆的實現多重下拉式選單的功能唷,甚至連 cascade 不容易做到的「預設值」也完全沒問題,所需要撰寫的程式碼也少於 cascade,整個就是夢幻的 Plugin!這麼神奇的外掛要怎麼用呢?以下簡單的範例,給有需要的人參考吧:範例是三階層的關聯式多重下拉式選單,分為index.php(呈現頁)、action.php(Ajax 後端資料處理頁)、index.js(JavaScript 處理)、以及 selectboxes
經由公司的 jQuery 教育訓練,Jace 介紹了一個超讚的 jQuery Plugin:Select box manipulation。透過這個外掛的幫助,可以更輕鬆的實現多重下拉式選單的功能唷,甚至連 cascade 不容易做到的「預設值」也完全沒問題,所需要撰寫的程式碼也少於 cascade,整個就是夢幻的 Plugin!這麼神奇的外掛要怎麼用呢?以下簡單的範例,給有需要的人參考吧:範例是三階層的關聯式多重下拉式選單,分為index.php(呈現頁)、action.php(Ajax 後端資料處理頁)、index.js(JavaScript 處理)、以及 selectboxes
首先我們載入 jQuery 以及 selectboxes,同時頁面所需使用的 JavaScript 也利用外部的方式載入:
index.php(節錄):
action.php:
index.js:
是不是非常簡單呢!多樣化的 jQuery Plugin 可以幫助我們更輕鬆的完成過去繁複的程式撰寫工作,真的要感謝廣大網路上樂於分享的前輩們的努力,有需要的人可以試試看這個更簡單的方法唷!
線上程式預覽
範例程式下載(範例程式內附 selectboxes.sql 即為測試用的資料庫 sql 檔)
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="selectboxes.js"></script>
<script type="text/javascript" src="index.js"></script>
index.php(節錄):
<h3>主機 - 類型 - 遊戲(預設值:XBOX360/FPS/刺客聯盟)</h3>有需要填入預設值的時候,至要在隱藏欄位 fullIdPath 中給定 id 的序列值,就可以輕鬆達到設定預設值的效果。
<p>
<select id="select1">
<option value="">請選擇</option>
<?php
// 資料庫設定
$host_sql = 'localhost';
$username_sql = 'username';
$password_sql = 'password';
// 聯結資料庫
$link = mysql_connect($host_sql, $username_sql, $password_sql) or die('無法連結資料庫');
mysql_select_db('selectboxes', $link);
mysql_query('SET NAMES UTF8');
// 動態取得第一階層下拉式選單
$query = 'SELECT id, name FROM games WHERE levelNum = 1';
$result = mysql_query($query, $link);
while ($row = mysql_fetch_assoc($result)) {
echo '<option value="' . $row['id'] . '">' . $row['name'] . '</option>' . "\n";
}
?>
</select>
<select id="select2">
<option value="">請選擇</option>
</select>
<select id="select3">
<option value="">請選擇</option>
</select>
<!-- 利用隱藏欄位指定預設的選項 -->
<input id="fullIdPath" type="hidden" value="3,8,24" />
</p>
action.php:
<?php將取得的資料放入陣列,在經由 json_encode() 轉換為 json 格式;selectboxes 就可以將其轉化為選項
// 資料庫設定
$host_sql = 'localhost';
$username_sql = 'username';
$password_sql = 'password';
// 聯結資料庫
$link = mysql_connect($host_sql, $username_sql, $password_sql) or die('無法連結資料庫');
mysql_select_db('selectboxes', $link);
mysql_query('SET NAMES UTF8');
// 預設選項
$data['0'] = '請選擇';
// 只有在 parentId 與 levelNum 都存在的情況下,才進行資料庫的搜尋
if (0 !== (int) $_GET['id'] && 0 !== (int) $_GET['lv']) {
$parentId = (int) $_GET['id'];
$levelNum = (int) $_GET['lv'];
$query = sprintf("SELECT id, name FROM games WHERE parentId = %d AND levelNum = %d", $parentId, $levelNum);
$result = mysql_query($query, $link);
while ($row = mysql_fetch_assoc($result)) {
// 將取得的資料放入陣列中
$data[$row['id']] = $row['name'];
}
}
// 將陣列轉換為 json 格式輸入
echo json_encode($data);
index.js:
$(function () {
// 判斷是否有預設值
var defaultValue = false;
if (0 < $.trim($('#fullIdPath').val()).length) {
$fullIdPath = $('#fullIdPath').val().split(',');
defaultValue = true;
}
// 設定預設選項
if (defaultValue) {
$('#select1').selectOptions($fullIdPath[0]);
}
// 開始產生關聯下拉式選單
$('#select1').change(function () {
// 觸發第二階下拉式選單
$('#select2').removeOption(/.?/).ajaxAddOption(
'action.php',
{ 'id': $(this).val(), 'lv': 2 },
false,
function () {
// 設定預設選項
if (defaultValue) {
$(this).selectOptions($fullIdPath[1]).trigger('change');
} else {
$(this).selectOptions().trigger('change');
}
}
).change(function () {
// 觸發第三階下拉式選單
$('#select3').removeOption(/.?/).ajaxAddOption(
'action.php',
{ 'id': $(this).val(), 'lv': 3 },
false,
function () {
// 設定預設選項
if (defaultValue) {
$(this).selectOptions($fullIdPath[2]);
}
}
);
});
}).trigger('change');
// 全部選擇完畢後,顯示所選擇的選項
$('#select3').change(function () {
alert('主機:' + $('#select1 option:selected').text() +
'/類型:' + $('#select2 option:selected').text() +
'/遊戲:' + $('#select3 option:selected').text());
});
});
是不是非常簡單呢!多樣化的 jQuery Plugin 可以幫助我們更輕鬆的完成過去繁複的程式撰寫工作,真的要感謝廣大網路上樂於分享的前輩們的努力,有需要的人可以試試看這個更簡單的方法唷!
線上程式預覽
範例程式下載(範例程式內附 selectboxes.sql 即為測試用的資料庫 sql 檔)
引用URL
http://cgi.blog.roodo.com/trackback/8671037
回應文章 

你好,想請教
asp 沒有json_encode();
這段程式碼要怎麼改呢?謝
Posted by miyuki
at April 23,2009 16:59
抱歉,我跟 asp 不熟...不過 google 了一下發現許多資料,應該是不難找到解決的辦法唷;請參考:http://0rz.tw/SxJk8
Posted by 台扣啵
at April 23,2009 17:54

您好:
非常感謝您的幫忙,json的部份我已解決了
Posted by miyuki
at April 23,2009 21:33

請問可以做到以上一階層的sql語法 來決定是否有下一階層的下拉式選單嗎?
下拉式選單的數量是動態的 以上一階層的下拉式選單所下的sql 是否有查到資料為準
Posted by Will
at April 27,2009 00:17
你好,動態產生下一階層的下拉式選單應該不是問題,只是事件的觸發上可能要利用 $.live() 綁定change 事件(http://bit.ly/jNtA);最近有點忙,這方面實際作法可能要請你自行研究囉~謝謝
Posted by 台扣啵
at April 27,2009 22:29

你好,我是改您的方法,因為我有兩張資料表[kind]:kind_id、[food]:food_id、kind_id。
在第一個select1 是用種類資料表[kind_id]去顯示,而在選取第二個select2時,JS部分我是這樣寫。
$('#select2').removeOption(/.?/).ajaxAddOption(
'action.php',
{ 'kind_id': $(this).val() }
action.php直接針對
$query = "SELECT food_id,food_name FROM food where kind_id = %d";
這樣在js依然抓不到值,可以請教怎麼改嘛?
我也想學習樓上詢問的利用sql選取的值,去影響下一層的選單,但$live不支援change...
真的研究很久,但真的寫不出來。可以拜託作者教導嘛,拜託...
Posted by 肉包包
at September 2,2009 00:59

您好
我想做五層下拉
在第三層後加了.change....
第一次load的時候沒問題,但選了其中一個下拉後就會不斷循環跑,不知道是哪邊寫錯了
$('#select3').removeOption(/.?/).ajaxAddOption(
'/action.php',
{ 'id': $(this).val(), 'lv': 3 },
false,
function () {
// 設定預設選項
if (defaultValue) {
$(this).selectOptions($fullIdPath[2]).trigger('change');
} else {
$(this).selectOptions().trigger('change');
}
}
).change(function () {
// 觸發第四階下拉式選單
$('#select4').removeOption(/.?/).ajaxAddOption(
'/action.php',
{ 'id': $(this).val(), 'lv': 4 },
false,
function () {
// 設定預設選項
if (defaultValue) {
$(this).selectOptions($fullIdPath[3]).trigger('change');
} else {
$(this).selectOptions().trigger('change');
}
}
).change(function () {
// 觸發第五階下拉式選單
$('#select5').removeOption(/.?/).ajaxAddOption(
'/action.php',
{ 'id': $(this).val(), 'lv': 5 },
false,
function () {
// 設定預設選項
if (defaultValue) {
$(this).selectOptions($fullIdPath[4]).trigger('change');
}
}
);
});
});
Posted by Amy
at September 2,2009 17:48
To 肉包包:
建議可以把每層的 $query 都印出來,丟到 MySQL 看資料是否正確;也可以印出 $data 這個陣列,看看資料格式是否與 AJAX 符合。
哈,原來 $.live() 不支援 change 事件啊~Sorry;可以試著用 click 事件修改?
To Amy:
建議也是把出問題那一層的 $query 印出來看看
謝謝
Posted by 台扣啵
at September 3,2009 15:51
存檔位置好像死了@@
Posted by 遊客
at September 15,2009 18:16
抱歉,重新開機後就忘了啟動 no-ip;現在應該可以下載了,感謝提醒^^
Posted by 台扣啵
at September 15,2009 23:32

你好,我參考了貴站,完成了三層連動的下拉式選單,但是我想把最後的數據丟到文字框裡是否有辦法?也就是三層的下拉式選單其實都是條件,最後的結果只有一個,我想把這個結果放到文字框裡面,可否請您提供一點意見。
Posted by Empty
at November 26,2009 14:41
你好,如果是要顯示在 input 中;直接改寫 $('#select3').change() function 的內容即可。不過關於後來提到的條件與結果,是指依照 select 的選擇條件,在重新於資料庫中查詢結果嗎?如果是這樣就要用 AJAX 的方式囉~
Posted by 台扣啵
at November 27,2009 10:07
