回前頁

表單集合元件選取值偵測:<SELECT> and <RADIO>

什麼叫表單集合元件?
在 HTML 中表單 (FORM) 本身就是一個集合元件,它包含了各種 INPUT、SELECT 、TEXTAREA ...... 等子元件,而形成一個 elements 集合物件,但本範例並不是要 探討怎樣用 Script 去偵測表單集合裡,那個子元件在動作,因為那沒什麼意義。 我們要討論的是表單子元件中,某種型態的子元件,本身並不是單獨的存在,而是由 更下層的同型態子元件集合而構成的。其中目前正流行使用的,是: 這些屬於 FORM 標籤下的集合元件,和 FORM 標籤下的單獨元件(如 TEXT,SUBMIT,PASSWORD...等)在取得瀏覽者輸入值上,是需要不同方式的。像 FORM 下 的單獨子元件,我們可以用下列的 Script 去取出瀏覽者輸入值:
var 變數名稱=document.forms.表單名稱.elements.子元件名稱.value;
但如果你用上述語法去取表單集合子元件的值是會產生錯誤的,因為集合子元件是數個 更下層元素共用一個名稱索引,所以光指名是那個元件還不夠,還要指明是該元件的 第幾個元素,才能確切知道瀏覽者的選取值。而如何得知瀏覽者選擇了集合子元件的 第幾個元素,就是本範例要和你討論的問題。
偵測 RADIO 選取值
首先我們討論瀏覽者在 RADIO 集合元件的選取值偵測,之所以選 RADIO 先講, 是因為 RADIO 元件比較死板,在網頁物件中 (DOM:Document Object Module) 提供的 可用屬性最少,必須用最基本的方法去偵測瀏覽者選取值,所以我們從基本功開始。
RADIO HTML 敘述
首先我們先安排 HTML 敘述如下:
<FORM NAME="form1">
    <!-- 使用四個取名為 rd1 的 radio 選鈕,來構成一個多選一集合物件。 // -->>
    <INPUT TYPE="radio" NAME="rd1" VALUE="漢堡" CHECKED>漢堡
    <INPUT TYPE="radio" NAME="rd1" VALUE="義大利麵">義大利麵
    <INPUT TYPE="radio" NAME="rd1" VALUE="炸雞">炸雞
    <INPUT TYPE="radio" NAME="rd1" VALUE="披薩">披薩
    <!-- 當按傳送鍵時執行 masterFoodChoiceA() radio 偵測自訂函式 // -->>
    <INPUT TYPE="submit" VALUE="傳送菜單" onclick="masterFoodChoiceA();return false;">
</FORM>
RADIO Script 安排
我們從瀏覽器相關說明得知,每個集合中的 RADIO 都有個 checked 屬性, 來記錄該 RADIO 是否被選取,我們只要逐一檢查各 RADIO 的 checked 屬性,就知道 瀏覽者選了那個 RADIO 選項。但有個小問題是那要檢查幾個 RADIO 呢,難道先要在 HTML 中算算有幾個 RADIO ,再寫 RADIO Script 嗎?當然不是不可以,但嫌麻煩了些, 而且那樣的 Script 也很難多 HTML 共用。所以我們可以利用大部分 DOM 集合物件都有 的 length 屬性 (集合或陣列的元素總數屬性),來設定迴圈要跑幾次。首先我們準備 這樣的 RADIO 選項偵測函式:
/* radio 集合選項偵測函式,
   參數 elem 是指外部傳入的 radio 集合物件。 */
function radioChoiceDetect(elem)
{
 /* 變數 result 紀錄 radio 集合物件第幾項被選取,並傳回呼叫函式。 */
 var result;
 /* 逐一檢查各 radio 元素是否被選取 */
 for (var i=0;i < elem.length;i++)
 /* 如果某 radio 的 checked 值為真,表示被瀏覽者選取,那就由 result 紀錄其
    索引編號;也因為 radio 的特性是多選一,所以有一個被選取後,就不需再檢查,
    故使用 break 敘述終止迴圈執行。 */
 {if (elem[i].checked) {result=i;break;}}
 /* 傳回 radio 被選元素的索引編號 */
 return result;}
