javascriptのname属性で要素を取得できないとき

現象と状況

意外なところで不具合を発見したときの話。


テーブルに表示している行のチェックボックスを選択して、別の画面にパラメータを渡す処理のJavaScriptが以下のように書いていた。

function SelectCheck(){

    var count = 0;

    // これがだめな書き方
    for( i = 0; i < FORM1.tagCheck.length; i++ ){
      if( FORM1.tagCheck[i].checked ){
        count++;
      }
    }

    if( count > 6 ){
      return false;
    }

    return true;
}

<FORM name="FORM1">
  <table class="tableborder">
    <% no = 0;%>
    <% while (param.next()) {%>
      <tr>
        <td class="cont">
          <input type="checkbox" 
             name="tagCheck" id="<%= "tag" + no %>">
        </td>
      </tr>
      <% no++; %>
    <%} %>
  </table>
</FORM>


要素をname属性で取得してどれがチェックされているか判定するんだけど、取得の仕方がこれだと良くない。


この書き方だとname属性の要素が複数あった場合は要素が取得できるが、一つしかない場合idでの取得になってしまい、該当するidの要素がないために取得できなかった。


なんで気づかなかったかというと、そもそも一つになるケースがなかったからテストされてなかったんだけど、仕様変更であとからそういうパターンが発生して発覚した。

修正方法

そういうわけではっきりgetElementsByNameを使用して、要素を取得するように以下のように修正して解決。

function SelectCheck(){

    var count = 0;

    // これでOK
    for( i = 0; i < document.
     getElementsByName("tagCheck").length; i++ ){
      if( document.
     getElementsByName("tagCheck")[i].checked ){
        count++;
      }
    }

    if( count > 6 ){
      return false;
    }

    return true;
}

<FORM name="FORM1">
  <table class="tableborder">
    <% no = 0;%>
    <% while (param.next()) {%>
      <tr>
        <td class="cont">
          <input type="checkbox"
             name="tagCheck" id="<%= "tag" + no %>">
        </td>
      </tr>
      <% no++; %>
    <%} %>
  </table>
</FORM>