Javascriptでバリデーションする際の注意点

2009 年 2 月 24 日 by 山平

Webシステムを開発する際に、クライアント側でもバリデーションをすることが少なくありません。
便利なライブラリは沢山ありますが、自力で実装しなければならない場合もしばしば。
そんななかでdocument.form.elementsについて、何だか分かりにくいなあ、と言う部分をまとめてみました。

■確認環境

例として以下のようなHTML入力フォームを考えてみます。

<form name="fmPersonal">
名前:
<input type="text" name="txFullname" />
性別:
<input type="radio" name="raSex" value="male" />男
<input type="radio" name="raSex" value="female" />女
ペット:
<input type="checkbox" name="chPets" value="dog" />犬
<input type="checkbox" name="chPets" value="cat" />猫
血液型:
<select name="ssBlood">
<option value="A">A</option>
<option value="B">A</option>
</select>
家族:
<select name="smFamily" multiple="multiple">
<option value="father">父</option>
<option value="mother">母</option>
</select>
</form>

■elementsコレクションの戻り値

上記の確認環境は一般的な作りだと思いますが、これら要素にdocument.elementsコレクションを介してアクセスすると…

//名前:→Element(text)オブジェクト
document.forms["fmPersonal"].elements["txFullname"];
//ペット:→NodeListオブジェクト
document.forms["fmPersonal"].elements["chPets"];
//性別:→NodeListオブジェクト
document.forms["fmPersonal"].elements["raSex"];
//血液型:→Element(select)オブジェクト
document.forms["fmPersonal"].elements["ssBlood"];
//家族:→Element(select)オブジェクト
document.forms["fmPersonal"].elements["smFamily"];

要素の種類に関わらず、同じnameを持たない要素はElementオブジェクトが、同じnameを持つ要素は、NodeListオブジェクトが返ってきます。
同名のラジオボタンやチェックボックスを使って選択肢を(特にDBから動的に)作成する場合には、戻り値がElementオブジェクトなのかNodeListオブジェクトなのかを意識する必要があります。
このような場合は、対象が1件でもNodeListオブジェクトを返してくれるgetElementsByNameメソッドを利用した方が余計な判別なしにループできて簡潔になります。

【参考】document.getElementsByName

■select要素を扱う際の注意

select要素のvalue属性も注意が必要です。
確認環境の項目「血液型」と「家族」。
HTML的には両者とも「type=select」ですが、Javascriptでは単一/複数選択で得られるtypeが違います。
単一選択の場合は「select-one」、複数選択の場合は「select-multiple」です。
この「select-multiple」で取得できる値が曲者で、value属性では選択されている先頭の値しか取れません。
値を正しく取得するためには、optionsコレクションの各要素のchecked属性を見なければなりません。

■NodeListの扱い

ラジオボタンはHTMLの仕様上、名前がかぶるのでElementかNodeListかの判別が必ず必要ですが、instance演算子で比較する際には、NodeListオブジェクトかどうかで判別するのではなく、Elementオブジェクトかどうかを見て判別した方が無難なようです。

【参考】Opera9.5βでNodeListの扱いが変化
Operaなんて少数派だからいいじゃんと言うなかれ、Firefoxもバージョン2と3では微妙に違います。
この件については十分な検証環境がないためこれ以上追うことができません。

以上です。

タグ:

TrackBack