然後我們再準備可供 form1 表單 submit 鈕所呼叫的執行函式 masterFoodChoiceA():
function masterFoodChoiceA()
{
 /* 準備好要向 radioChoiceDetect 函式傳送的 radio 集合物件 */
 var sendobj=document.forms.form1.elements.rd1;
 /* 依 radioChoiceDetect 函式的傳回值,顯示 radio 集合中的被選項 value 。 */
 alert("你選擇的餐點是 "+sendobj[radioChoiceDetect(sendobj)].value);}
RADIO 選項偵測範例
現在請在下面範例中,選擇一道主食,然後按傳送菜單鍵,你就會看到菜單選擇的顯示 訊息。
意成快餐店主食菜單
漢堡 義大利麵 炸雞 披薩
偵測 SELECT 選取值
相較於 RADIO 元件,一個更受歡迎並被廣泛使用的表單子集合元件是 SELECT 元件。 雖然 SELECT 比 RADIO 擁有更多的屬性,功能也更良好,但我們前幾節偵測 RADIO 選項值得方法,一樣適用在 SELECT 元件上,例如我們在 HTML 中如此佈置:
<FORM NAME="form2">
    <SELECT NAME="sel1">
        <OPTION VALUE="20">咖啡</OPTION>
        <OPTION VALUE="15">紅茶</OPTION>
        <OPTION VALUE="5">可樂</OPTION>
        <OPTION VALUE="10">果汁</OPTION>
    </SELECT>
    <INPUT TYPE="submit" VALUE="傳送菜單"
            onclick="drinkChoiceA();return false;">
</FORM>
我們可以引用偵測 RADIO 選項的自訂函式來偵測 SELECT 的瀏覽者選項,惟一要注意 的是 SELECT 集合元素的是否被選取,判別屬性不是 checked ,而是 selected。 我們把 radioChoiceDetect 函式改寫如下:
/* select 集合選項偵測函式,
   參數 elem 是指外部傳入的 select 集合物件。 */
function selectChoiceDetect(elem)
{var result;
 for (var i=0;i < elem.length;i++)
 {if (elem[i].selected) {result=i;break;}}
 return result;}
除了函式名稱和紅色粗體字處有改變外,其他完全照抄。
更多可利用的屬性
RADIO 元件只有 value 屬性一個可作為瀏覽者不同選擇的參考,但 SELECT 元件除了 value 之外,在開始 <OPTION> 標記和結束 </OPTION> 標記中還可包含 字串,作為選項顯示,並可在 Script 中使用 text 屬性取出其字串值。譬如前一段的 HTML 敘述,就是利用 OPTION 的包含字串做飲料單項名稱顯示,而用 value 屬性標示 各飲料之價錢。所以供 submit 鈕執行的函式是這麼設計的:
function drinkChoiceA()
{var sendobj=document.forms.form2.elements.sel1;
 /* 呼叫 selectChoiceDetect 函式查出瀏覽者選了那種飲料 */
 var no=selectChoiceDetect(sendobj);
 alert("你選擇的飲料是:"+sendobj[no].text+"\n價錢是:"
  +sendobj[no].value+"元");}
SELECT 選項偵測範例
現在請在下面範例中,選擇一杯飲料,然後按傳送菜單鍵,你就會看到菜單選擇的顯示 訊息。

意成快餐店飲料單

