ExtJS 3.4.0 - Build ComboBox with paging function

在ExtJS的下拉元件(ComboBox)中,如果資料量過多的話,可能會在第一次點擊時因為要

組成相關的DOM而導致瀏覽器執行指令碼過久的情形,可能會造成無回應的情況(如IE)。

因此在這邊簡單說明如何使用分頁功能,如此一來當點擊下拉時只需建立當下的分頁內容

,避免一次從後端傳回所有的資料。

前端程式

跟建立Grid一樣,您需要定義store、record,store為跟後端要求資料的儲存體,同時會定義

回傳的格式,並搭配record來取得mapping的資料。

  1. var signnoColumns = Ext.data.Record.create([{name: "code_no", type:'String'},{name: "code_na", type:'String'}]);
  2. var signnoStore = new Ext.data.Store({
  3. // load using HTTP
  4. url: "<%=request.getContextPath()%>/ActionServlet?action=composeComboBoxData",
  5. // 此讀取器可以解析JSON DATA, 並轉換成Record. Record需定義其欄位名稱與型別
  6. reader: new Ext.data.JsonReader({
  7. root: 'rows',
  8. totalProperty: 'totalRows',
  9. fields: signnoColumns
  10. })
  11. });

在這邊的record共定義了兩個欄位,分別為下拉選單的value(code_no)及text(code_na)

屬性root,表示JSON格式的key為rows,對應得值即為[{"code_no":"1", "code_na":"YES"},

{"code_no":"2", "code_na":"NO"}]

屬性totalProperty,表示JSON格式的key為totalRows,對應的為一總資料量的數值,如此才

可以提供元件算出頁數

接下來為定義ComboBox本身
  1. var signnoCombo = new Ext.form.ComboBox({
  2. valueField: 'code_no',
  3. displayName: '員工編號',
  4. allowBlank: true,
  5. typeAhead: false,
  6. triggerAction: 'all',
  7. transform:'signno',
  8. forceSelection:false,
  9. resizable:true,
  10. width:100,
  11. listWidth:250,
  12. minChars:0,
  13. lazyRender:false,
  14. store: signnoStore,
  15. displayField: 'code_na',
  16. selectOnFocus:false,
  17. pageSize:5
  18. });

  1. <input type="text" name="signno" id="signno" value="" size="10">

需注意的為設定屬性pageSize,在此設定為5表示一頁顯示五筆資料。而valueField、

displayField分別為code_no、code_na。

後端程式
  1. public void composeComboBoxData(HttpServletRequest request){
  2. System.out.println("action composeComboBoxData");
  3. DatabaseDAO dao = new DatabaseDAO();
  4. JSONObject jsonData = new JSONObject();
  5. JSONArray rowArray = new JSONArray();
  6. int start = Integer.parseInt(request.getParameter("start"));
  7. int limit = Integer.parseInt(request.getParameter("limit"));
  8. System.out.println(start+"--"+limit);
  9. int index = 0;
  10. try {
  11. Map<String, String> rowdata = new HashMap<>();
  12. ResultSet rs = dao.getResultSet("select distinct signno code_no, signno code_na from paydetail");
  13. while(rs.next()){
  14. if(index >= start && start+limit > index){
  15. rowdata.put("code_no", rs.getString("code_no"));
  16. rowdata.put("code_na", rs.getString("code_na"));
  17. rowArray.put(new JSONObject(rowdata));
  18. }
  19. index++;
  20. }
  21. jsonData.put("rows", rowArray);
  22. jsonData.put("totalRows", index);
  23. outputResponse(jsonData.toString());
  24. } catch (Exception e) {
  25. // TODO Auto-generated catch block
  26. e.printStackTrace();
  27. } finally{
  28. try {
  29. dao.releaseConnection();
  30. } catch (SQLException e) {
  31. // TODO Auto-generated catch block
  32. e.printStackTrace();
  33. }
  34. }
  35. }

在這邊要注意的是從前端固定會傳送參數start、limit,如您第一次點下拉,會傳送start => 0

、limit => 5的值到後端。此時您就可以依據查詢出來的資料集(ResultSet),來進一步組rows

key要對應的資料(應該為前5筆),totalRows要塞的是整體的數量。所以,當您點擊下一頁時

,start => 5、limit => 5,以此類推。在這邊的寫法會在每一次進入composeComboBoxData時

重新作查詢,您可以修改成第一次查詢時存進一List內,到時在下一次進入時直接針對該List

取得需要的資料區間即可,這樣就不用每一次查詢資料庫了。最後進行response輸出。



留言