LoginSignup
14
9

More than 5 years have passed since last update.

JSF PrimeFaces Dialogの入力結果をFormに反映する

Posted at

はじめに

JSFプログラミングにてFormからDialogをポップアップさせて、Dialog上のコンボボックス(selectOneMenu)の選択結果を元のフォームに反映させる方法の紹介です。
JavaEE上の開発になりますが、アプリケーションサーバにGlassFish、DialogのライブラリにPrimeFacesを使用しています。IDEはnetbeansを使っています。
NetBeansインストール方法はこちらを参照ください。
Projectの作成、PrimeFaces設定方法はこちらを参照下さい。
JavaEEの入門にはこちらがおススメです。

選択ボタンをクリックするとチーム一覧が表示され、任意チームのselectボタンをクリックすると一覧画面が閉じてフォームに入力される画面を作ってみました。

image

環境

NetBeans 8.0.2
JavaSDK 1.8.0.25
PrimeFaces 5.0
GlassFish 4.1

configファイル追加

PrimeFacesのマニュアルに記載されていますが、DialogFrameworkを有効とするためfaces-config.xmlファイルをWEB-INFフォルダに作成します。そして以下のエントリを追加します。

faces-config.xml
    <application>
        <action-listener>org.primefaces.application.DialogActionListener</action-listener>
        <navigation-handler>org.primefaces.application.DialogNavigationHandler</navigation-handler>
        <view-handler>org.primefaces.application.DialogViewHandler</view-handler>
    </application>

Dialogの表示

PrimeFacesのDialogFrameworkを利用すれば、作成したJSF画面をDialogとして表示することができます。BackingBeanではDialogとして表示したいJSFページをopenDialogメソッドの引数に指定します。

public void viewTeams() {
 RequestContext.getCurrentInstance().openDialog("viewTeams");
}

Dialogの親フォームではcommandButtonのリスナーにメソッドを指定し、ButtonClickの契機でDialogを表示させます。

<p:commandButton value="選択" actionListener="#{bb.viewTeams()}" />

Dialogの入力結果取得

dataTableの選択イベントにて、DialogFrameworkのcloseDialogメソッドを呼ぶことでDiaolgのクローズと親フォームへの選択結果渡しが同時にできます。

public void selectTeamFromDialog(String teams) {
        RequestContext.getCurrentInstance().closeDialog(teams);
}

親フォームではDialog選択結果を受け取るため、ajaxタグを使用してdialogReturnイベントをフックします。選択結果はBackingBeanのメンバに格納するためlistenerを指定します。また、メンバの内容を表示するinputTextのidをupdateに指定します

        <p:commandButton value="選択" actionListener="#{bb.viewTeams()}" >
            <p:ajax event="dialogReturn" listener="#{bb.handleReturn}" 
                     update="inputTeam" />
        </p:commandButton>

BackingBeanではSelectEvent型の引数から選択結果を取得します。

 public void handleReturn(SelectEvent event) {
        team = (String) event.getObject();

 }

プログラムコード

JSF

ファイル名 説明
index.xhtml 親Formのページ
viewTeams.xhtml Dialogとして表示されるページ
index.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:p="http://primefaces.org/ui">

    <h:head>
        <title>favorite team</title>
    </h:head>
    <h:body>

        <h:form id="form1">
        好きなチームは?
        <h:inputText id="inputTeam" value="#{bb.team}" />
        <p:commandButton value="選択" actionListener="#{bb.viewTeams()}" >
            <p:ajax event="dialogReturn" listener="#{bb.handleReturn}" update="inputTeam" />
        </p:commandButton>           
        </h:form>

    </h:body>

</html>
viewTeams.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://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Teams</title>
        <style type="text/css">
            .ui-widget {
                font-size: 90%;
            }
        </style>
    </h:head>
    <h:body>
        <h:form>
            <p:selectOneMenu value="#{teamList.league}">
                <f:selectItem itemValue="セリーグ" itemLabel="セリーグ" />
                <f:selectItem itemValue="パリーグ" itemLabel="パリーグ" />
                <p:ajax event="change" update="teamTable" />             
            </p:selectOneMenu>    

            <p:dataTable id="teamTable" var="team" value="#{teamList.teams}" style="width:200px">
                <p:column headerText="チーム" style="width:50px;text-align: center">
                    <h:outputText value="#{team}" />
                </p:column>
                <p:column headerText="select" style="width:32px;text-align: center">
                    <p:commandButton icon="ui-icon-search"
                                 actionListener="#{bb.selectTeamFromDialog(team)}" />
                </p:column>            
            </p:dataTable>
        </h:form>
    </h:body>
</html>

Java

ファイル名 説明
Bb.java 親FormとDialogのBackingBean
TeamList.java DialogのdataList用メンバを生成して保持する
Bb.java
package beans;

import java.util.*;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;

@Named()
@RequestScoped
public class Bb {

    String team;

    public void viewTeams() {
        Map<String,Object> options = new HashMap<>();
        options.put("width", 250);
        RequestContext.getCurrentInstance().openDialog("viewTeams",options,null);
    }

    public void selectTeamFromDialog(String teams) {
        RequestContext.getCurrentInstance().closeDialog(teams);
    }

    public void handleReturn(SelectEvent event) {
        team = (String) event.getObject();

    }

    public void selectTeam(String team) {
        this.team=team;
    }

    public String getTeam() {
        return team;
    }

    public void setTeam(String team) {
        this.team = team;
    }

}
TeamList.java
package beans;

import java.util.*;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class TeamList {

    private List<String> teams=new ArrayList();
    private String league;

    @PostConstruct
    public void init(){
        league="セリーグ";
        changeLeague();     
    }

    public List<String> getTeams() {
        return teams;
    }

    public void setTeams(List<String> teams) {
        this.teams = teams;
    }

    public String getLeague() {
        return league;
    }

    public void setLeague(String league) {
        this.league = league;
        changeLeague();
    }


    public void changeLeague() {

        if(league == null)return;

        if(league.equals("セリーグ") ){
            teams=new ArrayList();
            teams.add("スワローズ");
            teams.add("ジャイアンツ");
            teams.add("タイガース");
            teams.add("カープ");
            teams.add("ドラゴンズ");
            teams.add("ディーエヌエー");          
        } else{
            teams=new ArrayList();
            teams.add("ホークス");
            teams.add("ファイターズ");
            teams.add("マリーンズ");
            teams.add("オリックス");
            teams.add("ライオンズ");
            teams.add("ゴールデンイーグルス");
        }

    }    
}

Poolから使用済みのbeanが割り当てられる可能性があるので、PostConstructアノテーションを指定したinitメソッドで初期化を行っています。

終わりに

簡単な画面制御と値の受け渡しでしたが、javascriptを使うことなくコード作成出来ました。フレームワークではタグライブラリなど使用するとjavascriptを自動生成するケースが有るので、直接javascriptを書く場合はフレームワークとの連携が難しい場合が有りました。javascriptで書いていた部分をPrimeFacesがフォローする分、スッキリとしたコードになりました。

14
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
9