請選擇快餐飲料:
更方便的偵測屬性
或許是瀏覽器廠商覺得用一個迴圈去偵測 RADIO 和 SELECT 集合元件的選項值仍然 太麻煩,所以 Internet Explorer 和 Netscape Navigator 兩大瀏覽器在 4.0 以後, 在 SELECT 元件上都提供了 selectedIndex 屬性。selectedIndex 是記錄了瀏覽者在 SELECT 集合元素上,最後一個選取元素的索引值,所以如果 SELECT 元件是單選集合, 那麼 selectedIndex 值即瀏覽者在 SELECT 上的選項索引值。如果我們使用 SELECT 的 selectedIndex 屬性,就可以代替 selectChoiceDetect 函式的傳回值,而不再需要用 迴圈來逐一檢測。因此我們可以把原 drinkChoiceA 函式改寫如下:
function drinkChoiceA()
{var sendobj=document.forms.form2.elements.sel1;
 var no=selectChoiceDetect(sendobj);
 var no=sendobj.selectedIndex;
 alert("你選擇的飲料是:"+sendobj[no].text+"\n價錢是:"
  +sendobj[no].value+"元");}
 /* 銀灰字表刪除之原敘述,紅色字表新增之敘述。 */
SELECT 複選項偵測
SELECT 除了可像 RADIO 一樣,以集合元素供瀏覽者做多選一的選擇外,借由 HTML 標記中 MUTIPLE 屬性的使用,還可做集合項複選的動作。譬如我們可以這樣佈置 HTML 敘述:
<FORM NAME="form3">
    <SELECT NAME="sel1" MULTIPLE SIZE="3">
        <OPTION VALUE="25">薯條</OPTION>
        <OPTION VALUE="40">雞塊</OPTION>
        <OPTION VALUE="30">南瓜派</OPTION>
        <OPTION VALUE="30">頻果派</OPTION>
        <OPTION VALUE="25">洋蔥圈</OPTION>
    </SELECT>
    <INPUT TYPE="submit" VALUE="傳送菜單"
            onclick="snikerChoice();return false;">
</FORM>
複選偵測的 Script
雖然我們在前段提到 SELECT 有個好用的屬性 selectedIndex ,但因為這屬性只紀錄 最後一次選取項目的索引值,無法顯示瀏覽者複選的狀況,所以最後解決之道還是 要回到我們一開始的最基本方案,用迴圈逐一撿查 SELECT 集合元素的 selected 值。
/* SELECT 複選項偵測函式 */
function multiSelectChoiceDetect(elem)
{var result=new Array();	//因為要把所有選擇項目都紀錄下來,所以使用陣列變數。
 for (var i=0;i < elem.length;i++)
 {if (elem[i].selected) {result[result.length]=i;}}	//要從頭到尾,找出所有被選項目,所以不使用 break 脫離敘述。
 /* 傳回陣列,而非單一值。 */
 return result;}
複選顯示的 Script
既然 SELECT 複選項檢測函式傳回值是陣列,那麼接收傳回值的顯示函式,同樣也必須 以迴圈來逐一處理傳回之陣列值,因此範例安排如下:
/* SELECT 複選項顯示函式 */
function snikerChoice()
{var sendobj=document.forms.form3.elements.sel1;
 /* 用 choice 接收偵測函式傳回之陣列值 */
 var choice=multiSelectChoiceDetect(sendobj);
 var total=0;
 var str="你選擇的點心是:";
 /* 逐一處理選擇項目 */
 for (var i=0;i < choice.length;i++)
 {str+="\n"+sendobj[choice[i]].text;	//將選項名稱加入顯示字串。
  total+=parseFloat(sendobj[choice[i]].value);}		//總計選項金額。
 str+="\n點心總金額是:"+total+" 元";
 alert(str);
SELECT 複選項範例
現在請在下面範例中,選擇若干點心,要複選需配合 [ctrl] or [shift] 按鍵,選好後 按傳送菜單鍵,你就會看到菜單選擇的顯示訊息。

意成快餐店點心單

請選擇快餐點心:



意成組合快餐報價單

好了,有了上面各段使用表單集合元件的選項偵測技術后,你已經有足夠的能力去設計 一份動態報價的網頁,下面是這些 DHTML 技術的綜合運用,你可以參考看看。

意成組合快餐報價單
主菜飲料點心


份量選擇:
超大


單選單選多選

回前頁
1