顯示具有 Struts2 標籤的文章。 顯示所有文章
顯示具有 Struts2 標籤的文章。 顯示所有文章

2009年12月20日 星期日

實作可編輯的Ext Grid,新增資料到Server side data(Database)

開發環境:
IDE:MyEclipse6.6GA
Web Server:Tomcat 6.0.20
Database:MySql 5.1.36
MVC:Struts2.1.8
FrameWork:Spring2.0,Hibernate3.2
Client UI:Ext2.3.0

一、建立可編輯之Ext Grid及JSON output頁面:
1.Ext Grid頁面(editGrid2.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>">

    

    <title>My JSP 'combox.jsp' starting page</title>

    

 <meta http-equiv="pragma" content="no-cache">

 <meta http-equiv="cache-control" content="no-cache">

 <meta http-equiv="expires" content="0">    

 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

 <meta http-equiv="description" content="This is my page">

 <!--

 <link rel="stylesheet" type="text/css" href="styles.css">

 -->

 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">

 <link rel="stylesheet" type="text/css" href="css/onReady.css">

 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

 <script type="text/javascript" src="extjs/ext-all.js"></script>

 <script type="text/javascript" src="extjs/ext-lang-zh_TW.js"></script> 

 <script type="text/javascript"><!--

 

  Ext.onReady(function(){

   var store = new Ext.data.Store({

    url: 'SysMgrJson!getMovies.action',

    reader: new Ext.data.JsonReader({root:'results',totalProperty:'totals'}, [

     'id',

     'coverthumb',

     'title',

     'director',

     {name: 'released', type: 'date', dateFormat: 'Y-m-d'},

     'genre',

     'tagline',

     {name: 'price', type: 'float'},

     {name: 'active'}

    ])

   });

   

   var genres = new Ext.data.Store({

    data: [

     [1,"Comedy"],

     [2,"Drama"],

     [3,"Action"],

     [4,"Mystery"]    

    ],

    reader: new Ext.data.ArrayReader({id:'id'}, [

     'id',

     'genre'])

   }); 

        

   //Combining two columns function

   function title_tagline(val, x, store){

    return '<b>'+val+'</b><br>'+store.data.tagline;

   }

   //Generating HTML and graphics

   function cover_image(val){

    return '<img src="images/'+val+'.jpg" width="50%" height="50%">';

   }

   //for edit field of grid

   var title_edit = new Ext.form.TextField();

   var director_edit = new Ext.form.TextField();

   var tagline_edit = new Ext.form.TextField({

    maxLength: 45

   });

   var price_edit = new Ext.form.TextField();

   var coverthumb_edit = new Ext.form.TextField();

   var released_edit = new Ext.form.DateField();

   var genre_edit = new Ext.form.ComboBox({

    typeAhead: true,

    triggerAction: 'all',

    mode: 'local',

    store: genres,

    displayField:'genre',

    valueField: 'genre'

   });

   

   //for add row to grid

   var ds_model = Ext.data.Record.create([

    'id',  

    'title',

    'director',

    {name: 'released', type: 'date', dateFormat: 'Y-m-d'},

    'genre',

    'tagline',

    'coverthumb',

    {name: 'price', type: 'float'},

    {name: 'active'}

   ]);      

   // add your data store here

   var grid = new Ext.grid.EditorGridPanel({

    //renderTo: document.body,

    renderTo:'example-grid',

    frame:true,

    title: 'Movie Database',

    height:300,

    width:550,

    stripeRows:true,

    store: store,

    //增加grid event for Row Selection mode

    sm: new Ext.grid.RowSelectionModel({

     //singleSelect: true,

     listeners: {

      rowselect: {

       fn: function(sm,index,record) {

        index++;

        Ext.Msg.alert('提示','您選擇了,'+record.data.title+',第 '+index+'筆資料');

       }

      }

     }

    }),

    //Altering the grid at the click of a button 

    tbar: [

     //modify title column of grid

     {

      text: '修改 Title',

      handler: function(){

       var sm = grid.getSelectionModel();

       if (sm.hasSelection()){

        var sel = sm.getSelected();

        Ext.Msg.show({

         title: '修改 Title',

         prompt: true,

         buttons: Ext.MessageBox.OKCANCEL,

         value: sel.data.title,

         fn: function(btn,text){

          if (btn == 'ok'){

           sel.set('title', text);

          }

         }

        });

       }else{

        Ext.Msg.alert('提示','請選擇欲修改Title之列');

       }

      }

     },

     //hidden price column of grid

     {

      text: 'Hide Price',

      handler: function(btn){

       var cm = grid.getColumnModel();

       var pi = cm.getIndexById('price');

       //var pi=5;

       if (cm.isHidden(pi)){

        cm.setHidden(pi,false);

        btn.setText('Hide Price');

       }else{

        cm.setHidden(pi,true);

        btn.setText('Show Price');

       }

       btn.render();

      }

     },

     //add first row to grid

     {

      text: 'Add Movie(First)',

      icon: 'images/RowInsert.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       grid.getStore().insert(0,new ds_model({

        id:'',

        title:'New Movie',

        director:'',

        genre:'Comedy',

        tagline:'',

        active:'1'

        })

       );

       grid.startEditing(0,0);

      }

     },

     //add last row to grid

     {

      text: 'Add Movie(Last)',

      icon: 'images/RowInsert.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       grid.getStore().insert(grid.getStore().getCount(),new ds_model({

        id:'',

        title:'New Movie',

        director:'',

        genre:'Comedy',

        tagline:'',

        active:'1'

        })

       );

       grid.startEditing(grid.getStore().getCount()-1,0);

      }

     },

     //Deleting data from the server

     {

      text: 'Remove Movie',

      icon: 'images/RowDelete.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       var sm = grid.getSelectionModel();

       if (sm.hasSelection()){

        //var sel = sm.getSelected();

        var sels = sm.getSelections();

        var len = sels.length;

        var ids = new Array(len);

        for(var i=0;i<len;i++){

         ids[i] = sels[i].data.id;

         if(i==0){

          var msgs = '刪除: '+sels[i].data.title;

         }else{

          msgs = msgs +',\n'+sels[i].data.title; 

         }

        };

        Ext.Msg.show({

        title: '刪除電影',

         buttons: Ext.MessageBox.YESNOCANCEL,

         msg: msgs,

         fn: function(btn){

          if (btn == 'yes'){

           var conn = new Ext.data.Connection();

           conn.request({

            url: 'SysMgrJson!updateMovies.action',

            method:'post',

            params: {

             action: 'delete',

             id: ids

            },

            success: function(resp,opt) {

             //grid.getStore().remove(sel);

             grid.getStore().reload();

            },

            failure: function(resp,opt) {

             Ext.Msg.alert('Error',

             'Unable to delete movie');

            }

           });

          }

         }

        });

       }else{

        Ext.Msg.alert('提示','請選擇欲刪除(多)列之資料');

       }

      }

      },

      
     //Saving data to the server

     {

      text: 'Save Movie',

      icon: 'images/save-icon.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       var sm = grid.getSelectionModel();

       if (sm.hasSelection()){

        var sels = sm.getSelections();

        var len = sels.length;

        var values = new Array(len);

        for(var i=0;i<len;i++){

         values[i] = new Array(9);

         values[i][0] = sels[i].data.id;

         values[i][1] = sels[i].data.title;

         values[i][2] = sels[i].data.director;

         values[i][3] = (sels[i].data.released).format('Y-m-d');

         values[i][4] = sels[i].data.genre;

         values[i][5] = sels[i].data.tagline;

         values[i][6] = sels[i].data.coverthumb;

         values[i][7] = sels[i].data.price;

         values[i][8] = sels[i].data.active;

         if(i==0){

          var msgs = '儲存: '+sels[i].data.title;

         }else{

          msgs = msgs +',\n'+sels[i].data.title; 

         }

        };

        Ext.Msg.show({

        title: '儲存電影',

         buttons: Ext.MessageBox.YESNOCANCEL,

         msg: msgs,

         fn: function(btn){

          if (btn == 'yes'){

           var conn = new Ext.data.Connection();

           conn.request({

            url: 'SysMgrJson!updateMovies.action',

            method:'post',

            params: {

             action: 'update',

             values: values

            },

            success: function(resp,opt) {

             //grid.getStore().remove(sel);

             grid.getStore().reload();

            },

            failure: function(resp,opt) {

             Ext.Msg.alert('Error',

             'Unable to save movie');

            }

           });

          }

         }

        });

       }else{

        Ext.Msg.alert('提示','請選擇欲儲存(多)列之資料');

       }

      }

      }             

    ],

          bbar: new Ext.PagingToolbar({

              pageSize: 5,

              store: store,

              displayInfo: true,

              displayMsg: '第 {0} 筆 - {1} 筆 of {2} 筆',

              emptyMsg: "沒有資料"

          }),       

    //Defining a Grids column model and want to display column

    columns: [

    {header: "Cover", dataIndex: 'coverthumb',renderer:cover_image},

    {header: "CoverThumb", dataIndex: 'coverthumb',editor:coverthumb_edit},

    //Combining two columns

    {header: "Title", dataIndex: 'title',renderer:title_tagline,editor:title_edit},

    {header: "Director", dataIndex: 'director',editor:director_edit},

    //Client-side sorting

    {header: "Released", dataIndex: 'released',sortable:true,

    renderer: Ext.util.Format.dateRenderer('m/d/Y'),editor:released_edit},

    {header: "Genre", dataIndex: 'genre',editor:genre_edit},    

    {header: "Price",dataIndex: 'price',id:'price',editor:price_edit},

    //setup hidden column

    {header: "Tagline", dataIndex: 'tagline',hidden:true,editor:tagline_edit}

    ]

   });

   //需在gridPanel建立後才可以Load資料

   store.load({params:{start:0, limit:5}});

  });

 //

 --></script>

  </head>

  

  <body><br>

   <center>

    <h3><font color="red">Movie Database Grid</font></h3><br>

   </center>

   <table align="center" border="0">

    <tr>

     <td>

     <div id="example-grid"></div>

    <td>

   </tr>

  </table>

  </body>

