7-3 動態下拉式選單

使用 select 標籤,我們可以產生單選或是多選的下拉式選單,但是這些選單的選項都是固定的,若要能夠即時改變這些選項,就要靠 JavaScript。本節將說明如何以 JavaScript 來即時改變這些選項,以產生動態的下拉式選單。

假設一個選單的名稱是 theList,那麼它所具有的性質可以說明如下:

如果我們要刪除選單的選項,有兩種作法:
  1. 使用 theList.options[i]=null 可以直接刪除第 i 個選項。
  2. 使用 theList.options.length=n 可以將選項個數設定為 n,其餘多的選項將會被刪除。
若要增加選項,可以使用下列命令: theList.options[i]=new Option(text, value); 其中 text 和 value 分別代表新選項的文字和值。必須小心的是: 在下列範例中,我們可以動態地增加或刪除選項:

Example(dynamicListBox01.htm):

上述範例的完整原始檔案如下:

原始檔(dynamicListBox01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>動態下拉式選單:增加選項與刪除選項</h2>
<hr>

<script>
function deleteOption(list){
	var index=list.selectedIndex;
	if (index>=0)
		list.options[index]=null;
	else
		alert("無反白選項!");
}

function addOption(list, text, value){
	var index=list.options.length;
	list.options[index]=new Option(text, value);
	list.selectedIndex=index;
}
</script>

<form>
<select id=theList size=5>
	<option value=星期一>Monday
	<option value=星期三>Wednesday
	<option value=星期五>Friday
	<option value=星期日>Sunday
</select>
<p>
<input type="button" value="刪除反白選項" onclick="deleteOption(theList)"><br>
<input type="button" value="增加右列選項" onclick="addOption(theList, theText.value, theValue.value)">
Text: <input id=theText value="test">
Value: <input id=theValue value="test">
</form>

<hr>
</body>
</html>

在上述範例中,我們使用 id 而不使用 name 來代表表單控制項,其好處是可以直接使用 id 來使用表單元素,而不必一定要經由文件物件模型的階層結構來由上到下、一層一層指定。

利用同樣的概念,我們可以產生類似樹狀的結構,可讓使用者進行「目錄搜尋」(Directory Search)。在下列範例中,我們利用動態下拉式選單產生兩層的樹狀結構,或稱「兩框連動」,換句話說,你只要在左方選取系別,右方就會出現成員,請試看看:

Example(dynamicListBox02.htm):

上述範例的完整原始檔案如下:

原始檔(dynamicListBox02.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>動態下拉式選單:兩框連動(兩層樹狀選項)</h2>
<hr>

<script>
department=new Array();
department[0]=["張隆紋", "黃能富", "王炳豐", "張世杰", "張智星"];	// 資訊系
department[1]=["黃瑞星", "黃仲陵", "呂忠津", "鄭博泰", "盧向成"];	// 電機系
department[2]=["楊敬堂", "王培仁", "葉銘權", "宋鎮國"];			// 動機系
department[3]=["王天戈", "開執中", "梁正宏"];				// 工科系

function renew(index){
	for(var i=0;i<department[index].length;i++)
		document.myForm.member.options[i]=new Option(department[index][i], department[index][i]);	// 設定新選項
	document.myForm.member.length=department[index].length;	// 刪除多餘的選項
}
</script>

<form name="myForm">
系別:
<select size=5 onChange="renew(this.selectedIndex);">
	<option value="資訊系">資訊系
	<option value="電機系">電機系
	<option value="動機系">動機系
	<option value="工科系">工科系
</select>

隊員:
<select name="member" size=5>
	<option value="">請由左方選取系別
</select>
</form>

<hr>
</body>
</html>

在上述範例中,我們用到了二維陣列,以方便存取相關資料。

使用類似的方式,我們也可以產生三層的樹狀結構,或稱「三框連動」。在下列範例中,我們將歌曲資料分成三個層次,分別是語言、歌手、歌名,以便進行目錄式搜尋,範例如下:

Example(dynamicListBox03.htm):

在上述範例中,你可以先在左方點選語言,中間就會顯示相關歌手,接著點選歌手,右方就會顯示相關歌名,接著你再點選歌名,下方就會出現完整的搜尋路徑。原始檔案如下:

原始檔(dynamicListBox03.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>動態下拉式選單:三框連動(三層樹狀選項)</h2>
<hr>

<script>
function node(name, child){
	this.name=name;
	this.child=child;
}

function dataHierarchy(){
	// 國語歌手
	var mandarin=new Array();
	var i=0;
	mandarin[i++]=new node("張學友", ["我等到花兒也謝了", "一千個傷心的理由", "咖啡"]);
	mandarin[i++]=new node("張惠妹", ["聽海", "剪愛", "原來你什麼都不要", "三天三夜"]);
	mandarin[i++]=new node("劉德華", ["謝謝你的愛", "來生緣", "忘情水"]);
	mandarin[i++]=new node(  "伍佰", ["浪人情歌", "樹枝孤鳥"]);
	mandarin[i++]=new node("周華健", ["花心", "心的方向"]);
	// 英語歌手
	var english=new Array();
	var i=0;
	english[i++]=new node("Michael", ["Beat It", "Billie Jean", "Heal The World"]);
	english[i++]=new node("Celine", ["My Heart Will Go On", "Hope"]);
	// 語言類別
	var output=new Array();
	var i=0;
	output[i++]=new node("國語", mandarin);
	output[i++]=new node("英語", english);

	return(output);
}
dataTree=dataHierarchy();

// 第三個欄位被更動後的反應動作
function onChangeColumn3(){
	updatePath();
}

// 第二個欄位被更動後的反應動作
function onChangeColumn2(){
	form=document.theForm;
	index1=form.column1.selectedIndex;
	index2=form.column2.selectedIndex;
	index3=form.column3.selectedIndex;
	// Create options for column 3
	for (i=0;i<dataTree[index1].child[index2].child.length;i++)
		form.column3.options[i]=new Option(dataTree[index1].child[index2].child[i], dataTree[index1].child[index2].child[i]);
	form.column3.options.length=dataTree[index1].child[index2].child.length;
	updatePath();
}

// 第一個欄位被更動後的反應動作
function onChangeColumn1() {
	form=document.theForm;
	index1=form.column1.selectedIndex;
	index2=form.column2.selectedIndex;
	index3=form.column3.selectedIndex;
	// Create options for column 2
	for (i=0;i<dataTree[index1].child.length;i++)
		form.column2.options[i]=new Option(dataTree[index1].child[i].name, dataTree[index1].child[i].name);
	form.column2.options.length=dataTree[index1].child.length;
	// Clear column 3
	form.column3.options.length=0;
	updatePath();
}

// 修改所顯示的路徑
function updatePath(){
	form=document.theForm;
	index1=form.column1.selectedIndex;
	index2=form.column2.selectedIndex;
	index3=form.column3.selectedIndex;
	if ((index1>=0) && (index2>=0) && (index3>=0)) {
		text1=form.column1.options[index1].text;
		text2=form.column2.options[index2].text;
		text3=form.column3.options[index3].text;
		form.path.value=text1+" ==> "+text2+" ==> "+text3;
	} else
		form.path.value="";
}
</script>

<form name="theForm">
<table align=center border=1>
	<tr>
		<th>歌曲語言<th>歌星名字<th>歌曲清單
	<tr>
		<td align=center>
			<select name="column1" size=10 onChange="onChangeColumn1();">
				<script>
				for (i=0; i<dataTree.length; i++)
					document.writeln("<option value=\""+dataTree[i].name+"\">"+dataTree[i].name);
				</script>
			</select>
		<td align=center>
			<select name="column2" size=10 onChange="onChangeColumn2();">
			</select>
		<td align=center>
			<select name="column3" size=10 onChange="onChangeColumn3();">
			</select>
	<tr><td colspan=3 align=center>路徑:<input type=text name=path size=60></td></tr>
</table>
</form>

<hr>
</body>
</html>

在上述範例中,我們使用了一個自訂物件的建構函數 node(),以便用來建立此三層樹狀資料結構。此資料結構可以顯示如下:

國語 --- 張學友 --- 我等到花兒也謝了 --- 一千個傷心的理由 --- 咖啡 --- 張惠妹 --- 聽海 --- 剪愛 --- 原來你什麼都不要 --- 三天三夜 --- 劉德華 --- 謝謝你的愛 --- 來生緣 --- 忘情水 --- 伍佰 --- 浪人情歌 --- 樹枝孤鳥 --- 周華健 --- 花心 --- 心的方向 英語 --- Michael --- Beat It --- Billie Jean --- Heal The World --- Celine --- My Heart Will Go On --- Hope
JavaScript 程式設計與應用:用於網頁用戶端