posts - 40,  comments - 187,  trackbacks - 0
说在前面的话:
ECSide组件,一个功能丰富,简单易用的列表组件,套用圈子里的一句话:它可能不是最好的,但也许是你最需要的。感兴趣的同志们可以访问ECSide的圈子,里面的资源及文档都很丰富,不在这里做过多的介绍了,圈子地址为http://ecside.group.javaeye.com/
 
实例讲解:
实现从一张公告表读取公告信息并以列表展示的功能。本文中的源代码可通过这个链接下载。
bulletin_powered_by_ecside_allen.zip

另附ECSide标签的使用说明,方便大家查阅。

ECSide标签使用说明

开发环境:
Dev Tool: Eclipse 3.3
Web Server: Tomcat 5.5.23
Framework: Spring 2.0.6 + Hibernate 3.3.0 + Struts 1.2.8 + ecside_2.0_RC1
Database: Oracle 9i
 
实现步骤:

0) 准备工作

使用ecside工具,你需要准备的有:

1、ecside.jar

2、 ecside.tld标签

3、ecside.js

4、ecside.css

5、ecside使用table图片

注:以上内容均可在圈子中下载到。

1)配置ecside
   需要在web.xml中配置ecside的过滤器,用于文件导出和语言编码,忘记配置的话,会出现“正在提交”的问题。
<!--  ecside export filter  -->
    
< filter >
        
< filter-name > ecsideExport </ filter-name >
        
< filter-class > org.ecside.filter.ECSideFilter </ filter-class >
        
< init-param >
            
< param-name > useEasyDataAccess </ param-name >
            
< param-value > true </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > useEncoding </ param-name >
            
< param-value > true </ param-value >
        
</ init-param >
        
< init-param >         
            
< param-name > encoding </ param-name >
            
< param-value > UTF-8 </ param-value >
        
</ init-param >
    
</ filter >
    
< filter-mapping >
        
< filter-name > ecsideExport </ filter-name >
        