</html>

2.JSON output頁面(outputJSON.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags"  %>

<s:property value="jsonString" escape="false"/>


二、建立刪除資料DAO及Service及Struts2 Action:
0.建立bean (Movies.java):
package com.bean.test;



public class Movies {

 private int id;

 private String title;

 private String director;

 private String released;

 private String genre;

 private String tagline;

 private String coverthumb;

 private String price;

 private String active;

 

 public int getId() {

  return id;

 }

 public void setId(int id) {

  this.id = id;

 }

 public String getTitle() {

  return title;

 }

 public void setTitle(String title) {

  this.title = title;

 }

 public String getDirector() {

  return director;

 }

 public void setDirector(String director) {

  this.director = director;

 }

 public String getReleased() {

  return released;

 }

 public void setReleased(String released) {

  this.released = released;

 }

 public String getGenre() {

  return genre;

 }

 public void setGenre(String genre) {

  this.genre = genre;

 }

 public String getTagline() {

  return tagline;

 }

 public void setTagline(String tagline) {

  this.tagline = tagline;

 }

 public String getCoverthumb() {

  return coverthumb;

 }

 public void setCoverthumb(String coverthumb) {

  this.coverthumb = coverthumb;

 }

 public String getPrice() {

  return price;

 }

 public void setPrice(String price) {

  this.price = price;

 }

 public String getActive() {

  return active;

 }

 public void setActive(String active) {

  this.active = active;

 }

}


1.建立刪除資料DAO Interface(SysMgrDAO.java):
package com.dao.test;



import java.util.List;



public interface SysMgrDAO {

 public List findFunctionAll();

 public List findFunctionAll(final int start,final int limit);

 public int getFunctionTotalCount();

 public List findTitleAll();

 public List findTitleAll(final int start,final int limit);

 public int getTitleTotalCount();

 public List findMovieAll(final int start,final int limit);

 public int getMoviesTotalCount();

 public String deleteMovie(int[] id);

 public String updateMovie(String[][] values);

}


2.建立刪除資料DAO Implement(SysMgrDAOImpl.java):
package com.dao.impl.test;



import java.sql.SQLException;

import java.util.List;





import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.hibernate.Hibernate;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.Transaction;

import org.hibernate.transform.Transformers;

import org.springframework.orm.hibernate3.HibernateCallback;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;



import com.bean.test.Function;

import com.bean.test.Movies;

import com.bean.test.Title;

import com.dao.test.SysMgrDAO;



public class SysMgrDAOImpl extends HibernateDaoSupport implements SysMgrDAO {

 private static final Log log = LogFactory.getLog(SysMgrDAOImpl.class);



 public List findFunctionAll() {

  log.debug("finding tbl_function with native sql");

  Session session = this.getSession();

  try{

   String sql="select id as fnid,name as fnname,`desc` as fndesc from cmsdb.tbl_function";  

   List list =  session.createSQLQuery(sql)

        .addScalar("fnid")

        .addScalar("fnname")

        .addScalar("fndesc")

        .setResultTransformer(Transformers.aliasToBean(Function.class))

        .list();

   log.debug("find successful of tbl_function with native sql");

   return list;

  }catch(RuntimeException re){

   log.error("finded error of tbl_function with native sql",re);

   throw re;

  }finally{

   session.close();

  }  

 }



 public List findFunctionAll(final int start,final int limit) {

  log.debug("get paging of tbl_function with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id as fnid,name fnname,`desc` as fndesc from cmsdb.tbl_function")

      .addScalar("fnid")

      .addScalar("fnname")

      .addScalar("fndesc")

      .setResultTransformer(Transformers.aliasToBean(Function.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_function with native sql successful");

    return obj;

   }

  }); 

 }



 public int getFunctionTotalCount() {

  log.debug("finding totalcount of tbl_function with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_function";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_function with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_function with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findTitleAll() {

  log.debug("finding tbl_title with native sql");

  Session session = this.getSession();

  try{

   String sql="select id,name,`desc` from cmsdb.tbl_title";  

   List list =  session.createSQLQuery(sql)

        .setResultTransformer(Transformers.aliasToBean(Title.class))

        .list();

   log.debug("find successful of tbl_title with native sql");

   return list;

  }catch(RuntimeException re){

   log.error("finded error of tbl_title with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findTitleAll(final int start, final int limit) {

  log.debug("get paging of tbl_title with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id as id,name as name,`desc` as `desc` from cmsdb.tbl_title")

      .addScalar("id")

      .addScalar("name")

      .addScalar("desc")

      .setResultTransformer(Transformers.aliasToBean(Title.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_title with native sql successful");

    return obj;

   }

  }); 

 }



 public int getTitleTotalCount() {

  log.debug("finding totalcount of tbl_title with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_title";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_title with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_title with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findMovieAll(final int start,final int limit) {

  log.debug("get paging of tbl_movies with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id,title,director,released,genre,tagline,coverthumb,price,active from cmsdb.tbl_movies")

      .addScalar("id")

      .addScalar("title")

      .addScalar("director")

      .addScalar("released",Hibernate.STRING)

      .addScalar("genre")

      .addScalar("tagline")

      .addScalar("coverthumb")

      .addScalar("price")

      .addScalar("active")

      .setResultTransformer(Transformers.aliasToBean(Movies.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_movies with native sql successful");

    return obj;

   }

  });

 }



 public int getMoviesTotalCount() {

  log.debug("finding totalcount of tbl_movies with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_movies";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_movies with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_movies with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public String deleteMovie(int[] id) {

  log.debug("deleting movies of tbl_movies with native sql");

  Session session = this.getSession();

  Transaction tx = session.beginTransaction();

  String sql;

  String flag="success";

  try{

   sql = "delete from cmsdb.tbl_movies where id=?";

   for(int i=0;i<id.length;i++){    

    session.createSQLQuery(sql).setParameter(0, Integer.valueOf(id[i])).executeUpdate();

    tx.commit();

   }

  }catch(RuntimeException re){

   flag="failure";

   tx.rollback();

   log.error("deleted error movies of tbl_movies with native sql",re);

   throw re;

  }finally{

   session.close();

  }  

  return flag;

 }



 public String updateMovie(String[][] values) {

  Session session = this.getSession();

  Transaction tx = null;

  String sql;

  String flag="success";

  try{

   for(int i=0;i<values.length;i++){

     String[] value = values[i][0].split(",");

     tx = session.beginTransaction();

     if(value[0]!=null && value[0].equals("")){//values[i][0]==>id field value,when id='' then insert

      log.debug("saving movies of tbl_movies with native sql");

      sql = "insert into tbl_movies(title,director,released,genre,tagline,coverthumb,price,active)values(?,?,?,?,?,?,?,?)";

    

      session.createSQLQuery(sql).setParameter(0, value[1])

               .setParameter(1, value[2])

               .setParameter(2, value[3])

               .setParameter(3, value[4])

               .setParameter(4, value[5])

               .setParameter(5, value[6])

               .setParameter(6, value[7])

               .setParameter(7, value[8])

               .executeUpdate();

      tx.commit();

     }else{//values[i][0]==>id field value,when id!='' then update

      log.debug("updating movies of tbl_movies with native sql");

      sql = "update tbl_movies set title=?" +

             ",director=?" +

             ",released=?" +

             ",genre=?" +

             ",tagline=?" +

             ",coverthumb=?" +

             ",price=?" +

             ",active=?" +

         " where id=?";

      

      session.createSQLQuery(sql).setParameter(0, value[1])

               .setParameter(1, value[2])

               .setParameter(2, value[3])

               .setParameter(3, value[4])

               .setParameter(4, value[5])

               .setParameter(5, value[6])

               .setParameter(6, value[7])

               .setParameter(7, value[8])

               .setParameter(8, Integer.valueOf(value[0]))

               .executeUpdate();

      tx.commit();    

     }

   }

  }catch(RuntimeException re){

   flag="failure";

   tx.rollback();

   log.error("saved error movies of tbl_movies with native sql",re);

   throw re;

  }finally{

   session.close();

  }  

  return flag;

 } 

}


3.建立刪除資料Service Interface(SysMgrService.java):
package com.service.test;



import java.util.List;



public interface SysMgrService {

 public List findFunctionAll();

 public List findFunctionAll(final int start,final int limit);

 public int getFunctionTotalCount();

 public List findTitleAll();

 public List findTitleAll(final int start,final int limit);

 public int getTitleTotalCount();

 public List findMovieAll(final int start,final int limit);

 public int getMoviesTotalCount();

 public String deleteMovie(int[] id);

 public String updateMovie(String[][] values);

}


4.建立刪除資料Service Implement(SysMgrDAO.java):
package com.service.impl.test;



import java.util.List;



import com.dao.test.SysMgrDAO;

import com.service.test.SysMgrService;



public class SysMgrServiceImpl implements SysMgrService {

 private SysMgrDAO sysMgrDAO;

 

 

 public List findFunctionAll() {

  return this.sysMgrDAO.findFunctionAll();

 }



 public List findFunctionAll(int start, int limit) {

  return this.sysMgrDAO.findFunctionAll(start, limit);

 }



 public List findTitleAll() {

  return this.sysMgrDAO.findTitleAll();

 }



 public List findTitleAll(int start, int limit) {

  return this.sysMgrDAO.findTitleAll(start, limit);

 }



 public int getFunctionTotalCount() {

  return this.sysMgrDAO.getFunctionTotalCount();

 }



 public int getTitleTotalCount() {

  return this.sysMgrDAO.getTitleTotalCount();

 }



 public SysMgrDAO getSysMgrDAO() {

  return sysMgrDAO;

 }



 public void setSysMgrDAO(SysMgrDAO sysMgrDAO) {

  this.sysMgrDAO = sysMgrDAO;

 }



 public List findMovieAll(int start, int limit) {

  return this.sysMgrDAO.findMovieAll(start, limit);

 }



 public int getMoviesTotalCount() {

  return this.sysMgrDAO.getMoviesTotalCount();

 }



 public String deleteMovie(int[] id) {

  return this.sysMgrDAO.deleteMovie(id);

 }



 public String updateMovie(String[][] values) {

  return this.sysMgrDAO.updateMovie(values);

 }

}



5.建立刪除資料Struts2 Action:
5.1.SysMgrAction.java
package com.action.test;



import java.util.List;



import net.sf.json.JSONArray;

import com.opensymphony.xwork2.ActionSupport;

import com.service.test.SysMgrService;





public class SysMgrAction extends ActionSupport {

 /**

  * 

  */

 private static final long serialVersionUID = 1L;

 private SysMgrService sysMgrService;

 private String jsonString;

 private int start;

 private int limit;

 private String function01;

 private String grade01;

 private int[] id;

 private String action;

 private String[][] values;



 public String getFunction() throws Exception {

  //沒有分頁功能

  //List list = this.sysMgrService.findFunctionAll();

  

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

  List list = this.sysMgrService.findFunctionAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "functoinJSON";

 }

 

 public String getFunctionAll() throws Exception {

  //沒有分頁功能

  List list = this.sysMgrService.findFunctionAll();

  String totals = String.valueOf(list.size());

  //有分頁功能  

  //String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

  //List list = this.sysMgrService.findFunctionAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "functoinJSON";

 }

 

 public String getTitle() throws Exception {

  //沒有分頁功能

  //List list = this.sysMgrService.findTitleAll();

  

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getTitleTotalCount());

  List list = this.sysMgrService.findTitleAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "titleJSON";

 } 



 public String comboFormSubmit() throws Exception{

  this.jsonString = "{\"success\":\"true\",\"funcId\":\""+function01+"\",\"grade\":\""+grade01+"\"}";

  return "comboFormJSON";

 }

 

 public String getMovies() throws Exception { 

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getMoviesTotalCount());

  List list = this.sysMgrService.findMovieAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "outputJSON";

 }

 

 public String updateMovies() throws Exception { 

  if(action!=null && action.equals("delete")){

   if(this.sysMgrService.deleteMovie(id).equals("success")){

    this.jsonString = "{\"success\":\"true\"}";

   }else{

    this.jsonString = "{\"failure\":\"true\"}";

   }

  }else if(action!=null && action.equals("update")){

   if(this.sysMgrService.updateMovie(values).equals("success")){

    this.jsonString = "{\"success\":\"true\"}";

   }else{

    this.jsonString = "{\"failure\":\"true\"}";

   }   

  }  

  return "outputJSON";

 }

 

 public SysMgrService getSysMgrService() {

  return sysMgrService;

 }





 public void setSysMgrService(SysMgrService sysMgrService) {

  this.sysMgrService = sysMgrService;

 } 



 public String getJsonString() {

  return jsonString;

 }



 public void setJsonString(String jsonString) {

  this.jsonString = jsonString;

 }



 public int getStart() {

  return start;

 }



 public void setStart(int start) {

  this.start = start;

 }



 public int getLimit() {

  return limit;

 }



 public void setLimit(int limit) {

  this.limit = limit;

 }



 public String getFunction01() {

  return function01;

 }



 public void setFunction01(String function01) {

  this.function01 = function01;

 }



 public String getGrade01() {

  return grade01;

 }



 public void setGrade01(String grade01) {

  this.grade01 = grade01;

 }



 public int[] getId() {

  return id;

 }



 public void setId(int[] id) {

  this.id = id;

 }



 public String getAction() {

  return action;

 }



 public void setAction(String action) {

  this.action = action;

 }



 public String[][] getValues() {

  return values;

 }



 public void setValues(String[][] values) {

  this.values = values;

 }

}


5.2.struts2 config(struts.xml):
<?xml version="1.0" encoding="UTF-8"?>

   <!DOCTYPE struts PUBLIC

 "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"

 "http://struts.apache.org/dtds/struts-2.1.dtd">



<struts>

 <constant name="struts.devMode" value="true"></constant> 

 <constant name="struts.configuration.xml.reload" value="true"></constant>

 <constant name="struts.i18n.reload" value="true"></constant>

 <constant name="struts.custom.i18n.resources" value="globalMessages"></constant>

 

 <package name="ExtStudy" extends="struts-default">

  <action name="SysMgrJson" class="SysMgrJsonAction">

   <result name="functoinJSON">JsonJSP/functionJSON.jsp</result>

   <result name="titleJSON">JsonJSP/titleJSON.jsp</result>

   <result name="comboFormJSON">JsonJSP/comboFormJSON.jsp</result>

   <result name="outputJSON">JsonJSP/outputJSON.jsp</result>

  </action>

 </package>

</struts>


5.3.spring config(applicationContext.xml):
<?xml version="1.0" encoding="UTF-8"?>

<beans

 xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">



 <!-- 直接使用dbcp當dataSource 

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>

  <property name="url" value="jdbc:mysql://localhost:3306/mytest"></property>

  <property name="username" value="manning"></property>

  <property name="password" value="action"></property>

  <property name="maxActive" value="50"></property>

  <property name="maxIdle" value="50"></property>

  <property name="maxWait" value="100"></property>

  <property name="defaultAutoCommit" value="true"></property>

 </bean>

  -->

 

 <!-- 使用jndi當dataSource  -->

 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

  <!-- 當resourceRef=false,則jndiName需加上java:comp/env字元,resourceRef其default value=false

  <property name="resourceRef">false</property>

  <property name="jndiName" value="java:comp/env/jdbc/MytestDB"></property>

   -->  

  <property name="resourceRef" value="true"></property>

  <property name="jndiName" value="jdbc/CMSDB"></property>

  <property name="proxyInterface" value="javax.sql.DataSource"></property>

 </bean>

 

 <!-- spring use jdni with weblogic config

 <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

  <property name="resourceRef" value="true"></property>

  <property name="jndiName" value="MySqlDataSource"></property>

  <property name="jndiEnvironment">

   <props>

    <prop key="java.naming.provider.url">t3://localhost:7001</prop>

   </props>

  </property>

 </bean>

 -->

 

 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

  <property name="dataSource" ref="dataSource"></property>

  <property name="hibernateProperties">

   <props>

    <prop key="hibernate.show_sql">true</prop>

    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>

   </props>

  </property>

  <property name="mappingResources">

   <list>



   </list>

  </property>

 </bean>

 

 <!-- DAO -->

 <bean id="SysMgrDAO" class="com.dao.impl.test.SysMgrDAOImpl">

  <property name="sessionFactory" ref="sessionFactory"></property>

 </bean>

 

 <!-- Service -->

 <bean id="SysMgrService" class="com.service.impl.test.SysMgrServiceImpl">

  <property name="sysMgrDAO" ref="SysMgrDAO"></property>

 </bean>

 

 <!-- Action -->

 <bean id="SysMgrJsonAction" class="com.action.test.SysMgrAction" scope="prototype">

  <property name="sysMgrService" ref="SysMgrService"></property>

 </bean>

</beans>


三、測試結果:
1.http://localhost:8080/ExtStudy/Basic/editGrid2.jsp














2009年12月19日 星期六

實作可編輯的Ext Grid,可刪除Server side data(Database)


開發環境:
IDE:MyEclipse6.6GA
Web Server:Tomcat 6.0.20
Database:MySql 5.1.36
MVC:Struts2.1.8
FrameWork:Spring2.0,Hibernate3.2
Client UI:Ext2.3.0

一、建立可編輯之Ext Grid及JSON output頁面:
1.Ext Grid頁面(editGrid1.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>">

    

    <title>My JSP 'combox.jsp' starting page</title>

    

 <meta http-equiv="pragma" content="no-cache">

 <meta http-equiv="cache-control" content="no-cache">

 <meta http-equiv="expires" content="0">    

 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

 <meta http-equiv="description" content="This is my page">

 <!--

 <link rel="stylesheet" type="text/css" href="styles.css">

 -->

 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">

 <link rel="stylesheet" type="text/css" href="css/onReady.css">

 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

 <script type="text/javascript" src="extjs/ext-all.js"></script>

 <script type="text/javascript" src="extjs/ext-lang-zh_TW.js"></script> 

 <script type="text/javascript"><!--

 

  Ext.onReady(function(){

   var store = new Ext.data.Store({

    url: 'SysMgrJson!getMovies.action',

    reader: new Ext.data.JsonReader({root:'results',totalProperty:'totals'}, [

     'id',

     'coverthumb',

     'title',

     'director',

     {name: 'released', type: 'date', dateFormat: 'Y-m-d'},

     'genre',

     'tagline',

     {name: 'price', type: 'float'},

     {name: 'available', type: 'bool'}

    ])

   });

   

   var genres = new Ext.data.Store({

    data: [

     [1,"Comedy"],

     [2,"Drama"],

     [3,"Action"],

     [4,"Mystery"]    

    ],

    reader: new Ext.data.ArrayReader({id:'id'}, [

     'id',

     'genre'])

   }); 

        

   //Combining two columns function

   function title_tagline(val, x, store){

    return '<b>'+val+'</b><br>'+store.data.tagline;

   }

   //Generating HTML and graphics

   function cover_image(val){

    return '<img src="images/'+val+'.jpg" width="50%" height="50%">';

   }

   //for edit field of grid

   var title_edit = new Ext.form.TextField();

   var director_edit = new Ext.form.TextField();

   var tagline_edit = new Ext.form.TextField({

    maxLength: 45

   });

   var released_edit = new Ext.form.DateField();

   var genre_edit = new Ext.form.ComboBox({

    typeAhead: true,

    triggerAction: 'all',

    mode: 'local',

    store: genres,

    displayField:'genre',

    valueField: 'genre'

   });

   

   //for add row to grid

   var ds_model = Ext.data.Record.create([    

    'title',

    'director',

    {name: 'released', type: 'date', dateFormat: 'Y-m-d'},

    'genre',

    'tagline',

    'coverthumb',

    {name: 'price', type: 'float'},

    {name: 'available', type: 'bool'}

   ]);      

   // add your data store here

   var grid = new Ext.grid.EditorGridPanel({

    //renderTo: document.body,

    renderTo:'example-grid',

    frame:true,

    title: 'Movie Database',

    height:300,

    width:550,

    stripeRows:true,

    store: store,

    //增加grid event for Row Selection mode

    sm: new Ext.grid.RowSelectionModel({

     //singleSelect: true,

     listeners: {

      rowselect: {

       fn: function(sm,index,record) {

        index++;

        Ext.Msg.alert('提示','您選擇了,'+record.data.title+',第 '+index+'筆資料');

       }

      }

     }

    }),

    //Altering the grid at the click of a button 

    tbar: [

     //modify title column of grid

     {

      text: '修改 Title',

      handler: function(){

       var sm = grid.getSelectionModel();

       if (sm.hasSelection()){

        var sel = sm.getSelected();

        Ext.Msg.show({

         title: '修改 Title',

         prompt: true,

         buttons: Ext.MessageBox.OKCANCEL,

         value: sel.data.title,

         fn: function(btn,text){

          if (btn == 'ok'){

           sel.set('title', text);

          }

         }

        });

       }

      }

     },

     //hidden price column of grid

     {

      text: 'Hide Price',

      handler: function(btn){

       var cm = grid.getColumnModel();

       var pi = cm.getIndexById('price');

       //var pi=5;

       if (cm.isHidden(pi)){

        cm.setHidden(pi,false);

        btn.setText('Hide Price');

       }else{

        cm.setHidden(pi,true);

        btn.setText('Show Price');

       }

       btn.render();

      }

     },

     //add first row to grid

     {

      text: 'Add Movie(First)',

      icon: 'images/RowInsert.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       grid.getStore().insert(0,new ds_model({

        title:'New Movie',

        director:'',

        genre:0,

        tagline:''

        })

       );

       grid.startEditing(0,0);

      }

     },

     //add last row to grid

     {

      text: 'Add Movie(Last)',

      icon: 'images/RowInsert.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       grid.getStore().insert(grid.getStore().getCount(),new ds_model({

        title:'New Movie',

        director:'',

        genre:0,

        tagline:''

        })

       );

       grid.startEditing(grid.getStore().getCount()-1,0);

      }

     },

     
     //Deleting data from the server

     {

      text: 'Remove Movie',

      icon: 'images/RowDelete.png',

      cls: 'x-btn-text-icon',

      handler: function() {

       var sm = grid.getSelectionModel();

       if (sm.hasSelection()){

        //var sel = sm.getSelected();

        var sels = sm.getSelections();

        var len = sels.length;

        var ids = new Array(len);

        for(var i=0;i<len;i++){

         ids[i] = sels[i].data.id;

         if(i==0){

          var msgs = '刪除: '+sels[i].data.title;

         }else{

          msgs = msgs +',\n'+sels[i].data.title; 

         }

        };

        Ext.Msg.show({

        title: '刪除電影',

         buttons: Ext.MessageBox.YESNOCANCEL,

         msg: msgs,

         fn: function(btn){

          if (btn == 'yes'){

           var conn = new Ext.data.Connection();

           conn.request({

            url: 'SysMgrJson!updateMovies.action',

            method:'post',

            params: {

             action: 'delete',

             id: ids

            },

            success: function(resp,opt) {

             //grid.getStore().remove(sel);

             grid.getStore().reload();

            },

            failure: function(resp,opt) {

             Ext.Msg.alert('Error',

             'Unable to delete movie');

            }

           });

          }

         }

        });

       }else{

        Ext.Msg.alert('提示','請選擇欲刪除(多)列之資料');

       }

      }

     }        

    ],

          bbar: new Ext.PagingToolbar({

              pageSize: 5,

              store: store,

              displayInfo: true,

              displayMsg: '第 {0} 筆 - {1} 筆 of {2} 筆',

              emptyMsg: "沒有資料"

          }),       

    //Defining a Grids column model and want to display column

    columns: [

    {header: "Cover", dataIndex: 'coverthumb',renderer:cover_image},

    {header: "CoverThumb", dataIndex: 'coverthumb'},

    //Combining two columns

    {header: "Title", dataIndex: 'title',renderer:title_tagline,editor:title_edit},

    {header: "Director", dataIndex: 'director',editor:director_edit},

    //Client-side sorting

    {header: "Released", dataIndex: 'released',sortable:true,

    renderer: Ext.util.Format.dateRenderer('m/d/Y'),editor:released_edit},

    {header: "Genre", dataIndex: 'genre',editor:genre_edit},    

    {header: "Price",dataIndex: 'price',id:'price'},

    //setup hidden column

    {header: "Tagline", dataIndex: 'tagline',hidden:true,editor:tagline_edit}

    ]

   });

   //需在gridPanel建立後才可以Load資料

   store.load({params:{start:0, limit:5}});

  });

 //

 --></script>

  </head>

  

  <body><br>

   <center>

    <h3><font color="red">Movie Database Grid</font></h3><br>

   </center>

   <table align="center" border="0">

    <tr>

     <td>

     <div id="example-grid"></div>

    <td>

   </tr>

  </table>

  </body>

