- - PR -
セレクトボックスが変更されたら対応する処理をするには
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 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> ↑ボタンはうまく動きます。 |
|
投稿日時: 2006-02-23 23:25
うまくいかないというのはどう現象が発生しているのでしょうか?
見る限り、同一の名前(ボタンとhidden)が同じフォームに存在しているので、 mydispatchForm.cmdは配列になります。 mydispatchForm.cmd[0]がhiddenになって、 mydispatchForm.cmd[1]がsubmitになりますよ。 |
|
投稿日時: 2006-02-23 23:52
現象を記載せずにすいませんでした。
リクエスト[/mydispatch]に cmd という名前のハンドラパラメータがありません というエラーになります。 セレクトボックスを変えた場合: <input type='hidden' name='cmd' value='change'>と予めvalue値を入力としておけば エラーなく動くのですが、valueに値を指定しないとエラーになります。valueが書き換えられていないように思えます。 ボタン毎に処理が変わることを確認した後、セレクトボックスでもできるかと思い試していたのですが、hiddenの部分を加えたら、ボタンでも同様のエラーになってしまいました。 よろしくお願いします。 [ メッセージ編集済み 編集者: BoBo 編集日時 2006-02-23 23:54 ] |
|
投稿日時: 2006-02-24 00:22
エラーとなる原因は、hiddenに値が格納されていないからですが、
直接的な原因はヒントのつもりで書いた事です。 配列になっているのに、要素を指定していないので 値が設定されていないのです。 StrutsのLookupDispatchActionのソースをチラッと読んだのですが、 リクエストパラメータからBoBoさんの例でいう、'cmd'の文字で値を取得しています。 その値がnullもしくは0文字ならエラーにしているみたいですね。 ちなみに、HttpServletRequest#getParameterで 委譲先のメソッドを判断しているわけですが、 getParameterメソッドは複数の同じ名前のパラメータが存在する場合、 先頭のものを返します。 ですので、ボタンとhiddenで両方同じ名前を使用する場合、 hiddenの値が先に取得されると、ボタンの内容は一切無視されます。 フォーム部品はdisabled属性をtrueにするとname=valueの形式で送信されないため、 ボタンクリック時にhiddenタグのdisabled属性をtrueにするなどの対策も必要です。 |
|
投稿日時: 2006-02-24 00:24
JavaScriptにalertを入れてみたら、alertの時点ではcmdの値は変わっていました。
だけど、submitしたときに送信されるのは、別の値のようです。 function selecter_change(string){ mydispatchForm.cmd.value=string; alert(mydispatchForm.cmd.value); mydispatchForm.submit(); } |
|
投稿日時: 2006-02-24 00:55
同じ名前のフォーム部品が1つだけの場合、
form.elemはフォーム部品を直接示していて valueというプロトタイプを持っています。 このプロトタイプが送信される値です。 複数ある場合は配列になるため、 form.elemは配列を示すことになり、value="xxx"は配列のプロトタイプに対して 値を設定していることになります。 この時点で、form.elemのプロトタイプは0,1,valueになります。 このうち、フォーム部品を示すプロトタイプは0,1です。 valueは配列オブジェクトの単なる文字列格納領域になっています。 つまり、フォーム部品に値が設定されていないということです。 JavaScriptはオブジェクトに存在しないプロトタイプに対して代入を行うと、 自動的にプロトタイプが作られるため、間違いやすいです。 hiddenを使うときには動作が確認されるまでtext等に変えて可視化してから テストを行うと良いでしょう。 |
|
投稿日時: 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';"> |
|
投稿日時: 2006-02-24 01:12
Strutsは解析したことはあっても、あんまり使っていないので、
使い分けとか全然考えたことがないです・・・ どんな状況でも活用できるような万能フレームワークではありませんので、 複雑な要求に対しては、それなりに泥臭い処理を書かなければいけないですね。 |