原文:开发基于JBoss AS 7.2.0的Java EE程序 - 07.翻页
英文:JBoss AS 7.2.0 - Java EE application development - 07.EJB and JSF Pagination framework
概述
任何网站在显示大量的记录的时候,总是采用分页显示,本站 http://javaarm.com 也不例外。我们在本章描述的是 http://javaarm.com 的万能分页框架,它代码量小,但是很灵活、方便,本站的所有翻页显示,都是用该分页框架做的。
这个框架花费了我很多的心血,希望对大家有用。
1. EJB 分页查询框架
1.1 ICriteria.java
这是通用查询条件顶层接口
public interface ICriteria {
}
1.2 XTwoParametersCondition.java
这是带2个参数的查询条件
import java.io.Serializable;public class XTwoParametersCondition implements ICriteria,Serializable {
private static final long serialVersionUID = 1L;
public final String attributeName;
public final XCompareOperator compareOperator;
public final Object value;
public XTwoParametersCondition(String attributeName,XCompareOperator compareOperator, Object value){
this.attributeName = attributeName;
this.compareOperator = compareOperator;
this.value = value;
}
}
1.3 XCompareOperator.java
这是比较类型,用于定义各种比较算子 对应 SQL/JPQL 里面比较符号。
import java.io.Serializable;public class XCompareOperator implements Serializable {
private static final long serialVersionUID = 1L;
//
public static final XCompareOperator eq = new XCompareOperator("eq","=");
public static final XCompareOperator ne = new XCompareOperator("ne","<>");//"!=" is OK too!
public static final XCompareOperator lt = new XCompareOperator("eq","<");
public static final XCompareOperator le = new XCompareOperator("eq","<=");
public static final XCompareOperator gt = new XCompareOperator("eq",">");
public static final XCompareOperator ge = new XCompareOperator("eq",">=");
public static final XCompareOperator like = new XCompareOperator("like","like");
public final String sqlSymbol;
public final String jpqlSymbol;
public XCompareOperator(String sqlSymbol, String jpqlSymbol){
this.sqlSymbol = sqlSymbol;
this.jpqlSymbol = jpqlSymbol;
}
}
1.4 XOrder.java
这是排序类型。
import java.io.Serializable;public class XOrder implements Serializable{
private static final long serialVersionUID = 1L;
public final String attributeName;//参与排序的属性的名字
public final boolean asc;//升序
public XOrder(String attributeName,boolean asc){
this.attributeName = attributeName;
this.asc = asc;
}
}
1.5 XPager.java
这是分页信息存储器
import java.io.Serializable;
import java.util.List;public class XPager implements Serializable {
private static final long serialVersionUID = 1L;
public static final int DEFAULT_PAGESIZE = 50;//50
public static final int MINIMUM_PAGESIZE = 10;
public static final int MAXIMUM_PAGESIZE = 100;
public static final int MAX_PAGESIZE = 300;
public static final int PAGENUM_START = 1;
public static final String CRITERIA_FLAG = "?";
public int pageSize = DEFAULT_PAGESIZE;//翻页 size
public int pageNum = PAGENUM_START;//从1开始; 要获取的某页的数据
public String wherePattern;//格式:((?)AND(?)) OR ?
public List<ICriteria> conditionList;//查询条件约束列表,依次替代wherePattern中的 '?'
//
public List<XOrder> orderby;
}
1.6 QueryResult.java
这是分页结果信息存储器。
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class QueryResult implements Serializable {
private static final long serialVersionUID = 1L;
public int pageSize = XPager.DEFAULT_PAGESIZE;//翻页 size
public int pageNum = XPager.PAGENUM_START;//从1开始; 要获取的某页的数据
//
public int totalRecords = 0;//返回给用户
public int totalPages = XPager.PAGENUM_START;//返回给用户
@SuppressWarnings("rawtypes")
public List records = new ArrayList();//默认空列表
}
1.7 PagerHelper.java
这是最关键的分页辅助类!
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.Query;import org.jboss.logging.Logger;
public class PagerHelper {
public static final Logger log = Logger.getLogger(PagerHelper.class);
@SuppressWarnings("rawtypes")
public static final QueryResult getResult(Class clz, EntityManager em, XPager pager){
QueryResult queryResult = new QueryResult();
try{
/*************************************[预处理]*************************************/
if(pager.pageNum<1){
pager.pageNum = XPager.PAGENUM_START;
}if(pager.pageSize<XPager.MINIMUM_PAGESIZE || pager.pageSize>XPager.MAXIMUM_PAGESIZE){
pager.pageSize = XPager.DEFAULT_PAGESIZE;
}
//
queryResult.pageNum = pager.pageNum;
queryResult.pageSize = pager.pageSize;
/*************************************[求总记录数]*************************************/
HashMap<String,Object> parameterNameValuePairs = new HashMap<String,Object>();
final String whereJpql = getWhereJpql(pager,parameterNameValuePairs).trim();
final String orderbyJpql = getOrderbyJpql(pager).trim();
final String countJpql = "SELECT COUNT(*) FROM "+ clz.getName()+" obj "+(whereJpql.equals("")?" ":" WHERE "+whereJpql);
final String queryJpql = "SELECT obj FROM "+ clz.getName()+" obj "
+(whereJpql.equals("")?" ":" WHERE "+whereJpql)
+(orderbyJpql.equals("")?" ":" ORDER BY "+orderbyJpql);
/*************************************[求总记录数]*************************************/
int totalRecords = 0;
try{
//
Query whereQuery = em.createQuery(countJpql);
Iterator<String> it = parameterNameValuePairs.keySet().iterator();
while(it.hasNext()){
String parameterName = it.next();
Object parameterValue = parameterNameValuePairs.get(parameterName);
whereQuery.setParameter(parameterName, parameterValue);
}
totalRecords = Integer.parseInt(whereQuery.getSingleResult().toString());
}catch(Exception e){
log.error(e);
}
queryResult.totalRecords = totalRecords;
/*************************************[分页]*************************************/
int remain = totalRecords % pager.pageSize;
int totalPages = totalRecords / pager.pageSize + (remain==0?0:1);
if(totalPages==0){//总记录为0 时,到这里可能依旧为0.
totalPages=1;
}
queryResult.totalPages = totalPages;
//
if(pager.pageNum>totalPages){
pager.pageNum = totalPages;
queryResult.pageNum = totalPages;
}
/*************************************[抓记录]*************************************/
if(totalRecords==0){
queryResult.records = new ArrayList();
}else{
Query query = em.createQuery(queryJpql)
.setFirstResult((pager.pageNum-1)*queryResult.pageSize)
.setMaxResults(queryResult.pageSize);
//
Iterator<String> it = parameterNameValuePairs.keySet().iterator();
while(it.hasNext()){
String parameterName = it.next();
Object parameterValue = parameterNameValuePairs.get(parameterName);
query.setParameter(parameterName, parameterValue);
}
queryResult.records = query.getResultList();
}
}catch(Exception e){
queryResult.records = new ArrayList();
}
return queryResult;
}
public static final String getWhereJpql(XPager pager, HashMap<String,Object> parameterNameValuePairs){
//1. 判定参数是否合法******************************************
if(pager.conditionList==null){
log.debug("pager.conditionList is null");
return "";
}
if(pager.wherePattern==null){
throw new RuntimeException("pager.wherePattern should NOT be null if pager.conditionList is NOT null.");//return "";
}
if(pager.wherePattern.indexOf("?")<0){
//log.debug("pager.wherePattern 不含条件占位符'?'");
throw new RuntimeException("pager.wherePattern contains no '?'.");//return "";
}
int criteriaFlagNum = 0;
String tmp = pager.wherePattern;
while(tmp.indexOf('?')>=0){//该while()仅仅用于计算criteriaFlagNum.
criteriaFlagNum++;
tmp = tmp.replaceFirst("\\?", "");
}
if(criteriaFlagNum!=pager.conditionList.size()){
String msg = "criteriaFlagNum is "+criteriaFlagNum+" and pager.conditionList.size() is "+pager.conditionList.size()+". They are NOT equal!";
log.warn(msg);
System.out.println(msg);
return "";
}
//2. 正式构造*************************************************
String wherePattern = pager.wherePattern;
Iterator<ICriteria> it = pager.conditionList.iterator();
while(it.hasNext()){
ICriteria criteria = it.next();
if(criteria instanceof XTwoParametersCondition){
XTwoParametersCondition c= (XTwoParametersCondition)criteria;
String attributeNameFlag = "_"+c.attributeName.replaceAll("\\.","_");//Example: c.attributeName="user.id"
//
String s = " obj."+c.attributeName+" "+c.compareOperator.jpqlSymbol+" :"+attributeNameFlag;
wherePattern = wherePattern.replaceFirst("\\?", s);
parameterNameValuePairs.put(attributeNameFlag, c.value);
}
}
return wherePattern;
}
public static final String getOrderbyJpql(XPager pager){
if(pager.orderby==null||pager.orderby.size()==0){
return "";
}
//
StringBuilder sb = new StringBuilder();
Iterator<XOrder> it = pager.orderby.iterator();
while(it.hasNext()){
XOrder order = it.next();
sb.append(" obj.").append(order.attributeName).append(" ").append(order.asc?"ASC":"DESC").append(",");
}
String s = sb.toString();
int lastCommaIndex = s.lastIndexOf(",");
return s.substring(0,lastCommaIndex);
}
public static void main(String args[]){
testWhere();
System.out.println("\n\n");
testOrderBy();
}
@SuppressWarnings("serial")
public static void testWhere(){
XPager pager = new XPager();
pager.wherePattern = " (? AND ?) OR (? AND ?) ";
List<ICriteria> lst = new ArrayList<ICriteria>(){
{
add(new XTwoParametersCondition("attribute1",XCompareOperator.eq,"xiang"));
add(new XTwoParametersCondition("attribute2",XCompareOperator.eq,"yingbing"));
add(new XTwoParametersCondition("age",XCompareOperator.ge,30));
add(new XTwoParametersCondition("weight",XCompareOperator.lt,150));
//add(new XTwoParametersCondition("MORE",XCompareOperator.lt,150));//
}
};
pager.conditionList = lst;
System.out.println(getWhereJpql(pager,new HashMap<String,Object>()));
}
@SuppressWarnings("serial")
public static void testOrderBy(){
XPager pager = new XPager();
pager.wherePattern = " (? AND ?) OR (? AND ?) ";
List<XOrder> lst = new ArrayList<XOrder>(){
{
add(new XOrder("name1",true));
add(new XOrder("name2",false));
}
};
pager.orderby = lst;
System.out.println(getOrderbyJpql(pager));
}
}
1.8 EJB Session 使用该EJB查询框架示例
我们以查询 文章主题(Topic) 为例。
(a) 接口
import java.util.List;
import com.ybxiang.forum.ejb.entity.Post;
import com.ybxiang.forum.ejb.entity.Topic;
import com.ybxiang.forum.query.QueryResult;
import com.ybxiang.forum.query.XPager;
public interface ITopicSession {
public QueryResult pageTopic(XPager pager);
}
(b) 实现
package com.ybxiang.forum.ejb.session;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.annotation.security.PermitAll;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.ybxiang.forum.ejb.entity.Topic;
import com.ybxiang.forum.query.PagerHelper;
import com.ybxiang.forum.query.QueryResult;
import com.ybxiang.forum.query.XPager;
@Stateless
@Local(ITopicSession.class)
public class TopicSession implements ITopicSession{
@PersistenceContext()
private EntityManager em;
@PermitAll()
public QueryResult pageTopic(XPager pager){
return PagerHelper.getResult(Topic.class,em, pager);
}
}
EJB这一层,就这些代码,我的设计是不是很简单呢?
2. JSF MBean查询框架
现在,我们来描述,如何在JSF MBean中使用我们的EJB查询框架。
2.1 JSF MBean翻页框架
我们定义了一个JSF MBean翻页框架,供所有的翻页JSF MBean扩展使用。
package com.ybxiang.forum.jsfmbean;
import java.util.List;
import com.ybxiang.forum.query.QueryResult;
import com.ybxiang.forum.query.XPager;
public abstract class AbstractPagerMBean {
protected QueryResult queryResult = null;
/**
* 不对JSF网开放!
*/
protected abstract void paging();
/**
* 查询页面读取page信息:
* (a) 点击“翻页链接”翻页时,从【 网页地址参数】中提取page参数。不从html form中提取!
* (b) 点击“查询按钮”时,从html form中提取page参数。
*/
public final int getPage(){
Integer page =ParameterHelper.getInteger(ParameterHelper.URL_PARAMETER_NAME_PAGE_NUM);
if(page==null){
return XPager.PAGENUM_START;
}
if(page<XPager.PAGENUM_START){
return XPager.PAGENUM_START;
}
return page;
}
/**
* 供查询页面set:<h:inputHidden id="page" value="#{topicGroupingPagerMBean.page}" />
*/
public void setPage(int page){
//什么都不做
}
@SuppressWarnings("rawtypes")
public final List getPagedRecords(){
//synchronized(queryResult) //防止并发执行query()多次!不行!
{
if(queryResult==null){paging();}
return queryResult.records;
}
}
public final int getTotalRecords(){
//synchronized(queryResult) //防止并发执行query()多次!不行!
{
if(queryResult==null){paging();}
return queryResult.totalRecords;
}
}
public final int getTotalPages(){
//synchronized(queryResult) //防止并发执行query()多次!不行!
{
if(queryResult==null){paging();}
return queryResult.totalPages;
}
}
}
2.2 JSF MBean查询举例
我们以查询 文章主题(Topic) 为例。
package com.ybxiang.forum.jsfmbean.topic;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import com.ybxiang.forum.ejb.entity.Menu;
import com.ybxiang.forum.ejb.session.IMenuSession;
import com.ybxiang.forum.ejb.session.ITopicSession;
import com.ybxiang.forum.jsfmbean.AbstractPagerMBean;
import com.ybxiang.forum.jsfmbean.JSFHelper;
import com.ybxiang.forum.jsfmbean.KeywordsHelper;
import com.ybxiang.forum.jsfmbean.ParameterHelper;
import com.ybxiang.forum.query.ICriteria;
import com.ybxiang.forum.query.QueryResult;
import com.ybxiang.forum.query.XCompareOperator;
import com.ybxiang.forum.query.XOrder;
import com.ybxiang.forum.query.XPager;
import com.ybxiang.forum.query.XTwoParametersCondition;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.jfree.util.Log;
@ManagedBean
@RequestScoped
public class TopicGroupingPagerMBean extends AbstractPagerMBean{
static final Logger logger = Logger.getLogger(TopicGroupingPagerMBean.class.getName());
@EJB
private IMenuSession menuSession;
@EJB
private ITopicSession topicSession;
//*****************************************[地址参数]*****************************************//
/**
* public: list.xhtml需要取用
*/
public Long getMid(){
return ParameterHelper.getLong(ParameterHelper.URL_PARAMETER_NAME_MENU_ID);
}
/**
* 供search时,JSF page set!
*/
public void setMid(Long mid){
//什么都不做
}
/**
* 查询页面读取keywords信息:
* (a) 点击“翻页链接”翻页时,从【 网页地址参数】中提取keywords参数。不从html form中提取!
* (b) 点击“查询按钮”时,从html form中提取keywords参数。
*/
public final String getKeywords(){
String keywords = ParameterHelper.getString(ParameterHelper.URL_PARAMETER_NAME_KEYWORDS);
if(keywords==null || keywords.trim().length()==0){
return "";
}
try{
keywords = java.net.URLDecoder.decode(keywords, ParameterHelper.ENCODING);
}catch(Exception e){
Log.error(e);
}
return keywords;
}
/**
* 供查询页面set:<h:inputHidden id="keywords" value="#{topicGroupingPagerMBean.keywords}" />
*/
public void setKeywords(String keywords){
//什么都不做
}
//*****************************************[翻页实现]*****************************************//
/**
* 不对JSF网页开放!
*/
@SuppressWarnings("serial")
protected void paging(){
//
logger.fine("querying...");
if(queryResult!=null){return;}
queryResult = new QueryResult();//作用:下面各种检测不通过时返回空结果集!
//
//获取必要参数***************************************
final Long menuId = getMid();
//参数有效性判定*************************************
if(menuId<1){
return;
}
//菜单是否对外开放******************
Menu menu = menuSession.getMenu(menuId);
if(!menu.isOpen()){//本栏目未开放
logger.warning("该菜单["+menuId+"]未开放,只允许管理员查看!");
if( ! JSFHelper.isCurrentUserAdministrator()){
//logger.warning("该菜单["+menuId+"]未开放;现在查看该菜单的不是管理员,有人试图窃取本菜单下信息!");
return;
}
}
if(menu.isJaasRoleControlled()){//需要该菜单对应的JAAS Role才能访问
if(! JSFHelper.isMenuOpenedToCurrentUser(menu)){
return;
}
}
//待查询的关键字
//SearchCriteriaMBean searchMBean = (SearchCriteriaMBean) JSFHelper.readFromSession(SearchCriteriaMBean.NAME);
//String keywords = searchMBean==null?null:searchMBean.getKeywords4Topic();
String keywords = getKeywords();
//
//构造翻页器*****************************************
XPager pager = new XPager();
pager.pageNum = getPage();
pager.orderby = new ArrayList<XOrder>(){
{
add(new XOrder("sortWeight",false));
}
};
if(keywords==null || keywords.trim().length()==0){
pager.wherePattern = "(?)";
List<ICriteria> lst = new ArrayList<ICriteria>(){
{
add(new XTwoParametersCondition("menuId",XCompareOperator.eq,menuId));
}
};
pager.conditionList = lst;
}else{
final String sqlQueryString = KeywordsHelper.buildSqlQueryString(keywords);
pager.wherePattern = "(?) and (?)";
List<ICriteria> lst = new ArrayList<ICriteria>(){
{
add(new XTwoParametersCondition("menuId",XCompareOperator.eq,menuId));
add(new XTwoParametersCondition("title",XCompareOperator.like,sqlQueryString));
}
};
pager.conditionList = lst;
}
//查询***********************************************
queryResult = topicSession.pageTopic(pager);
}
//*****************************************[界面动作]*****************************************//
//一律转化为URL参数传进来,否则提交参数然后翻页会导致多次查询DB。
}
3. JSF页面分页显示查询结果框架
3.1 翻页组件 - pager.xhml
该翻页组件花费了我很多心血啊!
<?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"><ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<!-- bellow h:panelGroup is a 'div' because its layout is 'block' -->
<h:panelGroup layout="block" style="text-align: right; margin-bottom:10px;">
<h:outputLink disabled="#{page eq 1}" styleClass="marginHor10px"
value="#{fromWebPath}?#{sharedParameterValuePairs}&page=#{1}"><img src="#{request.contextPath}/img/arrow_begin.gif" class="img-nav"/>
</h:outputLink>
<h:outputLink disabled="#{page eq 1}" styleClass="marginHor10px"
value="#{fromWebPath}?#{sharedParameterValuePairs}&page=#{page-1}"><img src="#{request.contextPath}/img/arrow_back.gif" class="img-nav"/>
</h:outputLink>
<h:inputText class="marginLeft10px" maxlength="5" size="2" value="#{page}" onkeydown="if(event.keyCode==13) {var fixedValue=this.value>#{totalPages}?#{totalPages}:this.value;window.location='#{fromWebPath}?#{sharedParameterValuePairs}&page='+fixedValue; doane(event);}"/>
<h:outputLink disabled="#{page eq totalPages}" styleClass="marginHor10px"
value="#{fromWebPath}?#{sharedParameterValuePairs}&page=#{page+1}"><img src="#{request.contextPath}/img/arrow_forward.gif" class="img-nav"/>
</h:outputLink>
<h:outputLink disabled="#{page eq totalPages}" styleClass="marginHor10px"
value="#{fromWebPath}?#{sharedParameterValuePairs}&page=#{totalPages}"><img src="#{request.contextPath}/img/arrow_end.gif" class="img-nav"/>
</h:outputLink>
<h:outputFormat styleClass="marginHor10px" value="#{messages['ybxiang.javaarm.pager.total.records']}" >
<f:param value="#{totalRecords}" />
</h:outputFormat>
<h:outputText value=" " />
<h:outputFormat styleClass="marginHor10px" value="#{messages['ybxiang.javaarm.pager.total.pages']}" >
<f:param value="#{totalPages}" />
</h:outputFormat>
</h:panelGroup>
</ui:composition>
3.2 显示查询记录组件 - displayer_topicList.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"><ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"><h:dataTable style="font-size: 14px;" width="100%"
value="#{topicList}" var="topicItem"
rowClasses="table_odd_row,table_even_row" >
<h:column headerClass="topicList_Title" >
<f:facet name="header">
<h:outputText value="#{messages['ybxiang.javaarm.topic.title']}"/>
</f:facet>
<h:outputLink target="_blank"
rendered="#{topicItem.separator}"
disabled="#{not facesContextMBean.isCurrentUserAdministrator()}"
value="#{request.contextPath}/faces/display.xhtml">
<h:outputText value="♠♠♠♠♠♠"
title="#{topicItem.title}:#{topicItem.sortWeight}" />
<f:param name="tid" value="#{topicItem.id}" />
</h:outputLink>
<h:outputLink target="_blank"
styleClass="linelessLink"
rendered="#{!topicItem.separator}"
value="#{request.contextPath}/faces/display.xhtml">
<h:outputText value="#{topicItem.title}"
title="#{topicItem.sortWeight}" />
<h:graphicImage rendered="#{topicItem.excellent}" value="#{request.contextPath}/img/star.png" width="15" height="15" style="border:0px;" />
<f:param name="tid" value="#{topicItem.id}" />
</h:outputLink>
</h:column>
<h:column headerClass="topicList_Author" >
<f:facet name="header">
<h:outputText value="#{messages['ybxiang.javaarm.author']}"/>
</f:facet>
<h:outputText rendered="#{topicItem.separator}" value="♠" />
<h:outputLink rendered="#{!topicItem.separator}" value="#{request.contextPath}/faces/user.xhtml?uid=#{topicItem.authorId}" target="_blank">
<h:outputText value="#{userCachingMBean.getUserByIdFromCache(topicItem.authorId).username}" />
</h:outputLink>
</h:column>
<h:column headerClass="topicList_Statistics" >
<f:facet name="header">
<h:outputText value="#{messages['ybxiang.javaarm.hitsOfReply']}"/>
</f:facet>
<h:outputText rendered="#{topicItem.separator}" value="♠" />
<h:outputText rendered="#{!topicItem.separator}" value="#{topicItem.hitsOfReply}" />
</h:column>
</h:dataTable></ui:composition>
3.3 查询结果显示页面举例 - list.xhtml
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
template="/template/template.xhtml">
<ui:define name="title">
<h:outputText value="#{menuCachingMBean.getMenu(topicGroupingPagerMBean.mid).getDomain().getName()} > #{menuCachingMBean.getMenu(topicGroupingPagerMBean.mid).getName()}" />
</ui:define>
<ui:define name="headMetaData">
<link rel="stylesheet" type="text/css" media="all" href="#{request.contextPath}/css/dataTable.css" />
<link rel="stylesheet" type="text/css" media="all" href="#{request.contextPath}/css/dataTable_topic.css" />
</ui:define>
<ui:define name="body">
<h:panelGroup layout="block" rendered="true">
<h:panelGroup layout="block" rendered="true">
<h:form id="form">
<h:inputHidden id="mid" value="#{topicGroupingPagerMBean.mid}" />
<h:inputHidden id="page" value="#{topicGroupingPagerMBean.page}" />
<h:outputText value=" " />
<h:inputText id="keywords" value="#{topicGroupingPagerMBean.keywords}" />
<input type="button" value="#{messages['ybxiang.javaarm.search']}" onclick="var keywords=document.getElementById('form:keywords').value;window.location.href='#{request.contextPath}/faces/list.xhtml?mid=#{topicGroupingPagerMBean.mid}&keywords='+keywords" />
<ui:include src="/template/pager.xhtml" >
<ui:param name="sharedParameterValuePairs" value="mid=#{topicGroupingPagerMBean.mid}&keywords=#{topicGroupingPagerMBean.keywords}" />
<ui:param name="fromWebPath" value="#{request.contextPath}/faces/list.xhtml" />
<ui:param name="page" value="#{topicGroupingPagerMBean.page}" />
<ui:param name="totalRecords" value="#{topicGroupingPagerMBean.totalRecords}" />
<ui:param name="totalPages" value="#{topicGroupingPagerMBean.totalPages}" />
</ui:include>
<ui:include src="/template/displayer_topicList.xhtml" >
<ui:param name="topicList" value="#{topicGroupingPagerMBean.getPagedRecords()}" />
</ui:include>
<ui:include src="/template/pager.xhtml" >
<ui:param name="sharedParameterValuePairs" value="mid=#{topicGroupingPagerMBean.mid}&keywords=#{topicGroupingPagerMBean.keywords}" />
<ui:param name="fromWebPath" value="#{request.contextPath}/faces/list.xhtml" />
<ui:param name="page" value="#{topicGroupingPagerMBean.page}" />
<ui:param name="totalRecords" value="#{topicGroupingPagerMBean.totalRecords}" />
<ui:param name="totalPages" value="#{topicGroupingPagerMBean.totalPages}" />
</ui:include>
</h:form>
</h:panelGroup>
</h:panelGroup>
</ui:define>
</ui:composition>
Comments