</html>


2.JSON output頁面(outputJSON.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags"  %>

<s:property value="jsonString" escape="false"/>


二、建立刪除資料DAO及Service及Struts2 Action:
0.建立bean (Movies.java):
package com.bean.test;



public class Movies {

 private int id;

 private String title;

 private String director;

 private String released;

 private String genre;

 private String tagline;

 private String coverthumb;

 private String price;

 private String active;

 

 public int getId() {

  return id;

 }

 public void setId(int id) {

  this.id = id;

 }

 public String getTitle() {

  return title;

 }

 public void setTitle(String title) {

  this.title = title;

 }

 public String getDirector() {

  return director;

 }

 public void setDirector(String director) {

  this.director = director;

 }

 public String getReleased() {

  return released;

 }

 public void setReleased(String released) {

  this.released = released;

 }

 public String getGenre() {

  return genre;

 }

 public void setGenre(String genre) {

  this.genre = genre;

 }

 public String getTagline() {

  return tagline;

 }

 public void setTagline(String tagline) {

  this.tagline = tagline;

 }

 public String getCoverthumb() {

  return coverthumb;

 }

 public void setCoverthumb(String coverthumb) {

  this.coverthumb = coverthumb;

 }

 public String getPrice() {

  return price;

 }

 public void setPrice(String price) {

  this.price = price;

 }

 public String getActive() {

  return active;

 }

 public void setActive(String active) {

  this.active = active;

 }

}


1.建立刪除資料DAO Interface(SysMgrDAO.java):
package com.dao.test;



import java.util.List;



public interface SysMgrDAO {

 public List findFunctionAll();

 public List findFunctionAll(final int start,final int limit);

 public int getFunctionTotalCount();

 public List findTitleAll();

 public List findTitleAll(final int start,final int limit);

 public int getTitleTotalCount();

 public List findMovieAll(final int start,final int limit);

 public int getMoviesTotalCount();

 public String deleteMovie(int[] id);

}


2.建立刪除資料DAO Implement(SysMgrDAOImpl.java):
package com.dao.impl.test;



import java.sql.SQLException;

import java.util.List;



import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.hibernate.Hibernate;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.Transaction;

import org.hibernate.transform.Transformers;

import org.springframework.orm.hibernate3.HibernateCallback;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;



import com.bean.test.Function;

import com.bean.test.Movies;

import com.bean.test.Title;

import com.dao.test.SysMgrDAO;



public class SysMgrDAOImpl extends HibernateDaoSupport implements SysMgrDAO {

 private static final Log log = LogFactory.getLog(SysMgrDAOImpl.class);



 public List findFunctionAll() {

  log.debug("finding tbl_function with native sql");

  Session session = this.getSession();

  try{

   String sql="select id as fnid,name as fnname,`desc` as fndesc from cmsdb.tbl_function";  

   List list =  session.createSQLQuery(sql)

        .addScalar("fnid")

        .addScalar("fnname")

        .addScalar("fndesc")

        .setResultTransformer(Transformers.aliasToBean(Function.class))

        .list();

   log.debug("find successful of tbl_function with native sql");

   return list;

  }catch(RuntimeException re){

   log.error("finded error of tbl_function with native sql",re);

   throw re;

  }finally{

   session.close();

  }  

 }



 public List findFunctionAll(final int start,final int limit) {

  log.debug("get paging of tbl_function with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id as fnid,name fnname,`desc` as fndesc from cmsdb.tbl_function")

      .addScalar("fnid")

      .addScalar("fnname")

      .addScalar("fndesc")

      .setResultTransformer(Transformers.aliasToBean(Function.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_function with native sql successful");

    return obj;

   }

  }); 

 }



 public int getFunctionTotalCount() {

  log.debug("finding totalcount of tbl_function with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_function";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_function with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_function with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findTitleAll() {

  log.debug("finding tbl_title with native sql");

  Session session = this.getSession();

  try{

   String sql="select id,name,`desc` from cmsdb.tbl_title";  

   List list =  session.createSQLQuery(sql)

        .setResultTransformer(Transformers.aliasToBean(Title.class))

        .list();

   log.debug("find successful of tbl_title with native sql");

   return list;

  }catch(RuntimeException re){

   log.error("finded error of tbl_title with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findTitleAll(final int start, final int limit) {

  log.debug("get paging of tbl_title with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id as id,name as name,`desc` as `desc` from cmsdb.tbl_title")

      .addScalar("id")

      .addScalar("name")

      .addScalar("desc")

      .setResultTransformer(Transformers.aliasToBean(Title.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_title with native sql successful");

    return obj;

   }

  }); 

 }



 public int getTitleTotalCount() {

  log.debug("finding totalcount of tbl_title with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_title";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_title with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_title with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findMovieAll(final int start,final int limit) {

  log.debug("get paging of tbl_movies with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id,title,director,released,genre,tagline,coverthumb,price,active from cmsdb.tbl_movies")

      .addScalar("id")

      .addScalar("title")

      .addScalar("director")

      .addScalar("released",Hibernate.STRING)

      .addScalar("genre")

      .addScalar("tagline")

      .addScalar("coverthumb")

      .addScalar("price")

      .addScalar("active")

      .setResultTransformer(Transformers.aliasToBean(Movies.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_movies with native sql successful");

    return obj;

   }

  });

 }



 public int getMoviesTotalCount() {

  log.debug("finding totalcount of tbl_movies with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_movies";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_movies with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_movies with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public String deleteMovie(int[] id) {

  log.debug("deleting movies of tbl_movies with native sql");

  Session session = this.getSession();

  Transaction tx = session.beginTransaction();

  String sql;

  String flag="success";

  try{

   sql = "delete from cmsdb.tbl_movies where id=?";

   for(int i=0;i<id.length;i++){    

    session.createSQLQuery(sql).setParameter(0, Integer.valueOf(id[i])).executeUpdate();

    tx.commit();

   }

  }catch(RuntimeException re){

   flag="failure";

   tx.rollback();

   log.error("deleted error movies of tbl_movies with native sql",re);

   throw re;

  }finally{

   session.close();

  }  

  return flag;

 } 

}


3.建立刪除資料Service Interface(SysMgrService.java):
package com.service.test;



import java.util.List;



public interface SysMgrService {

 public List findFunctionAll();

 public List findFunctionAll(final int start,final int limit);

 public int getFunctionTotalCount();

 public List findTitleAll();

 public List findTitleAll(final int start,final int limit);

 public int getTitleTotalCount();

 public List findMovieAll(final int start,final int limit);

 public int getMoviesTotalCount();

 public String deleteMovie(int[] id);

}


4.建立刪除資料Service Implement(SysMgrDAO.java):
package com.service.impl.test;



import java.util.List;



import com.dao.test.SysMgrDAO;

import com.service.test.SysMgrService;



public class SysMgrServiceImpl implements SysMgrService {

 private SysMgrDAO sysMgrDAO;

 

 

 public List findFunctionAll() {

  return this.sysMgrDAO.findFunctionAll();

 }



 public List findFunctionAll(int start, int limit) {

  return this.sysMgrDAO.findFunctionAll(start, limit);

 }



 public List findTitleAll() {

  return this.sysMgrDAO.findTitleAll();

 }



 public List findTitleAll(int start, int limit) {

  return this.sysMgrDAO.findTitleAll(start, limit);

 }



 public int getFunctionTotalCount() {

  return this.sysMgrDAO.getFunctionTotalCount();

 }



 public int getTitleTotalCount() {

  return this.sysMgrDAO.getTitleTotalCount();

 }



 public SysMgrDAO getSysMgrDAO() {

  return sysMgrDAO;

 }



 public void setSysMgrDAO(SysMgrDAO sysMgrDAO) {

  this.sysMgrDAO = sysMgrDAO;

 }



 public List findMovieAll(int start, int limit) {

  return this.sysMgrDAO.findMovieAll(start, limit);

 }



 public int getMoviesTotalCount() {

  return this.sysMgrDAO.getMoviesTotalCount();

 }



 public String deleteMovie(int[] id) {

  return this.sysMgrDAO.deleteMovie(id);

 }

}



5.建立刪除資料Struts2 Action:
5.1.SysMgrAction.java
package com.action.test;



import java.util.List;



import net.sf.json.JSONArray;

import com.opensymphony.xwork2.ActionSupport;

import com.service.test.SysMgrService;





public class SysMgrAction extends ActionSupport {

 /**

  * 

  */

 private static final long serialVersionUID = 1L;

 private SysMgrService sysMgrService;

 private String jsonString;

 private int start;

 private int limit;

 private String function01;

 private String grade01;

 private int[] id;

 private String action;



 public String getFunction() throws Exception {

  //沒有分頁功能

  //List list = this.sysMgrService.findFunctionAll();

  

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

  List list = this.sysMgrService.findFunctionAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "functoinJSON";

 }

 

 public String getFunctionAll() throws Exception {

  //沒有分頁功能

  List list = this.sysMgrService.findFunctionAll();

  String totals = String.valueOf(list.size());

  //有分頁功能  

  //String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

  //List list = this.sysMgrService.findFunctionAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "functoinJSON";

 }

 

 public String getTitle() throws Exception {

  //沒有分頁功能

  //List list = this.sysMgrService.findTitleAll();

  

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getTitleTotalCount());

  List list = this.sysMgrService.findTitleAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "titleJSON";

 } 



 public String comboFormSubmit() throws Exception{

  this.jsonString = "{\"success\":\"true\",\"funcId\":\""+function01+"\",\"grade\":\""+grade01+"\"}";

  return "comboFormJSON";

 }

 

 public String getMovies() throws Exception { 

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getMoviesTotalCount());

  List list = this.sysMgrService.findMovieAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "outputJSON";

 }

 

 public String updateMovies() throws Exception { 

  if(action!=null && action.equals("delete")){

   if(this.sysMgrService.deleteMovie(id).equals("success")){

    this.jsonString = "{\"success\":\"true\"}";

   }else{

    this.jsonString = "{\"failure\":\"true\"}";

   }

  }

  return "outputJSON";

 }

 

 public SysMgrService getSysMgrService() {

  return sysMgrService;

 }





 public void setSysMgrService(SysMgrService sysMgrService) {

  this.sysMgrService = sysMgrService;

 } 



 public String getJsonString() {

  return jsonString;

 }



 public void setJsonString(String jsonString) {

  this.jsonString = jsonString;

 }



 public int getStart() {

  return start;

 }



 public void setStart(int start) {

  this.start = start;

 }



 public int getLimit() {

  return limit;

 }



 public void setLimit(int limit) {

  this.limit = limit;

 }



 public String getFunction01() {

  return function01;

 }



 public void setFunction01(String function01) {

  this.function01 = function01;

 }



 public String getGrade01() {

  return grade01;

 }



 public void setGrade01(String grade01) {

  this.grade01 = grade01;

 }



 public int[] getId() {

  return id;

 }



 public void setId(int[] id) {

  this.id = id;

 }



 public String getAction() {

  return action;

 }



 public void setAction(String action) {

  this.action = action;

 }

}


5.2.struts2 config(struts.xml):
<?xml version="1.0" encoding="UTF-8"?>

   <!DOCTYPE struts PUBLIC

 "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"

 "http://struts.apache.org/dtds/struts-2.1.dtd">



<struts>

 <constant name="struts.devMode" value="true"></constant> 

 <constant name="struts.configuration.xml.reload" value="true"></constant>

 <constant name="struts.i18n.reload" value="true"></constant>

 <constant name="struts.custom.i18n.resources" value="globalMessages"></constant>

 

 <package name="ExtStudy" extends="struts-default">

  <action name="SysMgrJson" class="SysMgrJsonAction">

   <result name="functoinJSON">JsonJSP/functionJSON.jsp</result>

   <result name="titleJSON">JsonJSP/titleJSON.jsp</result>

   <result name="comboFormJSON">JsonJSP/comboFormJSON.jsp</result>

   <result name="outputJSON">JsonJSP/outputJSON.jsp</result>

  </action>

 </package>

</struts>


5.3.spring config(applicationContext.xml):
<?xml version="1.0" encoding="UTF-8"?>

<beans

 xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">



 <!-- 直接使用dbcp當dataSource 

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>

  <property name="url" value="jdbc:mysql://localhost:3306/mytest"></property>

  <property name="username" value="manning"></property>

  <property name="password" value="action"></property>

  <property name="maxActive" value="50"></property>

  <property name="maxIdle" value="50"></property>

  <property name="maxWait" value="100"></property>

  <property name="defaultAutoCommit" value="true"></property>

 </bean>

  -->

 

 <!-- 使用jndi當dataSource  -->

 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

  <!-- 當resourceRef=false,則jndiName需加上java:comp/env字元,resourceRef其default value=false

  <property name="resourceRef">false</property>

  <property name="jndiName" value="java:comp/env/jdbc/MytestDB"></property>

   -->  

  <property name="resourceRef" value="true"></property>

  <property name="jndiName" value="jdbc/CMSDB"></property>

  <property name="proxyInterface" value="javax.sql.DataSource"></property>

 </bean>

 

 <!-- spring use jdni with weblogic config

 <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

  <property name="resourceRef" value="true"></property>

  <property name="jndiName" value="MySqlDataSource"></property>

  <property name="jndiEnvironment">

   <props>

    <prop key="java.naming.provider.url">t3://localhost:7001</prop>

   </props>

  </property>

 </bean>

 -->

 

 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

  <property name="dataSource" ref="dataSource"></property>

  <property name="hibernateProperties">

   <props>

    <prop key="hibernate.show_sql">true</prop>

    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>

   </props>

  </property>

  <property name="mappingResources">

   <list>



   </list>

  </property>

 </bean>

 

 <!-- DAO -->

 <bean id="SysMgrDAO" class="com.dao.impl.test.SysMgrDAOImpl">

  <property name="sessionFactory" ref="sessionFactory"></property>

 </bean>

 

 <!-- Service -->

 <bean id="SysMgrService" class="com.service.impl.test.SysMgrServiceImpl">

  <property name="sysMgrDAO" ref="SysMgrDAO"></property>

 </bean>

 

 <!-- Action -->

 <bean id="SysMgrJsonAction" class="com.action.test.SysMgrAction" scope="prototype">

  <property name="sysMgrService" ref="SysMgrService"></property>

 </bean>

</beans>


三、測試結果:
1.http://localhost:8080/ExtStudy/Basic/editGrid1.jsp

















2009年12月16日 星期三

實作Ext grid 分頁範例,其資料來源為從資料庫動態產生JSON檔案



開發環境:
IDE:MyEclipse6.6GA
Web Server:Tomcat 6.0.20
Database:MySql 5.1.36
MVC:Struts2.1.8
FrameWork:Spring2.0,Hibernate3.2
Client UI:Ext2.3.0

一、建立grid頁面(grid1.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">



<title>My JSP 'combox.jsp' starting page</title>



<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="styles.css">

-->

<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">

<link rel="stylesheet" type="text/css" href="css/onReady.css">

<script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

<script type="text/javascript" src="extjs/ext-all.js"></script>

<script type="text/javascript" src="extjs/ext-lang-zh_TW.js"></script>

<script type="text/javascript">

<!--

Ext.onReady(function(){

//***********Function Grid Panel****************

var proxy=new Ext.data.HttpProxy({url:'SysMgrJson!getFunction.action',method:'post'});

//JsonReader

var reader=new Ext.data.JsonReader({root:'results',

totalProperty:'totals'},

[

{name: 'fnid', mapping: 'fnid'},

{name: 'fnname',mapping:'fnname'},

{name: 'fndesc',mapping:'fndesc'}

]

);

//Store

var store=new Ext.data.Store({

proxy:proxy,

reader:reader

});



// create the grid

var grid = new Ext.grid.GridPanel({

store: store,

columns: [

{header: "功能編號", width: 100, dataIndex: 'fnid', sortable: true},

{header: "功能名稱", width: 100, dataIndex: 'fnname', sortable: true},

{header: "功能描述", width: 100, dataIndex: 'fndesc', sortable: true}

],

renderTo:'function-grid',

width:350,

height:200,

//tbar:top bar

//bbar:bottom bar

bbar: new Ext.PagingToolbar({

pageSize: 5,

store: store,

displayInfo: true,

displayMsg: '第 {0} 筆 - {1} 筆 of {2} 筆',

emptyMsg: "沒有資料"

})

});

//需在gridPanel建立後才可以Load資料

store.load({params:{start:0, limit:5}});

//***********Function Grid Panel****************



//***********Title Grid Panel****************

var Titleproxy=new Ext.data.HttpProxy({url:'SysMgrJson!getTitle.action',method:'post'});

//JsonReader

var Titlereader=new Ext.data.JsonReader({root:'results',

totalProperty:'totals'},

[

{name: 'id', mapping: 'id'},

{name: 'name',mapping:'name'},

{name: 'desc',mapping:'desc'}

]

);

//Store

var Titlestore=new Ext.data.Store({

proxy:Titleproxy,

reader:Titlereader

});



// create the grid

var Titlegrid = new Ext.grid.GridPanel({

store: Titlestore,

columns: [

{header: "職稱編號", width: 100, dataIndex: 'id', sortable: true},

{header: "職稱名稱", width: 100, dataIndex: 'name', sortable: true},

{header: "職稱描述", width: 100, dataIndex: 'desc', sortable: true}

],

renderTo:'title-grid',

width:350,

height:200,

//tbar:top bar

//bbar:bottom bar

bbar: new Ext.PagingToolbar({

pageSize: 5,

store: Titlestore,

displayInfo: true,

displayMsg: '第 {0} 筆 - {1} 筆 of {2} 筆',

emptyMsg: "沒有資料"

})

});

//需在gridPanel建立後才可以Load資料

Titlestore.load({params:{start:0, limit:5}});

//***********Title Grid Panel****************

});



//-->

</script>

</head>



<body>

<div id="function-grid"></div><br>

<div id="title-grid"></div>

</body>

</html>



二、建立DAO及Action:
1.建立系統管理DAO(SysMgrDAO.java):

package com.dao.test;



import java.util.List;



public interface SysMgrDAO {

public List findFunctionAll();

public List findFunctionAll(final int start,final int limit);

public int getFunctionTotalCount();

public List findTitleAll();

public List findTitleAll(final int start,final int limit);

public int getTitleTotalCount();

}



2.建立系統管理DAO Implement(SysMgrDAOImpl.java):

package com.dao.impl.test;



import java.sql.SQLException;

import java.util.List;



import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.hibernate.Hibernate;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.transform.Transformers;

import org.springframework.orm.hibernate3.HibernateCallback;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;



import com.bean.test.Function;

import com.bean.test.Title;

import com.dao.test.SysMgrDAO;



public class SysMgrDAOImpl extends HibernateDaoSupport implements SysMgrDAO {

private static final Log log = LogFactory.getLog(SysMgrDAOImpl.class);



public List findFunctionAll() {

log.debug("finding tbl_function with native sql");

Session session = this.getSession();

try{

String sql="select id as fnid,name as fnname,`desc` as fndesc from cmsdb.tbl_function";

List list = session.createSQLQuery(sql)

.addScalar("fnid")

.addScalar("fnname")

.addScalar("fndesc")

.setResultTransformer(Transformers.aliasToBean(Function.class))

.list();

log.debug("find successful of tbl_function with native sql");

return list;

}catch(RuntimeException re){

log.error("finded error of tbl_function with native sql",re);

throw re;

}finally{

session.close();

}

}



public List findFunctionAll(final int start,final int limit) {

log.debug("get paging of tbl_function with native sql");

return this.getHibernateTemplate().executeFind(new HibernateCallback(){

public Object doInHibernate(Session session) throws HibernateException, SQLException {

Object obj = session.createSQLQuery("select id as fnid,name fnname,`desc` as fndesc from cmsdb.tbl_function")

.addScalar("fnid")

.addScalar("fnname")

.addScalar("fndesc")

.setResultTransformer(Transformers.aliasToBean(Function.class))

.setFirstResult(start)

.setMaxResults(limit)

.list();

log.debug("get paging of tbl_function with native sql successful");

return obj;

}

});

}



public int getFunctionTotalCount() {

log.debug("finding totalcount of tbl_function with native sql");

Session session = this.getSession();

try{

String sql="select count(*) as count from cmsdb.tbl_function";

List list = session.createSQLQuery(sql)

.addScalar("count",Hibernate.INTEGER)

.list();

log.debug("find successful totalcount of tbl_function with native sql");

return ((Integer)list.get(0)).intValue();

}catch(RuntimeException re){

log.error("finded error totalcount of tbl_function with native sql",re);

throw re;

}finally{

session.close();

}

}



public List findTitleAll() {

log.debug("finding tbl_title with native sql");

Session session = this.getSession();

try{

String sql="select id,name,`desc` from cmsdb.tbl_title";

List list = session.createSQLQuery(sql)

.setResultTransformer(Transformers.aliasToBean(Title.class))

.list();

log.debug("find successful of tbl_title with native sql");

return list;

}catch(RuntimeException re){

log.error("finded error of tbl_title with native sql",re);

throw re;

}finally{

session.close();

}

}



public List findTitleAll(final int start, final int limit) {

log.debug("get paging of tbl_title with native sql");

return this.getHibernateTemplate().executeFind(new HibernateCallback(){

public Object doInHibernate(Session session) throws HibernateException, SQLException {

Object obj = session.createSQLQuery("select id as id,name as name,`desc` as `desc` from cmsdb.tbl_title")

.addScalar("id")

.addScalar("name")

.addScalar("desc")

.setResultTransformer(Transformers.aliasToBean(Title.class))

.setFirstResult(start)

.setMaxResults(limit)

.list();

log.debug("get paging of tbl_title with native sql successful");

return obj;

}

});

}



public int getTitleTotalCount() {

log.debug("finding totalcount of tbl_title with native sql");

Session session = this.getSession();

try{

String sql="select count(*) as count from cmsdb.tbl_title";

List list = session.createSQLQuery(sql)

.addScalar("count",Hibernate.INTEGER)

.list();

log.debug("find successful totalcount of tbl_title with native sql");

return ((Integer)list.get(0)).intValue();

}catch(RuntimeException re){

log.error("finded error totalcount of tbl_title with native sql",re);

throw re;

}finally{

session.close();

}

}



}



3.建立系統管理Service(SysMgrService.java):

package com.service.test;



import java.util.List;



public interface SysMgrService {

public List findFunctionAll();

public List findFunctionAll(final int start,final int limit);

public int getFunctionTotalCount();

public List findTitleAll();

public List findTitleAll(final int start,final int limit);

public int getTitleTotalCount();

}



4.建立系統管理Service Implement(SysMgrServiceImpl.java):

package com.service.impl.test;



import java.util.List;



import com.dao.test.SysMgrDAO;

import com.service.test.SysMgrService;



public class SysMgrServiceImpl implements SysMgrService {

private SysMgrDAO sysMgrDAO;





public List findFunctionAll() {

return this.sysMgrDAO.findFunctionAll();

}



public List findFunctionAll(int start, int limit) {

return this.sysMgrDAO.findFunctionAll(start, limit);

}



public List findTitleAll() {

return this.sysMgrDAO.findTitleAll();

}



public List findTitleAll(int start, int limit) {

return this.sysMgrDAO.findTitleAll(start, limit);

}



public int getFunctionTotalCount() {

return this.sysMgrDAO.getFunctionTotalCount();

}



public int getTitleTotalCount() {

return this.sysMgrDAO.getTitleTotalCount();

}



public SysMgrDAO getSysMgrDAO() {

return sysMgrDAO;

}



public void setSysMgrDAO(SysMgrDAO sysMgrDAO) {

this.sysMgrDAO = sysMgrDAO;

}

}



5.建立系統管理Action(SysMgrAction.java):

package com.action.test;



import java.util.List;



import net.sf.json.JSONArray;

import com.opensymphony.xwork2.ActionSupport;

import com.service.test.SysMgrService;





public class SysMgrAction extends ActionSupport {

/**

*

*/

private static final long serialVersionUID = 1L;

private SysMgrService sysMgrService;

private String jsonString;

private int start;

private int limit;

private String function01;

private String grade01;



public String getFunction() throws Exception {

//沒有分頁功能

//List list = this.sysMgrService.findFunctionAll();



//有分頁功能

String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

List list = this.sysMgrService.findFunctionAll(start, limit);

JSONArray array = JSONArray.fromObject(list);

this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

return "functoinJSON";

}



public String getFunctionAll() throws Exception {

//沒有分頁功能

List list = this.sysMgrService.findFunctionAll();

String totals = String.valueOf(list.size());

//有分頁功能

//String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

//List list = this.sysMgrService.findFunctionAll(start, limit);

JSONArray array = JSONArray.fromObject(list);

this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

return "functoinJSON";

}



public String getTitle() throws Exception {

//沒有分頁功能

//List list = this.sysMgrService.findTitleAll();



//有分頁功能

String totals = String.valueOf(this.sysMgrService.getTitleTotalCount());

List list = this.sysMgrService.findTitleAll(start, limit);

JSONArray array = JSONArray.fromObject(list);

this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

return "titleJSON";

}



public String comboFormSubmit() throws Exception{

this.jsonString = "{\"success\":\"true\",\"funcId\":\""+function01+"\",\"grade\":\""+grade01+"\"}";

return "comboFormJSON";

}



public SysMgrService getSysMgrService() {

return sysMgrService;

}





public void setSysMgrService(SysMgrService sysMgrService) {

this.sysMgrService = sysMgrService;

}



public String getJsonString() {

return jsonString;

}



public void setJsonString(String jsonString) {

this.jsonString = jsonString;

}



public int getStart() {

return start;

}



public void setStart(int start) {

this.start = start;

}



public int getLimit() {

return limit;

}



public void setLimit(int limit) {

this.limit = limit;

}



public String getFunction01() {

return function01;

}



public void setFunction01(String function01) {

this.function01 = function01;

}



public String getGrade01() {

return grade01;

}



public void setGrade01(String grade01) {

this.grade01 = grade01;

}

}



6.建立comboFormJSON頁面(comboFormJSON.jsp):

<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags" %>

<s:property value="jsonString" escape="false"/>



7.於struts.xml(src目錄下)設定Struts2 Action:

<action name="SysMgrJson" class="SysMgrJsonAction">

<result name="functoinJSON">JsonJSP/functionJSON.jsp</result>

<result name="titleJSON">JsonJSP/titleJSON.jsp</result>

<result name="comboFormJSON">JsonJSP/comboFormJSON.jsp</result>

</action>



8.於applicationContext.xml(WEB-INF目錄下)設定Struts2 Action:

<!-- DAO -->

<bean id="SysMgrDAO" class="com.dao.impl.test.SysMgrDAOImpl">

<property name="sessionFactory" ref="sessionFactory"></property>

</bean>


<!-- Service -->

<bean id="SysMgrService" class="com.service.impl.test.SysMgrServiceImpl">

<property name="sysMgrDAO" ref="SysMgrDAO"></property>

</bean>


<!-- Action -->

<bean id="SysMgrJsonAction" class="com.action.test.SysMgrAction" scope="prototype">

<property name="sysMgrService" ref="SysMgrService"></property>

</bean>



三、測試結果:
1.http://localhost:8080/ExtStudy/Basic/grid1.jsp


看到此畫面,恭喜您整合開發環境設定成功!

實作Ext grid,其資料來源為靜態之JSON檔案


開發環境:
IDE:MyEclipse6.6GA
Web Server:Tomcat 6.0.20
Database:MySql 5.1.36
MVC:Struts2.1.8
FrameWork:Spring2.0,Hibernate3.2
Client UI:Ext2.3.0

一、建立grid頁面(grid.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>">

    

    <title>My JSP 'combox.jsp' starting page</title>

    

 <meta http-equiv="pragma" content="no-cache">

 <meta http-equiv="cache-control" content="no-cache">

 <meta http-equiv="expires" content="0">    

 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

 <meta http-equiv="description" content="This is my page">

 <!--

 <link rel="stylesheet" type="text/css" href="styles.css">

 -->

 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">

 <link rel="stylesheet" type="text/css" href="css/onReady.css">

 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

 <script type="text/javascript" src="extjs/ext-all.js"></script>

 <script type="text/javascript" src="extjs/ext-lang-zh_TW.js"></script> 

 <script type="text/javascript">

 <!--

  Ext.onReady(function(){

  var proxy=new Ext.data.HttpProxy({url:'survey.html'});

  //Jsonreader

  var reader=new Ext.data.JsonReader({},

    [

     {name: 'appeId', mapping: 'appeId'},

     {name: 'survId'},

     {name: 'location'}, 

     {name: 'surveyDate'},

     {name: 'surveyTime'},

     {name: 'inputUserId'}           

    ]

  );

  //Store   

  var store=new Ext.data.Store({

    proxy:proxy,

    reader:reader

    });

  //load

  store.load();

     // create the grid

     var grid = new Ext.grid.GridPanel({

         store: store,

         columns: [

             {header: "appeId", width: 60, dataIndex: 'appeId', sortable: true},

             {header: "survId", width: 60, dataIndex: 'survId', sortable: true},

             {header: "location", width: 60, dataIndex: 'location', sortable: true},

             {header: "surveyDate", width: 100, dataIndex: 'surveyDate', sortable: true},

             {header: "surveyTime", width: 100, dataIndex: 'surveyTime', sortable: true},

             {header: "inputUserId", width:80, dataIndex: 'inputUserId', sortable: true}

         ],

         renderTo:'example-grid',

         width:540,

         height:200

     });

 

 });



 //-->

 </script>

  </head>

  

  <body>

  <div id="example-grid"></div>

  </body>

</html>


二、準備JSON檔案(survey.html)於Server Side:
[{"appeId":"1","survId":"1","location":"","surveyDate":"2008-03-14","surveyTime":"12:19:47","inputUserId":"1","inputTime":"2008-03-14 12:21:51","modifyTime":"0000-00-00 00:00:00"},{"appeId":"2","survId":"32","location":"","surveyDate":"2008-03-14","surveyTime":"22:43:09","inputUserId":"32","inputTime":"2008-03-14 22:43:37","modifyTime":"0000-00-00 00:00:00"},{"appeId":"3","survId":"32","location":"","surveyDate":"2008-03-15","surveyTime":"07:59:33","inputUserId":"32","inputTime":"2008-03-15 08:00:44","modifyTime":"0000-00-00 00:00:00"},{"appeId":"4","survId":"1","location":"","surveyDate":"2008-03-15","surveyTime":"10:45:42","inputUserId":"1","inputTime":"2008-03-15 10:46:04","modifyTime":"0000-00-00 00:00:00"},{"appeId":"5","survId":"32","location":"","surveyDate":"2008-03-16","surveyTime":"08:04:49","inputUserId":"32","inputTime":"2008-03-16 08:05:26","modifyTime":"0000-00-00 00:00:00"},{"appeId":"6","survId":"32","location":"","surveyDate":"2008-03-20","surveyTime":"20:19:01","inputUserId":"32","inputTime":"2008-03-20 20:19:32","modifyTime":"0000-00-00 00:00:00"}]


三、測試結果:
1.http://localhost:8080/ExtStudy/Basic/grid.jsp


看到此畫面,恭喜您整合開發環境設定成功!

實作Ext Combobox form,傳統 Submit form


開發環境:
IDE:MyEclipse6.6GA
Web Server:Tomcat 6.0.20
Database:MySql 5.1.36
MVC:Struts2.1.8
FrameWork:Spring2.0,Hibernate3.2
Client UI:Ext2.3.0

此範例為學習combo box在Ext2.3.0之用法,其中combo box之資料來源分別有從資料庫及local兩種,
以及透過傳統Submit form方式Submit後接收回傳結果到前端!
一、建立Combo表單頁面(combo1.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>">

    

    <title>My JSP 'combox.jsp' starting page</title>

    

 <meta http-equiv="pragma" content="no-cache">

 <meta http-equiv="cache-control" content="no-cache">

 <meta http-equiv="expires" content="0">    

 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

 <meta http-equiv="description" content="This is my page">

 <!--

 <link rel="stylesheet" type="text/css" href="styles.css">

 -->

 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">

 <link rel="stylesheet" type="text/css" href="css/onReady.css">

 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

 <script type="text/javascript" src="extjs/ext-all.js"></script>

 <script type="text/javascript" src="extjs/ext-lang-zh_TW.js"></script> 

 <script type="text/javascript">

 <!--

  Ext.onReady(function(){

   Ext.BLANK_IMAGE_URL='extjs/resources/images/default/s.gif';

   Ext.QuickTips.init();

   Ext.form.Field.prototype.msgTarget = 'side';

   var proxy=new Ext.data.HttpProxy({url:'SysMgrJson!getFunctionAll.action',method:'post'});

   //JsonReader

   var reader=new Ext.data.JsonReader({root:'results',

            totalProperty:'totals'},

     [

      {name: 'fnid', mapping: 'fnid'},

      {name: 'fnname',mapping:'fnname'},

      {name: 'fndesc',mapping:'fndesc'}   

     ]

   );

   //Store   

   var store=new Ext.data.Store({

     proxy:proxy,

     reader:reader

     });

   var functionCombo01 = new Ext.form.ComboBox({

    fieldLabel:'請選擇功能',

    hiddenName:'function01',

          store: store,

          valueField: 'fnname',

          displayField:'fnname',

          lazyRender:true,

          typeAhead: true,

          mode: 'remote',

          forceSelection: true,

          triggerAction: 'all',

          emptyText:'請選擇功能...',

          selectOnFocus:true

      });

      //store.load();

   var gradeCombo01 = new Ext.form.ComboBox({

    store:new Ext.data.SimpleStore({

       data : [["A"], ["B"], ["C"], ["D"],["E"]],

       fields: ['grade']

    }),

    hiddenName:'grade01',

    fieldLabel:'請選擇等級',

    emptyText:'請選擇等級...',

    triggerAction: 'all',

    minChars : 1,

    typeAhead: true,

    lazyRender:true,

    valueField: 'grade',

    displayField : 'grade',

    selectOnFocus:true,   

    mode : 'local'

   });      

   var comboForm = new Ext.form.FormPanel({

    renderTo:document.body,

    frame:true,

    title:'Simple Form',

    width:350,

    height:200,

    labelAlign:'left',

    bodyStyle:'padding:0px 0px 0',

    items:[functionCombo01,gradeCombo01],

    applyTo:'Simple_Form',

    buttons:[{text:'存檔',

        handler:function(){//傳統Form submit作法

         comboForm.getForm().getEl().dom.action='SysMgrJson!comboFormSubmit.action';

         comboForm.getForm().getEl().dom.method='POST';

         comboForm.getForm().getEl().dom.submit();    

        }},

        {text:'重置',handler:function(){

       comboForm.getForm().reset();

          }

        }

    ]

   });

  });  

 //-->

 </script>

  </head>

  

  <body>

  <div id="Simple_Form"></div>

  </body>

</html>


二、建立DAO及Action:
1.建立系統管理DAO(SysMgrDAO.java):
package com.dao.test;



import java.util.List;



public interface SysMgrDAO {

 public List findFunctionAll();

 public List findFunctionAll(final int start,final int limit);

 public int getFunctionTotalCount();

 public List findTitleAll();

 public List findTitleAll(final int start,final int limit);

 public int getTitleTotalCount();

}


2.建立系統管理DAO Implement(SysMgrDAOImpl.java):
package com.dao.impl.test;



import java.sql.SQLException;

import java.util.List;



import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.hibernate.Hibernate;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.transform.Transformers;

import org.springframework.orm.hibernate3.HibernateCallback;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;



import com.bean.test.Function;

import com.bean.test.Title;

import com.dao.test.SysMgrDAO;



public class SysMgrDAOImpl extends HibernateDaoSupport implements SysMgrDAO {

 private static final Log log = LogFactory.getLog(SysMgrDAOImpl.class);



 public List findFunctionAll() {

  log.debug("finding tbl_function with native sql");

  Session session = this.getSession();

  try{

   String sql="select id as fnid,name as fnname,`desc` as fndesc from cmsdb.tbl_function";  

   List list =  session.createSQLQuery(sql)

        .addScalar("fnid")

        .addScalar("fnname")

        .addScalar("fndesc")

        .setResultTransformer(Transformers.aliasToBean(Function.class))

        .list();

   log.debug("find successful of tbl_function with native sql");

   return list;

  }catch(RuntimeException re){

   log.error("finded error of tbl_function with native sql",re);

   throw re;

  }finally{

   session.close();

  }  

 }



 public List findFunctionAll(final int start,final int limit) {

  log.debug("get paging of tbl_function with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id as fnid,name fnname,`desc` as fndesc from cmsdb.tbl_function")

      .addScalar("fnid")

      .addScalar("fnname")

      .addScalar("fndesc")

      .setResultTransformer(Transformers.aliasToBean(Function.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_function with native sql successful");

    return obj;

   }

  }); 

 }



 public int getFunctionTotalCount() {

  log.debug("finding totalcount of tbl_function with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_function";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_function with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_function with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findTitleAll() {

  log.debug("finding tbl_title with native sql");

  Session session = this.getSession();

  try{

   String sql="select id,name,`desc` from cmsdb.tbl_title";  

   List list =  session.createSQLQuery(sql)

        .setResultTransformer(Transformers.aliasToBean(Title.class))

        .list();

   log.debug("find successful of tbl_title with native sql");

   return list;

  }catch(RuntimeException re){

   log.error("finded error of tbl_title with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }



 public List findTitleAll(final int start, final int limit) {

  log.debug("get paging of tbl_title with native sql");

  return this.getHibernateTemplate().executeFind(new HibernateCallback(){

   public Object doInHibernate(Session session) throws HibernateException, SQLException {

    Object obj = session.createSQLQuery("select id as id,name as name,`desc` as `desc` from cmsdb.tbl_title")

      .addScalar("id")

      .addScalar("name")

      .addScalar("desc")

      .setResultTransformer(Transformers.aliasToBean(Title.class))

      .setFirstResult(start)

      .setMaxResults(limit)

      .list();

    log.debug("get paging of tbl_title with native sql successful");

    return obj;

   }

  }); 

 }



 public int getTitleTotalCount() {

  log.debug("finding totalcount of tbl_title with native sql");

  Session session = this.getSession();

  try{

   String sql="select count(*) as count from cmsdb.tbl_title";  

   List list =  session.createSQLQuery(sql)

        .addScalar("count",Hibernate.INTEGER)

        .list();

   log.debug("find successful totalcount of tbl_title with native sql");

   return ((Integer)list.get(0)).intValue();

  }catch(RuntimeException re){

   log.error("finded error totalcount of tbl_title with native sql",re);

   throw re;

  }finally{

   session.close();

  }

 }

 

}


3.建立系統管理Service(SysMgrService.java):
package com.service.test;



import java.util.List;



public interface SysMgrService {

 public List findFunctionAll();

 public List findFunctionAll(final int start,final int limit);

 public int getFunctionTotalCount();

 public List findTitleAll();

 public List findTitleAll(final int start,final int limit);

 public int getTitleTotalCount();

}


4.建立系統管理Service Implement(SysMgrServiceImpl.java):
package com.service.impl.test;



import java.util.List;



import com.dao.test.SysMgrDAO;

import com.service.test.SysMgrService;



public class SysMgrServiceImpl implements SysMgrService {

 private SysMgrDAO sysMgrDAO;

 

 

 public List findFunctionAll() {

  return this.sysMgrDAO.findFunctionAll();

 }



 public List findFunctionAll(int start, int limit) {

  return this.sysMgrDAO.findFunctionAll(start, limit);

 }



 public List findTitleAll() {

  return this.sysMgrDAO.findTitleAll();

 }



 public List findTitleAll(int start, int limit) {

  return this.sysMgrDAO.findTitleAll(start, limit);

 }



 public int getFunctionTotalCount() {

  return this.sysMgrDAO.getFunctionTotalCount();

 }



 public int getTitleTotalCount() {

  return this.sysMgrDAO.getTitleTotalCount();

 }



 public SysMgrDAO getSysMgrDAO() {

  return sysMgrDAO;

 }



 public void setSysMgrDAO(SysMgrDAO sysMgrDAO) {

  this.sysMgrDAO = sysMgrDAO;

 }

}


5.建立系統管理Action(SysMgrAction.java):
package com.action.test;



import java.util.List;



import net.sf.json.JSONArray;

import com.opensymphony.xwork2.ActionSupport;

import com.service.test.SysMgrService;





public class SysMgrAction extends ActionSupport {

 /**

  * 

  */

 private static final long serialVersionUID = 1L;

 private SysMgrService sysMgrService;

 private String jsonString;

 private int start;

 private int limit;

 private String function01;

 private String grade01;



 public String getFunction() throws Exception {

  //沒有分頁功能

  //List list = this.sysMgrService.findFunctionAll();

  

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

  List list = this.sysMgrService.findFunctionAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "functoinJSON";

 }

 

 public String getFunctionAll() throws Exception {

  //沒有分頁功能

  List list = this.sysMgrService.findFunctionAll();

  String totals = String.valueOf(list.size());

  //有分頁功能  

  //String totals = String.valueOf(this.sysMgrService.getFunctionTotalCount());

  //List list = this.sysMgrService.findFunctionAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "functoinJSON";

 }

 

 public String getTitle() throws Exception {

  //沒有分頁功能

  //List list = this.sysMgrService.findTitleAll();

  

  //有分頁功能  

  String totals = String.valueOf(this.sysMgrService.getTitleTotalCount());

  List list = this.sysMgrService.findTitleAll(start, limit);

  JSONArray array = JSONArray.fromObject(list);

  this.jsonString = "{\"totals\":"+totals+",\"results\":"+array.toString()+"}";

  return "titleJSON";

 } 



 public String comboFormSubmit() throws Exception{

  this.jsonString = "{\"success\":\"true\",\"funcId\":\""+function01+"\",\"grade\":\""+grade01+"\"}";

  return "comboFormJSON";

 }

 

 public SysMgrService getSysMgrService() {

  return sysMgrService;

 }





 public void setSysMgrService(SysMgrService sysMgrService) {

  this.sysMgrService = sysMgrService;

 } 



 public String getJsonString() {

  return jsonString;

 }



 public void setJsonString(String jsonString) {

  this.jsonString = jsonString;

 }



 public int getStart() {

  return start;

 }



 public void setStart(int start) {

  this.start = start;

 }



 public int getLimit() {

  return limit;

 }



 public void setLimit(int limit) {

  this.limit = limit;

 }



 public String getFunction01() {

  return function01;

 }



 public void setFunction01(String function01) {

  this.function01 = function01;

 }



 public String getGrade01() {

  return grade01;

 }



 public void setGrade01(String grade01) {

  this.grade01 = grade01;

 }

}


6.建立comboFormJSON頁面(comboFormJSON.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags"  %>

<s:property value="jsonString" escape="false"/>


7.於struts.xml(src目錄下)設定Struts2 Action:
<action name="SysMgrJson" class="SysMgrJsonAction">

<result name="functoinJSON">JsonJSP/functionJSON.jsp</result>

<result name="titleJSON">JsonJSP/titleJSON.jsp</result>

<result name="comboFormJSON">JsonJSP/comboFormJSON.jsp</result>   

</action>


8.於applicationContext.xml(WEB-INF目錄下)設定Struts2 Action:
<!-- DAO -->

<bean id="SysMgrDAO" class="com.dao.impl.test.SysMgrDAOImpl">

<property name="sessionFactory" ref="sessionFactory"></property>

</bean>


<!-- Service -->

<bean id="SysMgrService" class="com.service.impl.test.SysMgrServiceImpl">

<property name="sysMgrDAO" ref="SysMgrDAO"></property>

</bean>


<!-- Action -->

<bean id="SysMgrJsonAction" class="com.action.test.SysMgrAction" scope="prototype">

<property name="sysMgrService" ref="SysMgrService"></property>

</bean>


三、測試結果:
1.http://localhost:8080/ExtStudy/Basic/combo1.jsp





看到此畫面,恭喜您整合開發環境設定成功!