- PR -

JSF selectOneMenuの連動

投稿者投稿内容
まごまご
常連さん
会議室デビュー日: 2005/11/16
投稿数: 24
投稿日時: 2006-02-09 22:48
selectOneMenuで
あるリスト(A1)を変更したら、リスト(B1)が作成され、
あるリスト(A2)を変更したら、リスト(B2)が作成され、
ということを行いたく、valueChangeListener等を用い
以下のような実装を行っているのですが、(上記リストは全て1画面内にいます)

-------------------
<!-- リストボックスA1 -->
<h:selectOneMenu immediate="true"
id="cdA1" value="#{bean.codeA1}"
onchange="submit()" valueChangeListener="#{bean.codeListenerA1}">
<f:selectItems value="#{bean.codeListA1}"/>
</h:selectOneMenu>
<!-- リストボックスB1 -->
<h:selectOneMenu
id="cdB1" value="#{bean.codeB1}">
<f:selectItems value="#{bean.codeListB1}"/>
</h:selectOneMenu>

<!-- リストボックスA2 -->
<h:selectOneMenu immediate="true"
id="cdA2" value="#{bean.codeA2}"
onchange="submit()" valueChangeListener="#{bean.codeListenerA2}">
<f:selectItems value="#{bean.codeListA2}"/>
</h:selectOneMenu>

<!-- リストボックスB2 -->
<h:selectOneMenu
id="cdB2" value="#{bean.codeB2}">
<f:selectItems value="#{bean.codeListB2}" />
</h:selectOneMenu>

-------------------

このとき、
A1を変更し、B1を作成し、B1から要素を選択したのち
A2を変更した際にB1での選択値を以前の状態に保ちたいのですが
初期化されてしまいます。
何か手段・参考になるURLなど御座いましたらよろしくお願いします。

ValueChangeListenerでは、そのリストの値しか取得出来ませんでした。
submit()されていると思ったのですが、プロパティにセットされた値はnullでした。
まごまご
常連さん
会議室デビュー日: 2005/11/16
投稿数: 24
投稿日時: 2006-02-09 22:53
すみません。valueChangeListenerに関するスレッドを見ていませんでした。
一度確認・検証後、それでもダメな場合はよろしくお願いします。
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-02-10 10:39
引用:

A1を変更し、B1を作成し、B1から要素を選択したのち
A2を変更した際にB1での選択値を以前の状態に保ちたいのですが
初期化されてしまいます。


「B1から要素を選択したのちA2を変更した」というのは,B1にはonchangeを指定して
いないですから,A2の変更でsubmitされ,そのときにB1の新しい値も送信されている
ということですよね.
ここで「初期化されてしまいます」というのは,どのタイミングでどこから何をみたら
初期化されていたのですか?
「beanのcodeListenerA2の中でcodeB1を見たら初期化されていた」?
初期化とは?nullになっていた?以前の入力値になっていた?

例えば,beanをrequestスコープにしておくと,リクエスト毎にインスタンシエートしま
すから,当然,初期値になっています.

引用:

ValueChangeListenerでは、そのリストの値しか取得出来ませんでした。
submit()されていると思ったのですが、プロパティにセットされた値はnullでした。


「そのリストの値」とは?
ValueChangeListenerはデフォルトではProcess Validationsフェーズで実行しますから
beanへの値の反映はまだ行われていません.
まごまご
常連さん
会議室デビュー日: 2005/11/16
投稿数: 24
投稿日時: 2006-02-10 11:28
説明不足ですみません。
引用: ------------------------------------------------------------------------

「B1から要素を選択したのちA2を変更した」というのは,B1にはonchangeを指定して
いないですから,A2の変更でsubmitされ,そのときにB1の新しい値も送信されている
ということですよね.

------------------------------------------------------------------------------
はい。そうです。
以前のスレッドを参考にし、
フェーズをUPDATE_MODEL_VALUESへ変更するという箇所を見ながら
直接Beanのプロパティの値を参照してみましたが、
他の項目(画面上にはtextbox、連動しない別のselectOneMenu等)の値は
submitされた値を参照出来たのですが、
-----
A1:valueChangeListener実装---->動的に変更されるリスト:B1
A2:valueChangeListener実装---->動的に変更されるリスト:B2
-----
A1を変更しvalueChangeListenerを発生させ、
生成されたリストB1の選択値が、A2のvalueChangeListenerの際に
B1の選択値がnull値となってしまい"selected"状態を保てないのです。
(逆の場合も同じ事象でした)
まごまご
常連さん
会議室デビュー日: 2005/11/16
投稿数: 24
投稿日時: 2006-02-10 11:52
度々すみません。今気づいたのですが、
下記のように実装しているのですが、初回は問題ないのですが、
2回目以降、valueChangeListenerが両方とも起動してしまう
(A1を変更させても、A1のvalueChangeListenerの起動後に
A2のvalueChangeListenerが起動します)
個別に動くものとばかり思っておりましたので、今まで気づきませんでした。
原因として何が考えられるでしょうか。