< url-pattern > /* </ url-pattern >
    
</ filter-mapping >

还需配置一下tld,
 
< taglib >
         
< taglib-uri > /WEB-INF/ecside.tld </ taglib-uri >
        
< taglib-location > /WEB-INF/taglib/ecside.tld </ taglib-location >
    
</ taglib >
 
另外,还可以初始化ecside.properties文件,写这个文件的目的是:把公共的内容集中在一个文件中,方便使用。一旦我们使用ecside 组件,哪个这些配置信息就可以直接引用。形式可以如下:
###########        table       ###############
table.method=post
table.width=95%
table.pageSizeList=10,20,50,100,1000,2000,all
table.rowsDisplayed=10
table.sortable=true
###########        column      ###############
column.format.date=yyyy/MM/dd
column.format.number=0.##
column.format.currency=###,###,###

2) 在Struts Action中使用ecside
首先来简单介绍一下RSF(列表、排序、过滤)操作方式:
ecside支持两种RSF方式:   基于java collection层 和 基于数据库层,下面分别介绍:

基于java collection层
这是ec的默认实现方式, 最简单易用.你要做的就是将整个列表所要展现的全部数据放入collection 内,并交给EC来处理.其中RSF操作,全部由EC在内存中完成,由于你已经将全部数据放入了collection中,所以排序 过滤都是基于全部数据的.你要在DAO中做的就是一个 查询操作,SQL语句中不需要加入 关于排序 分页 过滤的代码.
这种方式的优点非常明显:实现简单.缺点同样明显,而且在很大程度上是致命的: 数据量大的时候速度慢,而且很可能OutOfMemory.
 
基于数据库层
在这种方式下,EC的角色发生了一点点变化。此时,EC负责把 collection 里的内容展现出来, 同时会向你提供RSF相关的参数。而这些参数需要你自己手动取得 并传入到DAO中(当然EC提供了很多方便的方法来帮助你取得这些参数),具体功能的实现需要你自己在DAO中组织相应的SQL语句。
这种方式的优缺点正好和方式一相反。
 
我这里采用第二种基于数据库层的分页方式实现列表,这时在JSP中使用ecside时,要将<ec:table>中的几个重要属性设定为limit。如: <ec:table filterRowsCallback="process/limit"  sortRowsCallback="process/limit"  retrieveRowsCallback="process/limit" ...> 这里filterRowsCallback表示过滤的Callback方式,sortRowsCallback表示排序的Callback方式,retrieveRowsCallback表示分页的Callback方式,这三个属性都需要设定为limit。(不熟悉的读者可以查询原版EC中的相关说明,不在这里详述。)
Struts Action的代码为:
/*  
     * 用ECSide構建列表
      *
     
*/

    
public  ActionForward list(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) 
{
        String v_type 
=  request.getParameter( " type " );
        
// 0) 設定過濾條件
        Map < String, Object >  filterMap  =   new  HashMap < String, Object > ();
//         filterMap.put("content", "test");
        Map < String, Object >  sortMap  =   new  HashMap < String, Object > ();
        sortMap.put(
" createTime " " desc " );  //  按照創建時間倒序排列
        
// 1) 設定ECSide分頁對象
        Limit limit  =  RequestUtils.getLimit(request);
        
//  取总记录数
         int  pageNo  =  RequestUtils.getPageNo(request);
        
int  pagesize  =  RequestUtils.getCurrentRowsDisplayed(request);
        
if  (pagesize  ==   0 )
            pagesize 
=  PAGESIZE;
        
//  设置总记录数及每页记录数
         int  totalRows  =  RequestUtils.getTotalRowsFromRequest(request);
        
if  (totalRows  <=   0 {
            totalRows 
=  getEntityManager()
                    .getCount(getEntityClass(), filterMap);
        }

        limit.setRowAttributes(totalRows, pagesize);
        
//  根據參數得到結果
        List < Bulletin >  result  =  getEntityManager().queryForListByCriter(
                getEntityClass(), filterMap, sortMap,
                ((pageNo 
-   1 *  pagesize), pagesize);
        request.setAttribute(getEntityListName(), result);
        request.setAttribute(
" myPageSize " , getPageSize(request));
        request.setAttribute(
" type " , v_type);
        
return  mapping.findForward(LIST);
    }

这里我构建了过滤条件及排序条件查询数据,通过queryForListByCriter方法,输入当前起始页及每页的显示条数在数据层得到所需数据。详见代码中的注释。另附数据处理层两个方法的代码:
/*分页查询数据*/
public List queryForListByCriter(Class entityClass, Map filter,
            Map sortMap, 
int start, int everypage) {
        Criteria criteria 
= getCriteria(entityClass);
        setFilter(criteria, filter);
        setSort(criteria, sortMap);
        criteria.setFirstResult(start);
        criteria.setMaxResults(everypage);
        
return criteria.list();
    }


/*计算数据条数*/    
public int getCount(Class entityClass, Map filter) {
        Criteria criteria 
= getCriteria(entityClass);
        setFilter(criteria, filter);
        criteria.setProjection(Projections.rowCount());
        
return ((Integer) criteria.uniqueResult()).intValue();
    }

注:ecside与ORM工具无关,不管你使用什么方法只要能获得一个集合就好,这里我用的是Hibernate获得的集合。
 
3)在JSP中使用ecside
需要注意的是:
1. items的值一定要和request.setAttribute(getEntityListName(), result); 属性一致
2. 可以引用属性名做为值显示,如:${bulletin.id}
3. <ec:column property="name" title="公告名称">property属性值一定是映射文件中的某个属性
<% @ page contentType = " text/html; charset=UTF-8 "   %>
<% @ taglib uri = " /WEB-INF/ecside.tld "  prefix = " ec "   %>
<% @ taglib uri = " http://java.sun.com/jsp/jstl/core "  prefix = " c "   %>
<% @ taglib uri = " http://java.sun.com/jsp/jstl/fmt "  prefix = " fmt "   %>
<% @ taglib uri = " http://java.sun.com/jsp/jstl/functions "  prefix = " fn "   %>
< c:set  var ="ctx"  value ="${pageContext.request.contextPath}" />

< html >
< head >
    
< meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8"   />
     
< META  HTTP-EQUIV ="pragma"  CONTENT ="no-cache" >
    
< META  HTTP-EQUIV ="Cache-Control"  CONTENT ="no-cache, must-revalidate" >
    
< META  HTTP-EQUIV ="expires"  CONTENT ="0" >
    
< title > 公告列表 </ title >
    
< link  rel ="stylesheet"  type ="text/css"  href ="${ctx}/module/bizAcceptance/resources/ecside/css/ecside_style.css"   />
    
< script  type ="text/javascript"  src ="${ctx}/module/bizAcceptance/resources/ecside/js/prototype_mini.js"   ></ script >     
    
< script  type ="text/javascript"  src ="${ctx}/module/bizAcceptance/resources/ecside/js/ecside.js"   ></ script >
    
< script  type ="text/javascript"  src ="${ctx}/module/bizAcceptance/resources/ecside/js/ecside_msg_utf8_cn.js"   ></ script >
</ head >
< body >
< table  width ="100%"   border ="0"  cellspacing ="0"  cellpadding ="0" >
<!--  校验信息  -->
  
< tr >
    
< td  class ="left" > <% @ include file = " /module/commons/htmlmessages.jsp "   %> </ td >                 
  
</ tr >
  
< tr >
        
< td  height ="30" >
            
< span  style ="align:left;font-size:9pt;" >
                請選擇公告
              
< input  type ="button"  name ="Submit3"  value ='進  入' onclick ="doView()" >
            
</ span >< br >
        
</ td >
  
</ tr >
  
< tr >
      
< td >
          
< ec:table  items ="bulletins"  var ="bulletin"
            retrieveRowsCallback
="limit"
            filterRowsCallback
="limit"    
            action
="${ctx}/module/bulletin.do?method=list&type=${type}"
            title
="我的公告列表"  
            useAjax
="false"
            showPrint
="false"
            width
="100%"
            resizeColWidth
="true"
            filterable
="false"
            listWidth
="100%"
            rowsDisplayed
="${myPageSize}"
            pageSizeList
="${myPageSize},10,15,20,all"
            xlsFileName
="公告列表.xls"
            styleClass
="tableRegion"  
            style
="border:2px;table-layout:fixed;"
            classic
="true" >
            
< ec:row >
                
< ec:column  property ="_0"  title ="選擇"  width ="6%" >
                    
< input  type ="radio"  id ="radio_${GLOBALROWCOUNT}"  name ="checkedRadio"  value ="${bulletin.id}" >
                
</ ec:column >
                
< ec:column  property ="_1"  title ="序號"  width ="6%" >
                    ${GLOBALROWCOUNT}
                
</ ec:column >
                
< ec:column  property ="name"  title ="公告名稱" >
                    
< href ="JavaScript:doStarting('${affair.id}')"  title ="點擊查看" >< c:out  value ="${bulletin.name}" /></ a >
                
</ ec:column >
                
< ec:column  property ="desn"  title ="描述"  ellipsis ="true"   />
                
< ec:column  property ="createBy"  title ="創建人"  width ="10%"   />
                
< ec:column  property ="createTime"  title ="創建時間"   width ="20%" >
                    
< fmt:formatDate  value ="${bulletin.createTime}"  pattern ="yyyy-MM-dd HH:mm:ss" /> &nbsp;
                
</ ec:column >
                
< ec:column  property ="_2"  title ="可執行操作" >
                    
< href ="${ctx}/module/bulletin.do?method=edit&ID=${bulletin.id}" >< img  src ="${ctx}/images/affairmgt/update.gif"  border ="0"  title ="編輯" > 編輯 </ a > &nbsp;
                    
< href ="${ctx}/module/bulletin.do?method=delete&ID=${bulletin.id}" >< img  src ="${ctx}/images/affairmgt/delete.gif"  border ="0"  title ="移除" > 移除 </ a >
                
</ ec:column >
            
</ ec:row >
        
</ ec:table >
      
</ td >
  
</ tr >   
</ table >
< script  language ="javascript" >
    
var  _confirm  =   " false " ;
    
var  confirmMsg  =   " 查看此公告? " ;
    
var  urlPrefix  =   " ${ctx}/module/bulletin.do?method=view&ID= " ;
    
function  doView(itemId)  {
          
if  (itemId  !=   null {
            
if  (_confirm  ==  ' false ||  confirm(confirmMsg))  {
                ShowWaiting('正在加载数据,请稍候');
                  window.location 
=  urlPrefix  +  itemId;
            }

          }
  else   {
              
var  radio  =  document.getElementsByName('checkedRadio');
              
for  (i  =   0 ; i  <  radio.length; i ++ {
                  
if  (radio[i].checked)  {
                    
if  (_confirm  ==  ' false ||  confirm(confirmMsg))  {
                        itemId 
=  radio[i].value;
                          ShowWaiting('正在加载数据,请稍候');
                          window.location 
=  urlPrefix  +  itemId;
                    }

                    
return ;
                  }

              }

              alert('請選擇一個公告!');
          }

   }

</ script >
  
</ body >  
</ html >
 

其中,<ec:column property="desn" title="描述" ellipsis="true" />,ellipsis属性实现单元格内数据过长的时候,自动截短并加"..."的功能,但是ie only!因为ff不支持 text-overflow: ellipsis; 使用ellipsis="true"的同时,还要为ec:table加上 style="table-layout:fixed;" (如果您已经使用了调整列宽功能 则不用添加)。

 
4) 启动服务,大功告成。 

ecside_list.jpg 


需要提醒一下,这里采用的是ECSide的默认样式,可根据您具体的需求改变样式文件。


                                                                                     THE END
posted on 2008-12-15 10:47 小立飞刀 阅读(9158) 评论(10)  编辑  收藏 所属分类: User Interface

FeedBack:
# re: 如何使用ECSide(GT-Grid)组件构建列表(内附源码)[未登录]
2008-12-16 11:16 | 老马
我靠 写的不错呀  回复  更多评论
  
# re: 如何使用ECSide(GT-Grid)组件构建列表(内附源码)
2008-12-16 14:02 | 小立飞刀
更新ecside Jar包的版本为ecside_2.0_RC1.jar  回复  更多评论
  
# re: 如何使用ECSide(GT-Grid)组件构建列表(内附源码)
2009-01-13 14:06 | 小立飞刀
解决使用xlsFileName进行excel导出,无法导出全部数据的问题

在采用基于数据层的分页、过滤、排序方式时,导出操作也会采用相同的方式处理,即ecside会调用< ec:table>的action属性定义的方法进行导出数据封装,这就造成了导出时无法导出全部数据而只是导出当前页面数据。

解决方法是在action中封装结果数据时處理一下導出的操作,取全部數據,通过limit.isExported()判斷,代碼如下:
if (limit.isExported()) //判斷操作是否為導出 若是則封裝全部結果數據
result = getEntityManager().findForListByFilter(
filter, 0, totalRows);
else
result = getEntityManager().findForListByFilter(
filter, ((pageNo - 1) * pagesize), pagesize);   回复  更多评论
  
# re: 如何使用ECSide列表组件构建列表(内附源码)
2009-03-09 10:43 | philip
是否支持jstl标签  回复  更多评论
  
# re: 如何使用ECSide列表组件构建列表(内附源码)
2009-03-09 15:41 | 小立飞刀
@philip
支持的 我给的例子中就用了 比如可以如下使用<fmt:formatDate>标签:

<ec:column property ="createTime" title ="創建時間">
<fmt:formatDate value ="${bulletin.createTime}" pattern ="yyyy-MM-dd HH:mm:ss" />
</ec:column>

但是好像不能作为属性使用
  回复  更多评论
  
# re: 如何使用ECSide列表组件构建列表(内附源码)
2009-11-01 15:21 | 刚学ecside
import net.allen.core.struts.StrutsEntityAction;
大哥,这个类没有啊
能不能弄全一点啊,不胜感激!
我QQ:417186803  回复  更多评论
  
# re: 如何使用ECSide列表组件构建列表(内附源码)
2009-11-03 10:04 | 小立飞刀
@刚学ecside
这个类并无特殊用途,如果您用的是struts1.2的话,完全可以继承DispatchAction。  回复  更多评论
  
# re: 如何使用ECSide列表组件构建列表(内附源码)[未登录]
2009-11-19 11:25 | xx
请问用ecside组件时,实现对列数据的编辑和行数据的添加功能过程中,如果有时间字段,应该怎么让时间字段可以有日历和时间进行选择后输入啊?  回复  更多评论
  
# re: 如何使用ECSide列表组件构建列表(内附源码)
2009-11-25 15:22 | 小立飞刀
@xx
添加、编辑、删除等功能我基本上没有用到,但理论上来说,可以这样处理:
添加时,需要定义一个区块,如:
<div id="add_template" style="display:none;">
<input type="text" name="title">
<input type="text" name="someDate" class="Wdate" onclick="WdatePicker({dateFmt:'yyyy-MM-dd', skin:'blue'})">
...
</div>

在里面定义一个选择时间的input,我这里用的是My97DatePicker控件,就可以实现您说的时间选择了。  回复  更多评论
  
# c ni ma ma
2011-05-25 17:02 | dsf
fdg  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2009年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

生存或毁灭,这是个必答之问题:是否应默默的忍受坎苛命运之无情打击,还是应与深如大海之无涯苦难奋然为敌,并将其克服。此二抉择,究竟是哪个较崇高?

常用链接

留言簿(12)

随笔分类(43)

相册

收藏夹(7)

朋友的博客

电子资料

搜索

  •  

积分与排名

  • 积分 - 302059
  • 排名 - 192

最新评论

阅读排行榜

评论排行榜