プロが教えるわが家の防犯対策術!

javascriptでselectボックスの<OPTION>要素数の取得する方法について疑問があります。

データが1件の場合、複数件の場合とで分けて、
<OPTION>要素数を取得する処理を記述していますが、
データが1件の場合、
document.getElementsByName("sel").length
で正しい値が取得できません。

詳しくは下記のソースを参照していただきたいのですが、
(1)、(2)、(4)は、正しい値'5'ですが、
(3)だけ誤った値'1'になります。

これはなぜでしょうか?
javascript初心者のため、初歩的な質問かもしれませんが、
教えていただけたら嬉しいです。
よろしくお願い致します。

--------------------------------------
<HTML>
<HEAD>
<SCRIPT language="JavaScript">
  function getSelLen(){
var oForm = document.form1;
var sObj;
var sObj2;

//チェックボックスの数でデータが複数件か1件か判別しています。
if(oForm.chk.length){//データが複数件の場合
for ( var i = 0; i < oForm.chk.length; i++ ) {
sObj=document.getElementsByName("sel")[i];
alert("(1) "+ sObj.length);//・・・・(1) 正
sObj2=oForm.elements["sel"][i];
alert("(2) "+ sObj2.length);//・・・・(2) 正
}
}else{//データが1件の場合
sObj=document.getElementsByName("sel");
alert("(3) "+ sObj.length);//・・・・(3) 誤
sObj2=oForm.elements["sel"];
alert("(4) "+ sObj2.length);//・・・・(4) 正
}
}
</SCRIPT>
</HEAD>
<BODY>
<FORM name="form1">
<TABLE>
<TR>
<TD>
<INPUT type="checkbox" name="chk" >
</TD>
<TD>
<SELECT name="sel" >
<OPTION value="" selected>
<OPTION value="00">00
<OPTION value="01">01
<OPTION value="02">02
<OPTION value="03">03
</TD>
</TR>
<!-- 複数件の場合 以下のコメントアウトを解除する -->
<!--
<TR>
<TD>
<INPUT type="checkbox" name="chk" >
</TD>
<TD>
<SELECT name="sel" >
<OPTION value="" selected>
<OPTION value="00">00
<OPTION value="01">01
<OPTION value="02">02
<OPTION value="03">03
</TD>
</TR>
-->
</TABLE>
</FORM>
<FORM name="form2">
<INPUT type="button" onClick="getSelLen()" value=" selectの要素数 ">
</FORM>
</BODY>
</HTML>

A 回答 (4件)

getElementsByName()は必ず配列になりますから、


<select name="sel">が1つであっても、<select>を1つだけ取得したい場合は[0]という指定が必要です。


}else{//データが1件の場合
sObj=document.getElementsByName('sel')[0]; // 訂正箇所
alert("(3) "+ sObj.length);//・・・・(3) 誤


sObj.lengthの値は、
sObj=document.getElementsByName('sel')とした場合は<select name="sel">の個数、
sObj=document.getElementsByName('sel')[0]とした場合は、1つめの<select name="sel">の<option>の個数になります。



この動作(配列になるかならないか)はform.elements['sel']の動作と異なります。



なお、複数のフォームフィールドに同じnameが指定されていても問題ありません。
それで送信に失敗する場合は、通常はデータを受け取るCGIアプリケーションのバグです。

PHPで受け取る場合は、通常はname="name[]">のように四角カッコを付ける必要がありますが、HTMLとしては文法違反になります。
<select>に multiple を指定する場合も四角カッコが必要です。
    • good
    • 2
この回答へのお礼

まさに!
私が頂きたかった回答です!ありがとうございます。

document.getElementsByName('sel')[0];
で試してみたら、うまく動作しました。

あと、同じnameが複数指定されている件は、
開発上どうしようもないことで、送信エラーになることはありません。

とても勉強になり、疑問が解消してスッキリしました。
ありがとうございました。

お礼日時:2010/07/23 10:06

なんだか勘違いをなさっているみたい。



>alert("(3) "+ sObj.length);//・・・・(3) 誤
sObjは直前のsObj=document.getElementsByName("sel")なので、要素が1個なら1が返ってきて当然です。
前半でも同じことをやれば、2などが返ってくるはず。(ご提示のコードにはありませんが)
前半で表示させているsObj.lengthは、sObj=document.getElementsByName("sel")[i]なので意味が違います。
というかselect要素のOption数を見るのなら、sObj.Options.lengthのほうが安全かも。

<スクリプトに関して>
select要素の数を判別するのにinput要素の数で判定しているみたいですが、直接select要素の数を見るのが本来のはず。
必ず1対1に対応しているとしても、input要素からみるのなら、それに対応するselect要素を探すという手順になりそう。(こちらの方が面倒ですが)
もっとも、表示させるだけなら場合分けをしなくてもできそうですけど…

前半でforでまわしているのにも関わらず、ループの中で個別の処理をしているのはおかしいのでは?
(コードをそのままで、対象の要素数を3、4…と増やしてみればわかると思います。)


<HTMLに関して>
#1様が既に指摘なさっていますが、ひとつのformの中に同じnameの要素が複数あるのは、formとして問題なのでは。
(送信した時を考えてみればわかるはず)

(その他直接関係はありませんが)
selectタグの閉じタグは省略可能でしたっけ?(よく覚えてませんが…)
タグは小文字を利用する習慣をつけておいたほうが良いかも…
例示からは読み取れませんが、レイアウト用のtable使用は避けた方がよろしいかと。


いろいろ書きましたが、以下サンプルとして。
(1個でも複数でも同じ処理の例。 whileはforに変えても同様にできます。)

function getSelLen(){
var i = 0, res = "", sel = document.forms["form1"].getElementsByTagName("SELECT");
while (sel[i]) res += "No " + i + " : options = " + sel[i++].options.length + "\n";
alert(res);
}
    • good
    • 0
この回答へのお礼

私の勘違いについて、ご指摘いただき理解できました。
ありがとうございます。

そして、ソースについてもご指摘、サンプルまで作っていただいて、
ありがとうございました。

実際に開発しているものをだいぶ省略・簡略し、
疑問点がわかるように書いたつもりだったのですが、
逆におかしくなってしまったようで、、、。

とても勉強になりました。ありがとうございました。

お礼日時:2010/07/23 09:51

(3)は"sel"という名前の要素が幾つあるかだから


1件しかないなら1になりますよ。
それと、OPTIONの個数を調べるならば、
sObj.options.length が正しい書き方です。
    • good
    • 0

nameならば、document.form1.selでできませんか?



<SELECT name="sel" >が2つあるのも問題でしょうね。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!