[JSP]-------------------
<!-- リストボックスA1 -->
<h:selectOneMenu immediate="true"
id="cdA1" value="#{bean.codeA1}"
onchange="submit()" valueChangeListener="#{bean.codeListenerA1}">
<f:selectItems value="#{bean.codeListA1}"/>
</h:selectOneMenu>
<!-- リストボックスB1 -->
<h:selectOneMenu
id="cdB1" value="#{bean.codeB1}">
<f:selectItems value="#{bean.codeListB1}"/>
</h:selectOneMenu>

<!-- リストボックスA2 -->
<h:selectOneMenu immediate="true"
id="cdA2" value="#{bean.codeA2}"
onchange="submit()" valueChangeListener="#{bean.codeListenerA2}">
<f:selectItems value="#{bean.codeListA2}"/>
</h:selectOneMenu>

<!-- リストボックスB2 -->
<h:selectOneMenu
id="cdB2" value="#{bean.codeB2}">
<f:selectItems value="#{bean.codeListB2}" />
</h:selectOneMenu>

-------------------
[managedBaen]-------------------
/**
* リストA1
* @param event
*/
public void codeListenerA1(ValueChangeEvent event)
throws AbortProcessingException {

codeListB1 = changeCodeListB1((String) event.getNewValue());
}

/**
* リストA2
* @param event
*/
public void codeListenerA2(ValueChangeEvent event)
throws AbortProcessingException {
codeListB2 = changeCodeListB2((String) event.getNewValue());
}
-------------------
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-02-14 11:53
引用:

以前のスレッドを参考にし、
フェーズをUPDATE_MODEL_VALUESへ変更するという箇所を見ながら
直接Beanのプロパティの値を参照してみましたが、
他の項目(画面上にはtextbox、連動しない別のselectOneMenu等)の値は
submitされた値を参照出来たのですが、
A1を変更しvalueChangeListenerを発生させ、
生成されたリストB1の選択値が、A2のvalueChangeListenerの際に
B1の選択値がnull値となってしまい"selected"状態を保てないのです。
(逆の場合も同じ事象でした)


以前のスレッドにも書きましたが,Update Model Valuesフェーズの後で,
一部のビーンの値は更新され,一部は更新されないということはありえません.
考えられるのは,
・B1の値としてnullが入力されたものとして処理された
・ビーンの値がnullに初期化されていて,かつB1の入力値がリクエストパラメタとして
 送られていないか,更新されていない

リクエストパラメタとして何か来ているか確認して下さい.
それと,ビーンのスコープがrequestになっていませんか?

引用:

2回目以降、valueChangeListenerが両方とも起動してしまう
(A1を変更させても、A1のvalueChangeListenerの起動後に
A2のvalueChangeListenerが起動します)
個別に動くものとばかり思っておりましたので、今まで気づきませんでした。
原因として何が考えられるでしょうか。


「フェーズをUPDATE_MODEL_VALUESへ変更」はやった上での話でしょうか?
immediate="true"のままでそうする意味はないと思いますが.
henachoco
常連さん
会議室デビュー日: 2005/11/21
投稿数: 29
お住まい・勤務地: 新ハンドル:t_yamo
投稿日時: 2006-02-14 13:52
なんだかEvent/Listenerの機構にひっぱられてトリッキーな方向に向かっているような気がします。
他のスレッドでも記しましたが、当該リストボックスを生成するgetterでハンドリングしてあげるとすっきりすると思います。
コード:
public List getCodeListB1() {
  return changeCodeListB1(codeA1);
}


これの肝は、当該画面の再描画を行なう際に「#{bean.codeListB1}」で毎回「getCodeListB1()」が呼ばれるということです。
ValueChangeListenerの機構を使わなくてもgetterで状況に応じた値を返すことができますし、必要であればキャッシュを使ってある程度の効率化を図ることもできます。
何より構造がシンプルになりますし、モデルとの同期も簡単に取れます。

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=27658&forum=12&start=8
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-02-15 22:06
引用:

henachocoさんの書き込み (2006-02-14 13:52) より:
なんだかEvent/Listenerの機構にひっぱられてトリッキーな方向に向かっているような気がします。
他のスレッドでも記しましたが、当該リストボックスを生成するgetterでハンドリングしてあげるとすっきりすると思います。


賛成です.
A1,A2のsetterの方で処理する手もありますね.
いずれにしてもValueChangeListenerにはうかつに手を出さない方がやっぱり良さそうです.

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