- PR -

セレクトボックスが変更されたら対応する処理をするには

投稿者投稿内容
BoBo
会議室デビュー日: 2006/02/23
投稿数: 7
投稿日時: 2006-02-23 22:44
2つのセレクトボックスがあって、一方が変わったら他方も変わるという処理を
LookupDispatchActionを使って作りたいのですが、うまくできません。

セレクトボックスが変わったときに、onchangeでサブミットするJavaScriptを
呼べばいいのかと思いためしたのですが、パラメータをどう設定していいのか
わかりません。どのようにしたらいいのでしょうか?よろしくお願いします。


[[JavaScript]]

function selecter_change(string){
mydispatchForm.cmd.value=string;
mydispatchForm.submit();
}



[[フォームの中]]
↓ボタンのプロパティcmdを、nameに設定して、JavaScriptでvalueを設定してみましたがだめでした。
<input type='hidden' name='cmd' value=''>

<select name='sel' onchange="selecter_change('change')">
<option value='s1'>セレクト1</option>
<option value='s2'>セレクト2</option>
</select>

<html:submit property="cmd"><bean:message key="button.add"/></html:submit>
↑ボタンはうまく動きます。

かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-23 23:25
うまくいかないというのはどう現象が発生しているのでしょうか?

見る限り、同一の名前(ボタンとhidden)が同じフォームに存在しているので、
mydispatchForm.cmdは配列になります。
mydispatchForm.cmd[0]がhiddenになって、
mydispatchForm.cmd[1]がsubmitになりますよ。
BoBo
会議室デビュー日: 2006/02/23
投稿数: 7
投稿日時: 2006-02-23 23:52
現象を記載せずにすいませんでした。

リクエスト[/mydispatch]に cmd という名前のハンドラパラメータがありません

というエラーになります。


セレクトボックスを変えた場合:
<input type='hidden' name='cmd' value='change'>と予めvalue値を入力としておけば
エラーなく動くのですが、valueに値を指定しないとエラーになります。valueが書き換えられていないように思えます。

ボタン毎に処理が変わることを確認した後、セレクトボックスでもできるかと思い試していたのですが、hiddenの部分を加えたら、ボタンでも同様のエラーになってしまいました。


よろしくお願いします。

[ メッセージ編集済み 編集者: BoBo 編集日時 2006-02-23 23:54 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-24 00:22
エラーとなる原因は、hiddenに値が格納されていないからですが、
直接的な原因はヒントのつもりで書いた事です。
配列になっているのに、要素を指定していないので
値が設定されていないのです。

StrutsのLookupDispatchActionのソースをチラッと読んだのですが、
リクエストパラメータからBoBoさんの例でいう、'cmd'の文字で値を取得しています。
その値がnullもしくは0文字ならエラーにしているみたいですね。

ちなみに、HttpServletRequest#getParameterで
委譲先のメソッドを判断しているわけですが、
getParameterメソッドは複数の同じ名前のパラメータが存在する場合、
先頭のものを返します。
ですので、ボタンとhiddenで両方同じ名前を使用する場合、
hiddenの値が先に取得されると、ボタンの内容は一切無視されます。

フォーム部品はdisabled属性をtrueにするとname=valueの形式で送信されないため、
ボタンクリック時にhiddenタグのdisabled属性をtrueにするなどの対策も必要です。
BoBo
会議室デビュー日: 2006/02/23
投稿数: 7
投稿日時: 2006-02-24 00:24
JavaScriptにalertを入れてみたら、alertの時点ではcmdの値は変わっていました。
だけど、submitしたときに送信されるのは、別の値のようです。


function selecter_change(string){
mydispatchForm.cmd.value=string;
alert(mydispatchForm.cmd.value);

mydispatchForm.submit();
}
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-24 00:55
同じ名前のフォーム部品が1つだけの場合、
form.elemはフォーム部品を直接示していて
valueというプロトタイプを持っています。
このプロトタイプが送信される値です。

複数ある場合は配列になるため、
form.elemは配列を示すことになり、value="xxx"は配列のプロトタイプに対して
値を設定していることになります。
この時点で、form.elemのプロトタイプは0,1,valueになります。
このうち、フォーム部品を示すプロトタイプは0,1です。
valueは配列オブジェクトの単なる文字列格納領域になっています。
つまり、フォーム部品に値が設定されていないということです。

JavaScriptはオブジェクトに存在しないプロトタイプに対して代入を行うと、
自動的にプロトタイプが作られるため、間違いやすいです。
hiddenを使うときには動作が確認されるまでtext等に変えて可視化してから
テストを行うと良いでしょう。
BoBo
会議室デビュー日: 2006/02/23
投稿数: 7
投稿日時: 2006-02-24 01:06
できました!下部にまとめておきます。
かつのりさん、どうもありがとうございました。


同一の処理をAction#executeでも作りました。それは、パラメータcmdを用意して、cmdにchangeとか、btn1とかをセットしてサーバに送り、if文でcmdに応じた処理に振り分けるようにしました。この方法だと、重複する項目がある場合でもフォーム毎にActionを作らないといけないように感じ、またボタン毎に検証ルールも設定できないのでLookupDispatchActionで作ったという経緯があります。

状況に応じてActionやLookupDispatchActionを使い分けると思いますが、経験が豊富な方はどういう基準で選ぶのでしょうか?よろしければアドバイスをお願いします。




function selecter_change(string){
mydispatchForm.cmd[0].value=string;
mydispatchForm.cmd[0].disabled=false;
mydispatchForm.submit();
}

<html:submit property="cmd" onclick="cmd[0].disabled='true';">
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-24 01:12
Strutsは解析したことはあっても、あんまり使っていないので、
使い分けとか全然考えたことがないです・・・

どんな状況でも活用できるような万能フレームワークではありませんので、
複雑な要求に対しては、それなりに泥臭い処理を書かなければいけないですね。

スキルアップ/キャリアアップ(JOB@IT)