SeamのRichFacesで最も便利な機能ModalPanel。
これを使いたくてSeamを使ってると言っても良いかも。
ただし、便利に使うには少々コツが必要。意外にリソースが少なかったりするからメモっておく。
普通に上位10件程度の履歴などを見せる場合には、特にコツもなく以下のようなコードで出来る。
パネルを開く
<h:outputLink value=”#” id=”show_link”>
<h:graphicImage url=”img/historys-mini.gif” alt=”履歴” border=”0″ />
<rich:componentControl for=”history_panel” attachTo=”show_link” operation=”show” event=”onclick” />
<a4j:support event=”onclick” actionListener=”#{orderEntryAction.getHistorys(row)}” reRender=”hispanel” />
</h:outputLink>
パネル部分
<rich:modalPanel id=”history_panel” width=”550″ height=”400″>
<f:facet name=”header”>
<h:panelGroup>
<h:outputText value=”購買履歴(最近の10件):” />
</h:panelGroup>
</f:facet>
<f:facet name=”controls”>
<h:panelGroup>
<h:graphicImage value=”img/wclose.png” style=”cursor:pointer” id=”hidelink”/>
<rich:componentControl for=”history_panel” attachTo=”hidelink” operation=”hide” event=”onclick” />
</h:panelGroup>
</f:facet>
<rich:dataTable id=”hispanel” var=”sublists” value=”#{orderHistoryLists}” border=”0″ cellpadding=”0″ cellspacing=”0″ rowKeyVar=”subrow”>
<rich:column styleClass=”cell_no”>
<f:facet name=”header”>
<h:outputText value=”No:” />
</f:facet>
<h:outputText value=”#{subrow+1}” />
</rich:column>
<rich:column>
<f:facet name=”header”>
<h:outputText value=”年月日:” />
</f:facet>
<h:outputText value=”#{sublists.orders.bdate}”>
<s:convertDateTime pattern=”yyyy/MM/dd HH:mm” />
</h:outputText>
</rich:column>
<rich:column styleClass=”cell_number”>
<f:facet name=”header”>
<h:outputText value=”数量:” />
</f:facet>
<h:outputText value=”#{sublists.num}” />
</rich:column>
<rich:column>
<f:facet name=”header”>
<h:outputText value=”金額:” />
</f:facet>
<h:outputText value=”#{sublists.price}” />
</rich:column>
</rich:dataTable>
</rich:modalPanel>
特に難しくもなく、RichFacesのマニュアル通りに書けば普通に動く。
rich:modalPanelのコードは、どこに書いてもOKなので、ページの頭にでも書いておけばOK。
ただし、ModalPanelの中でフォームを使って検索などをしたい場合には書き方が変わる。
例えば、メインでリンクをクリック->モーダルオープン->商品や顧客などを検索->検索結果をメインにセット等という業務システムではあるととても助かる機能を実装したい場合、上記の方法だと何故かフォームの変数がSessionBeanに渡らない。
なので以下のように書く
パネルを開く
(上記といっしょ。省略)
パネル部分
<ui:include src=”ItemsearchPanel.xhtml” />
として別のfaceletファイルを読み込む。ui:includeは必ずa4j:formの外側で行う。何故ならItemsearchPanelの中でもa4j:formを使うから。
そしてItemsearchPanelActionクラスを作成(無論インターフェースも)。
@Stateful
@Name(“itemsearchPanelAction”)
public class ItemsearchPanelAction implements Serializable, IItemsearchPanel {
@PersistenceContext(type = EXTENDED)
private EntityManager em;
@In(required = false)
private String searchcd;
@In(required = false)
private String searchname;
@DataModel(value = “searchItemLists”)
private List<Item> searchItemLists;
@Out(required = false)
private Item item;
@In
private FacesMessages facesMessages;
@In
private Events events;
@Logger
private Log log;
Query query;
@Remove
@Destroy
public void destroy() {
}
public void searchItem() {
try {
if(searchcd.equals(“”)) {
query = em.createQuery(“SELECT i FROM Item AS i WHERE :searchname IS NULL OR (i.nameja LIKE :searchname OR i.namekana LIKE :searchname OR i.modelname LIKE :searchname OR i.modelkana LIKE :searchname OR i.makername LIKE :searchname OR i.standards LIKE :searchname )”);
query.setParameter(“searchname”,getSearchPattern(searchname));
} else {
query = em.createQuery(“SELECT i FROM Item AS i WHERE i.item = :searchcd”);
query.setParameter(“searchcd”,Long.parseLong(searchcd));
}
query.setFirstResult(0);
query.setMaxResults(8);
searchItemLists = query.getResultList();
} catch(NoResultException ex) {
facesMessages.add(“商品がありません”);
}
}
public String getSearchPattern(String word) { return word == null ? “%” : ‘%’ + word.toLowerCase().replace(‘*’, ‘%’) + ‘%’;
}
}
view部分
<ui:composition xmlns=”http://www.w3.org/1999/xhtml”
xmlns:s=”http://jboss.com/products/seam/taglib”
xmlns:ui=”http://java.sun.com/jsf/facelets”
xmlns:f=”http://java.sun.com/jsf/core”
xmlns:c=”http://java.sun.com/jsp/jstl/core”
xmlns:h=”http://java.sun.com/jsf/html”
xmlns:a4j=”http://richfaces.org/a4j”
xmlns:rich=”http://richfaces.org/rich”
template=”layout/template3.xhtml”>
<ui:component>
<rich:modalPanel id=”search_panel” width=”550″ height=”400″>
<f:facet name=”header”>
<h:panelGroup>
<h:outputText value=”商品の検索:” />
</h:panelGroup>
</f:facet>
<f:facet name=”controls”>
<h:panelGroup>
<h:graphicImage value=”img/wclose.png” style=”cursor:pointer” id=”search_hide” />
<rich:componentControl for=”search_panel” attachTo=”search_hide” operation=”hide” event=”onclick” />
</h:panelGroup>
</f:facet>
<a4j:form ajaxSubmit=”true”>
<h:panelGrid border=”0″ columns=”5″>
<h:panelGroup>
<h:outputLabel value=”商品コード:” />
</h:panelGroup>
<h:panelGroup>
<h:inputText value=”#{searchcd}” size=”5″ maxlength=”255″ style=”ime-mode:disabled;” />
</h:panelGroup>
<h:panelGroup>
<h:outputLabel value=”キーワード:” />
</h:panelGroup>
<h:panelGroup>
<h:inputText value=”#{searchname}” size=”30″ maxlength=”255″ />
<br />
<h:outputText value=”注)品名、型式、メーカー、サイズ/仕様であいまい検索” />
</h:panelGroup>
<h:panelGroup>
<a4j:commandButton value=”検索” actionListener=”#{itemsearchPanelAction.searchItem}” reRender=”slists” styleClass=”button_class” />
</h:panelGroup>
</h:panelGrid>
<rich:dataTable id=”slists” var=”slists” value=”#{searchItemLists}” border=”0″ cellpadding=”0″ cellspacing=”0″ rowKeyVar=”srow”>
<rich:column styleClass=”cell_no”>
<f:facet name=”header”>
<h:outputText value=”No:” />
</f:facet>
<h:outputText value=”#{srow+1}” />
</rich:column>
<rich:column>
<f:facet name=”header”>
<h:outputText value=”商品名:” />
</f:facet>
<h:outputText value=”#{slists.nameja}” />
</rich:column>
<rich:column>
<f:facet name=”header”>
<h:outputText value=”型番:” />
</f:facet>
<h:outputText value=”#{slists.modelname}” />
</rich:column>
<rich:column styleClass=”cell_center”>
<f:facet name=”header”>
<h:outputText value=”設定:” />
</f:facet>
<a4j:commandButton value=”設定” actionListener=”#{orderEntryAction.getItem(comming,slists)}” reRender=”main” id=”search_set” styleClass=”button_class” />
<rich:componentControl for=”search_panel” attachTo=”search_set” operation=”hide” event=”onclick” />
</rich:column>
</rich:dataTable>
</a4j:form>
</rich:modalPanel>
</ui:component>
</ui:composition>
ここまで来ればすぐ実装出来るはずだけど、a4j:formをつい忘れてしまうので要注意かな。
昨今はブラウザ側がポップアップブロックを標準装備しててJavaScriptのwindow.open()も使えないから、これは必須の機能だね。
もう気に入っちゃってガンガン多投してるけど、凄く表現力上がるし客受けも良い。
こういうのをパッと出来ちゃう所がseamの便利なところだなぁ。