2014年6月17日 星期二

核取方塊 Checkbox 的存取方法

昨天在改 project_v3 程式時, 為了如何存取一個 checkbox 竟然腦中一片空白 (我看是老了), 連 jQuery 與 ExtJS 要怎麼用也太久沒用生鏽了. 這裡就做個總整理, 以備不時之需.

首先是原始的 Javascript 作法, 在下列範例 1 中, 有一個 checkbox 群組, 要成為群組必須 name 相同, 這樣用 form 來取得此名稱時, 是取得一個 checkbox 物件陣列的參考, 因此可用 for 迴圈判斷哪一個 checkbox 被選取了 (checked 屬性為 true).

測試範例 1http://tony1966.xyz/test/jstest/checkbox_1.htm [看原始碼]

  <form>
    喜歡的水果 : <br>
    <input type="checkbox" name="fruit" value="蘋果" checked>蘋果
    <input type="checkbox" name="fruit" value="香蕉">香蕉
    <input type="checkbox" name="fruit" value="櫻桃">櫻桃<br>
    <input type="button" value="確定" onclick="check(this.form)">
  </form>
  <script language="Javascript">
    function check(formObj) {
      var obj=formObj.fruit;
      var selected=[];
      for (var i=0; i<obj.length; i++) {
        if (obj[i].checked) {
          selected.push(obj[i].value);
          }
        }
      alert("您喜歡的水果 : " + selected.join());
      }
  </script>

此例在按鈕元素中直接以 onclick 屬性處理動作事件, 強調 MVC 架構者不會建議這麼寫, 認為 View (網頁) 跟 Control (程式) 應該分開來. 另外, 我們用 this.form 當參數, 把表單物件傳給 check() 函式, 這樣在函式中用 formObj.fruit 便可取得 checkbox 群組陣列物件了. 若表單要傳給後端伺服器, 表單元件一定要用 form 元素包起來, 這樣瀏覽器才能將表單元件的內容放到 HTTP 協定裏傳給伺服器. 但若只是本地執行的網頁程式, 事實上是不需要用 form 元素包裹的, 如下面範例 2 所示 :

測試範例 2 : http://tony1966.xyz/test/jstest/checkbox_2.htm [看原始碼]

喜歡的水果 : <br>
<input type="checkbox" name="fruit" value="蘋果" checked>蘋果
<input type="checkbox" name="fruit" value="香蕉">香蕉
<input type="checkbox" name="fruit" value="櫻桃">櫻桃<br>
<input type="button" name="ok" id="ok" value="確定">
  <script language="Javascript">
    var btn=document.getElementById("ok");
    btn.onclick=function(){
      var obj=document.getElementsByName("fruit");
      var selected=[];
      for (var i=0; i<obj.length; i++) {
        if (obj[i].checked) {
          selected.push(obj[i].value);
          }
        }
      alert("您喜歡的水果 : " + selected.join());
      };
  </script>

此例我們使用 DOM 中 document 物件的  getElementById(), getElementsByName(), getElementsByTagName 等又臭又長的方法來取得網頁元件, 要注意以 Name 或 TagName 取得的可能是多個元件, 因此是用複數的 Elements, 而以 Id 取得的則是獨一無二的元件, 用單數 Element. 此例的 ok 按鈕也可以用 getElementsByName() 取得, 但因為它一律傳回一個陣列參考, 因此雖然名稱為 ok 者只有一個, 但仍必須用 btn[0] 才能正確取得 ok 按鈕, 此例也可改為 :

    var btn=document.getElementsByName("ok");
    btn[0].onclick=function(){ ... }

接下來看看 jQuery 怎麼做? 如下列範例 3 所示 :

測試範例 3 : http://tony1966.xyz/test/jstest/checkbox_3.htm [看原始碼]

  喜歡的水果 : <br>
  <input type="checkbox" name="fruit" value="蘋果" checked>蘋果
  <input type="checkbox" name="fruit" value="香蕉">香蕉
  <input type="checkbox" name="fruit" value="櫻桃">櫻桃<br>
  <input type="button" id="ok" value="確定">
  <script language="Javascript">
    $(document).ready(function(){
      $("#ok").click(function(){
        var selected=[];
        $("[name=fruit]:checkbox:checked").each(function(){
          selected.push($(this).val());
          });
        alert("您喜歡的水果 : " + selected.join());
        });
      });
  </script>

jQuery 只要用 [name=fruit]:checkbox:checked 這個過濾器就可以抓出被選取的 checkbox 了, 非常簡潔. 選取後得到包裹物件集合, 便可用 each() 公用函式來拜訪集合中的每一個包裹物件 $(this), 呼叫其 val() 方法便能取得其 value 屬性之值. 注意, 在 jQuery 中 $(this) 表示目前的包裹物件 (或稱為 jQuery 物件), 而 this 則為其相對之 DOM 物件.

1 則留言: