Eclipse+JSF+JPAで作るアプリ(15)―Primefaces データテーブルの設定 後半(2) コンテキストメニュー
Primefacesのデータテーブルタグ(p:datatable)の設定を色々と変えて動作を確認を行うセッションの後半その2です。
- コンテキストメニューを表示する。
- セルをグリッドで編集できるようにする。
のうち、コンテキストメニューの表示を行えるようにします。
コンテキストメニューはパネルメニューやメニューバー同様、とても簡単に作れます。
p:dialogを使った埋め込みダイアログ
コンテキストメニューの設定
表示したいデータテーブルのid(下記例では"userList")に対して、p:contextMenuタグのforアトリビュートで指定するだけです。
下記例では<p:contextMenu for="userList">です。
userlist.xml
<p:dataTable id="userList" … </p:dataTable> <p:contextMenu for="userList"> <p:menuitem value="パスワードの編集" icon="ui-icon-pencil" update="dialog" oncomplete="PF('passwordDialog').show()"> <f:setPropertyActionListener value="#{editUserView.selectedUsers[0].password}" target="#{editUserView.newPassword}"/> </p:menuitem> </p:contextMenu>
埋め込みダイアログの作成
パスワード表示メニューから、管理者にパスワードを入力させるためのダイアログを表示します。
PrimefacesのShowcaseに似たような例があります。
<h:form id="userListForm"> … </h:form> <p:dialog id="dialog" header="パスワードの編集" widgetVar="passwordDialog" modal="true" showEffect="fold" hideEffect="explode" resizable="false" dynamic="true"> <h:form id="dialogForm"> <p:outputPanel id="passwordEdit" style="text-align:center;"> <p:panelGrid columns="2"> <f:facet name="header"> <p:outputLabel value="#{editUserView.selectedUsers[0].name.concat('のパスワード変更')}" /> </f:facet> <p:outputLabel value="パスワード" /> <p:password value="#{editUserView.newPassword}" redisplay="true" /> <p:outputLabel value="見えるパスワード" /> <p:inputText value="#{editUserView.newPassword}" /> </p:panelGrid> <p:commandButton value="OK" icon="ui-icon-check" action="#{editUserView.updatePassword}" oncomplete="PF('passwordDialog').hide()" /> <p:commandButton value="キャンセル" icon="ui-icon-close" oncomplete="PF('passwordDialog').hide()" /> </p:outputPanel> </h:form> </p:dialog>
p:dialogタグでは
- widgetVar="passwordDialog"が、PF('xxx').show(), PF('xxx').hide()で渡すIDになります。
- modal="true"でモーダルダイアログになります。
- dynamic="true"でフォームがロードされた際に遅延ロードされるようになります。
後はほかのフォームと同じです。注目したい点は
- p:outputLabelタグのvalue="#{editUserView.selectedUsers[0].name.concat('のパスワード変更')}"で、EL式の文字列を連結しています。
- p:passwordタグの redisplay="true" でパスワードの初期値を設定しています。(後述)
- p:commandButtonタグのoncomplete="PF('passwordDialog').hide()"を呼ばないと当然ながらダイアログが消えません。
EditUserView.javaの変更点
特に大きな変更点はありません。
@Getter @Setter private String newPassword; … public String updatePassword() { if( selectedUsers == null || selectedUsers.isEmpty() ) return "success"; User user = selectedUsers.get(0); if( newPassword.equals(user.getPassword())) return "success";//同じなら更新しない。 user.setPassword(newPassword); UserManager.updateUser(user); ViewUtil.AddMessage("パスワードの変更", user.getName()+"のパスワードを変更しました。"); return "success"; }
ダイアログの値のアップデート
p:menuitemで、update="dialog"を指定しなければ、値は更新されません。
また、はまった点として、ダイアログのコントロールにパスワードを使用していたため、editUserView.newPasswordの値が空に見え、ManagedBeanが更新されていないかのように振る舞っていました。inputSecretには、redisplayを付けない限り、クリアされるのを忘れていました。
ダイアログで表示しているnewPasswordの値のアップデート方法は、いくつか方法があります。
- actionListenerでnewPasswordを設定する方法。
- 本例のように、setPropertyActionListenerを使う方法。
- actionで更新してしまう方法。
1番目はjavaのコーディングが発生します。3番目は画面遷移を伴わないですから使用すべきではないです。
結果として、2番のsetPropertyActionListenerを使用して更新しています。
右クリックで行が選択されるが、削除ボタンが有効にならない。
次のajaxでイベントを拾ってあげます。
<p:dataTable id="userList" … > <p:ajax event="contextMenu" update=":userListForm:removeButton" /> … </p:dataTable>
さて、次はグリッド編集(cellEditorとrowEditorの使用方法)です。