Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

PrimeFacesで複数画面から呼び出されるダイアログを共通化するには?

今日の記事は自分自身、色々と試行錯誤してやっているものなので、もしかしたら正攻法ではないかもしれません(^^;あくまでも参考程度と思って頂けると幸いです。

……

PrimeFacesのダイアログは非常に簡単に使えます。
実際どのようなダイアログか、Showcaseは以下にあります。

PrimeFaces ダイアログのshowcase

単純なダイアログサンプル

よくあるサンプルはJSFxhtmlで以下のように書くものです。

<?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>PrimeFacesのダイアログサンプル</title>
    </h:head>
    <h:body>
        <h:form id="dlgSampleFrm">
            
            <!-- ダイアログ表示ボタン -->
            <p:commandButton value="ダイアログ表示" onclick="sampleDlg.show();" />
            
            <!-- ダイアログ -->
            <p:dialog id="dlg" widgetVar="sampleDlg" modal="true" header="いえーいダイアログだぜー">
            </p:dialog>
            
        </h:form>
    </h:body>
</html>

実行すると以下のようなページが表示されて
f:id:kikutaro777:20130314233232j:plain
ボタンを押すと
f:id:kikutaro777:20130314233253j:plain
ダイアログがでます。ちなみに上図はキャプチャの都合上、ダイアログ位置をマウスで移動させていますが、特に指定なく使えばブラウザ中央に表示されます。

OKダイアログとかYes/Noダイアログとかシンプルなものはこれでも十分ですが、業務系によくあるような「XX検索ダイアログ」とか「YY選択ダイアログ」とか、そういったものになると、色々な画面から同じダイアログを呼び出したくなります。

しかし上記の書き方をしてしまうと、各呼出し元ページで同じダイアログの宣言を記述しなければならず、非効率です。

ダイアログを共通化するには…?

共通化に関して色々方法はあると思いますが、私は以下の情報を参考にしました。

How to include another XHTML in XHTML using JSF 2.0 Facelets?

タイトルの通り、xhtmlからxhtmlをincludeする、やりかたです。

これによって、ダイアログを定義した単独のxhtmlを、利用する画面がincludeする、ことを実現しています。

ダイアログのxhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    
    <!-- ダイアログ -->
    <p:dialog id="commonDlg" widgetVar="commonDlg" modal="true" header="共通で使えるダイアログだぜー">
    </p:dialog>
</ui:composition>

とだけ定義して、呼出し側のページは

<?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:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>PrimeFacesのダイアログ呼出しサンプル</title>
    </h:head>
    <h:body>
        <h:form id="dlgCallSampleFrm">
            
            <p:commandButton id="callCommonDlgBtn" value="共通ダイアログ呼ぶ" onclick="commonDlg.show();" />
            
            <!-- 共通ダイアログをインクルード -->
            <ui:include src="commonDialog.xhtml" />
        </h:form>
    </h:body>
</html>

のようにダイアログのxhtmlをincludeします。

実行すると
f:id:kikutaro777:20130314233557j:plain
f:id:kikutaro777:20130314233607j:plain
と表示されます。

一見、最初の例と同じですが、ダイアログのxhtmlが個別ファイルになっているため、複数画面から簡単に呼び出すことが可能です。

ただ、呼出し元画面への値の受け渡し等、少々工夫もいる部分もあったりするので、そのあたりはまた機会をみてまとめたいと思います。

ハマったこと

ちなみに、当初うまく実現できずにハマったケースとしては、括りだしたダイアログのxhtmlでhtmlタグやhead、bodyタグを定義してしまった、というのがあります(^^;
こうした形でincludeしてしまうと、生成されるHTMLは複数のhead、bodyタグを持ってしまいます。
以下のQAにもあるように
Multiple html body /html /body in same file
1つのHTMLファイルが複数のやタグを持つのは推奨されず、一見正常に動くのですが、ブラウザによっては駄目にもなるし、そもそもhtmlのお作法としてもアウトなようなので注意が必要かと思います(^^;

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村