質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

JSFカスタムコンポーネントを複数宣言して、それぞれをManagedBeanとデータ連携したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,125

mno

score 34

JSF2.2で、カスタムコンポーネントを実装しています。
年月日をそれぞれプルダウンリストで表示/入力させ、エラーチェックを行います。
プルダウンリストの先頭にブランク行を入れる/入れないを、カスタムタグの
プロパティで指定します。
以下のような構成で実装しました。
(説明のため一部抜粋のみです)


postAddToViewイベントを使用して、ManagedBeanとプロパティを共有します。
また、postValidateイベントで、ManagedBean側でバリデーションを行います。

この構成の場合、カスタムタグが1行(個別画面.xhtmlのdateFromのみ)の場合、
正常にプロパティの共有とバリデーションが行なえます。

しかし、カスタムタグが2行(dateFromとdateTo)の場合、上記イベントが
1回ずつしか発生せず、dateTo側の処理が正常に行われません。


これの解決策として、個別画面側に、f:eventを複数回直接書いてやる方法があります。
しかし、これではカスタムタグの意味があまりありません。

どなたか、よい解決策などありませんでしょうか?

dateSelect.xhtml (カスタムコンポーネントのビュー実体)

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:c="http://java.sun.com/jsp/jstl/core">

<f:event listener="#{dateMBean.valid}" type="postValidate" />
<f:event listener="#{dateMBean.postAddToView}" type="postAddToView" />
<c:set target="#{dateMBean}" property="idvalue" value="#{id}" />

<h:selectOneMenu id="#{id}_year" value="#{dateMBean.year}">
 <f:selectItems
     value="#{dateMBean.optionYear}"/>
</h:selectOneMenu>
<h:outputLabel id="#{id}_enableValidate" value="#{dateMBean.enableValidate}" style="display:none;" />
<h:outputLabel  id="#{id}_blank" value="#{blank}" style="display:none;" />
</html>

カスタムコンポーネント用のManagedBean

@ManagedBean
@Named
@ViewScoped
@Getter
@Setter
public class DateMBean {

    private String idvalue;
    private String label;
    private Boolean blankOption;
    private Date value;
    private Boolean enableValidate;
    private String year;

    @PostConstruct
    public void init() {
        property = "";
        value = null;

    }

    public void valid(ComponentSystemEvent e) {
        // バリデータ
    }

    public void postAddToView(ComponentSystemEvent e) {
        UIComponent component = e.getComponent();
        String id = getId();
        HtmlOutputLabel blankData = (HtmlOutputLabel)component.findComponent(id + "_blank");
        String blankVal = (String)blankData.getValue();
        if(!StringUtil.isNullOrEmpty(blankVal)) {
            blankVal = blankVal.toUpperCase();
            if("ON".equals(blankVal)) {
                blankOption = true;
            }else{
                blankOption = false;
            }
        }
    }

    public List<String> getOptionYear() {
        List<String> result = new ArrayList<String>();
        // 配列を返す
        return result;
    }
}

個別画面.xhtml(カスタムタグを記載します)

<h:form rendered="false">
<h:commandButton action="#{inputMBean.move}" value="処理"></h:commandButton>
    <htmlx:dateselect id="dateFrom" dateMBean="#{inputMBean.datebean}" blank="on" />
    <htmlx:dateselect id="dateTo" dateMBean="#{inputMBean.datebean2}" blank="on" />
</h:form>


その他、web.xmlにtaglib.xmlの記載を追記、taglib.xmlにdateSelect.xmlの記載を追記しています。


解決案 個別画面.xhtml(カスタムタグを記載します)

<h:form rendered="false">
<h:commandButton action="#{inputMBean.move}" value="処理"></h:commandButton>

<f:event listener="#{inputMBean.datebean.postAddToView}" type="postAddToView"><c:set target="#{inputMBean.datebean}" property="idvalue" value="#{id}" /></f:event>
<f:event listener="#{inputMBean.datebean2.postAddToView}" type="postAddToView"><c:set target="#{inputMBean.datebean2}" property="idvalue" value="#{id}" /></f:event>

    <htmlx:dateselect id="dateFrom" dateMBean="#{inputMBean.datebean}" blank="on" />
    <htmlx:dateselect id="dateTo" dateMBean="#{inputMBean.datebean2}" blank="on" />
</h:form>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

カスタムタグを作ったことを有りませんので確信は無いのですが、恐らく特定のBeanとマップさせるのは無理ではないかと思います。Beanがないと動かないタグとなりますよね?

対案としては共有ページとして作成し、ui:includeタグを使って読み込む方法ではどうでしょうか。

また、手前みそになりますが別ページをダイアログとして表示させて入力値を引き継ぐ方法です。
JSF PrimeFaces Dialogの入力結果をFormに反映する

ご参考までに。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/06 12:13

    ありがとうございます。
    ご提案いただいた方法を試してもうまく動かなかったのですが、
    解決案 個別画面.xhtmlで良いことになったためクローズします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る