Ext學習筆記09 - ComboBox,Store

ComboBox

ComboBox是指下拉菜單,在API中找到ComboBox對應的xtype是 combo

應用 Window 佈局的筆記中的窗體,其中性別 Gender 這一項選項只有兩個(male, female),可以使用 ComboBox 控件,爲Gender 一項加上 xtype,值爲 combo

Js代碼 複製代碼 收藏代碼
  1. {   
  2.     fieldLabel:"Gender",   
  3.     xtype:"combo"  
  4. },  
{
	fieldLabel:"Gender",
	xtype:"combo"
},

 
看,已經是一個下拉框的樣子了,但是這時Photo中的圖片又顯示不出來了,還是那個原因,textfield少了一個,需要調整 索引位置。

 

ComboBox使用的過程中是很複雜的,就像Dojo中的ComboBox 和 FilteringSelect,在實際應用中的根據不同的需求,應用起來非常靈活。

 

接下來要爲下拉框中賦值,Ext 對於數據存取都封裝在了data 中,存儲數據分爲 GroupingStore,JsonStore 和SimpleStore,在這裏使用SimpleStore,它是負責解析數據的數據存儲器,通常用來存儲數組數據,通過ArrayReader來解析讀取數組,看一下ArrayReader在API中的定義

在API提供的示例中給出了ArrayReader存儲數組數據的方式,瞭解了這一點,再來看SimpleStore


SimpleStore中有兩個重要的也是最常用的構造參數,Fields 和 Data

  • data:用來存放SimpleStore目標數據,以數組形式存在
  • fields:field對象定義的數組,也可以是field名字的字符串

SimpleStore中定義的數組都是用ArrayReader來讀取的,ArrayReader是封裝的一個基礎工具類,將讀取數組這個常用的操作抽取了出來。 

 

ComboBox中兩個常用的構造參數 displayField 和 mode: 

 

displayField:

綁定到當前ComboBox中的基礎數據的field名字,未定義的默認值爲 mode='text' 或 mode='remote'

 

mode:

ComboBox 加載數據的方式,默認從遠程服務器加載,如果ComboBox加載本地數據,需要設置 mode='local'。

 

在Gender一項中,只要從本地加載數據就可以了,它的值是確定的,並且不需要修改(如果是需要配置的值或者經常變動的值需要從服務器端加載,但是隻有當點擊ComboBox向下箭頭的時候纔會從服務器端發出加載數據請求,這樣會產生用戶體驗的延遲)

 

來看代碼:

Js代碼 複製代碼 收藏代碼
  1. {   
  2.     fieldLabel:"Gender",   
  3.     xtype:"combo",   
  4.     /* 顯示 data 的 field 名稱 */  
  5.     displayField:"gender",   
  6.     /* 從本地加載數據 */  
  7.     mode:"local",   
  8.     readOnly:true,   
  9.     store:new Ext.data.SimpleStore({   
  10.             /* 定義 dataStore 名稱 */  
  11.             fields:["gender"],   
  12.             /* 定義 data 內容 */  
  13.             data:[["Male"],["Female"]]   
  14.         })   
  15. },  
{
	fieldLabel:"Gender",
	xtype:"combo",
	/* 顯示 data 的 field 名稱 */
	displayField:"gender",
	/* 從本地加載數據 */
	mode:"local",
	readOnly:true,
	store:new Ext.data.SimpleStore({
			/* 定義 dataStore 名稱 */
			fields:["gender"],
			/* 定義 data 內容 */
			data:[["Male"],["Female"]]
		})
},

 

下拉菜單的效果就出來了:

 

 同樣需要設置 readOnly 這個參數,避免用戶的誤操作。但是這樣又出現了一個問題,Ext中的ComboBox提供了一種自動匹配的功能,比如下拉菜單中有一系列數據,我們想找到javaeye這樣的選項,當輸入字母 j 的時候,下拉列表中會查詢出所有以 j 開頭的字符串,其他的選項不會顯示,也就是說,Gender中只有兩項male和female,當選擇其中之一之後,另外的選項就不會顯示了,而且是readOnly,如果第一次操作用戶選錯了,希望重選就沒有辦法操作了,除非刷新頁面,這樣是不合理的。

 

這種情況下,有另外一個構造參數可以解決這個問題:

當觸發下拉動作被激活時執行這一操作。默認的參數是“query” 即執行查詢來匹配用戶輸入結果,使用參數“all” 會顯示所有的結果。需要在ComboBox定義中加上這一句:

Js代碼 複製代碼 收藏代碼
  1. /* 顯示所有結果 */  
  2. triggerAction:"all",  
/* 顯示所有結果 */
triggerAction:"all",

 

這樣,當選中一個結果之後,再次點擊向下箭頭,所有的結果都可以被選擇。

 

照葫蘆畫瓢,在 Depart 這一項也把 textfield 換成 comboBox

 

首先Depart這個textfield有點長,我們要把它變的短一些,但是前面在整個 Window 的佈局中使用的錨點佈局而使 width 這個構造參數失效了,要改變 textfield 的長度還是需要 再使用 錨點 來進行調整

Js代碼 複製代碼 收藏代碼
  1. {   
  2.     fieldLabel:"Depart",   
  3.     anchor:"46.5%"  
  4. }  
{
	fieldLabel:"Depart",
	anchor:"46.5%"
}

 

寬度調整到46.5%以和上面的文本框對齊

 

Js代碼 複製代碼 收藏代碼
  1. {   
  2.     fieldLabel:"Depart",   
  3.     xtype:"combo",   
  4.     anchor:"46.5%",   
  5.     displayField:"depart",   
  6.     mode:"local",   
  7.     triggerAction:"all",   
  8.     store: new Ext.data.SimpleStore({   
  9.             fields:["depart"],   
  10.             data:[["Sale"],["Development"],["Management"],["Other"]]   
  11.         })   
  12. }  
{
	fieldLabel:"Depart",
	xtype:"combo",
	anchor:"46.5%",
	displayField:"depart",
	mode:"local",
	triggerAction:"all",
	store: new Ext.data.SimpleStore({
			fields:["depart"],
			data:[["Sale"],["Development"],["Management"],["Other"]]
		})
}

 

 寬度設置成46.5%,以便和上面的對齊,效果

成功!

 

把 depart 這一項內容加載的事件放到 當窗口show的時候默認顯示下拉菜單中的第一個選項:

Js代碼 複製代碼 收藏代碼
  1. showLock:false,        
  2. listeners:{   
  3.     "show":function(_window){   
  4.                 if(!_window["showLock"]){   
  5.                     _window.findByType("textfield")[4].getEl().dom.src = "../../../image/default_pic.gif";   
  6.                     _window["showLock"]=true;                  
  7.                 }   
  8.                    
  9.                 var _depart = _window.findByType("combo")[1];   
  10.                 var _store = _depart.store;   
  11.                 _depart.setValue(_store.getAt(0).get("depart"));   
  12.              }   
  13. },  
showLock:false,		
listeners:{
	"show":function(_window){
				if(!_window["showLock"]){
					_window.findByType("textfield")[4].getEl().dom.src = "../../../image/default_pic.gif";
					_window["showLock"]=true;				
				}
				
				var _depart = _window.findByType("combo")[1];
				var _store = _depart.store;
				_depart.setValue(_store.getAt(0).get("depart"));
			 }
},

 

這樣,window 調用 show 方法的時候就會默認顯示第一個值了。

 

如果下拉列表裏面沒有我需要的值怎麼辦? 對於這樣的需求可以在 Depart 後面跟上一個按鈕,允許用戶添加所需要的Depart的值,然後填充到Depart中。

 

在一行中左邊顯示 ComboBox, 右邊顯示 Button 該怎麼辦呢?這就需要用到前面說到的列布局,需要小改動一下代碼:

Js代碼 複製代碼 收藏代碼
  1. {   
  2.     fieldLabel:"Address",   
  3.     width:"400"  
  4. },{   
  5.     xtype:"panel",   
  6.     layout:"column",   
  7.     baseCls:"x-plaint",   
  8.     items:[{   
  9.         columnWidth:.5,   
  10.         layout:"form",   
  11.         labelWidth:45,   
  12.         baseCls:"x-plaint",   
  13.         items:[{   
  14.             fieldLabel:"Depart",   
  15.             xtype:"combo",   
  16.             anchor:"100%",   
  17.             displayField:"depart",   
  18.             mode:"local",   
  19.             triggerAction:"all",   
  20.             store: new Ext.data.SimpleStore({   
  21.                         fields:["depart"],   
  22.                         data:[["Sale"],["Development"],["Management"],["Other"]]   
  23.                     })   
  24.         }]   
  25.     },{   
  26.         columnWidth:.5,   
  27.         layout:"form",   
  28.         baseCls:"x-plaint",   
  29.         bodyStyle:"padding-left: 10px",   
  30.         items:[{   
  31.             xtype:"button",   
  32.             text:"Add Depart"  
  33.         }]   
  34.     }]   
  35. }  
{
	fieldLabel:"Address",
	width:"400"
},{
	xtype:"panel",
	layout:"column",
	baseCls:"x-plaint",
	items:[{
		columnWidth:.5,
		layout:"form",
		labelWidth:45,
		baseCls:"x-plaint",
		items:[{
			fieldLabel:"Depart",
			xtype:"combo",
			anchor:"100%",
			displayField:"depart",
			mode:"local",
			triggerAction:"all",
			store: new Ext.data.SimpleStore({
						fields:["depart"],
						data:[["Sale"],["Development"],["Management"],["Other"]]
					})
		}]
	},{
		columnWidth:.5,
		layout:"form",
		baseCls:"x-plaint",
		bodyStyle:"padding-left: 10px",
		items:[{
			xtype:"button",
			text:"Add Depart"
		}]
	}]
}

 

效果:

這裏面用到的佈局和顯示的一些參數,參考Ext學習筆記07 - Window及Window中的佈局 就可以了, 都是一樣一樣一樣地。

 

這篇有點兒長了,下篇繼續吧。 

 

 

這部分的代碼:

Js代碼 複製代碼 收藏代碼
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">   
  2. <html>   
  3. <head>   
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
  5. <title>ComboBox in Window</title>   
  6. <link type="text/css" rel="stylesheet" href="../../../ext/resources/css/ext-all.css">   
  7.   
  8. <script type="text/javascript" src="../../../ext/adapter/ext/ext-base.js"></script>   
  9. <script type="text/javascript" src="../../../ext/ext-all.js"></script>   
  10. <script type="text/javascript" src="../../../ext/build/locale/ext-lang-zh_CN.js"></script>   
  11.   
  12. <script type="text/javascript">   
  13.   
  14.     Ext.onReady(function(){   
  15.         var _window=new Ext.Window({   
  16.             title:"New Person",   
  17.             width:500,   
  18.             height:320,   
  19.             plain:true,   
  20.             layout:"form",   
  21.             defaultType:"textfield",   
  22.             labelWidth:45,   
  23.             bodyStyle:"padding-top: 10px; padding-left:10px;",   
  24.             defaults:{anchor:"95%"},   
  25.             items:[{   
  26.                 xtype:"panel",   
  27.                 baseCls:"x-plain",   
  28.                 layout:"column",   
  29.                 items:[{   
  30.                         columnWidth:.5,   
  31.                         layout:"form",   
  32.                         defaults:{xtype:"textfield", width:170},   
  33.                         labelWidth:45,   
  34.                         baseCls:"x-plain",   
  35.                         /*bodyStyle:"padding-top: 10px; padding-left:10px;",*/  
  36.                         items:[   
  37.                             {fieldLabel:"Name"},   
  38.                             {   
  39.                                 fieldLabel:"Gender",   
  40.                                 xtype:"combo",   
  41.                                 /* 顯示 data 的 field 名稱 */  
  42.                                 displayField:"gender",   
  43.                                 /* 從本地加載數據 */  
  44.                                 mode:"local",   
  45.                                 /* 顯示所有結果 */  
  46.                                 triggerAction:"all",   
  47.                                 readOnly:true,   
  48.                                 store:new Ext.data.SimpleStore({   
  49.                                             /* 定義 dataStore 名稱 */  
  50.                                             fields:["gender"],   
  51.                                             /* 定義 data 內容 */  
  52.                                             data:[["Male"],["Female"]]   
  53.                                         })   
  54.                             },   
  55.                             {   
  56.                                 fieldLabel:"Age",   
  57.                                 value:"25",   
  58.                                 readOnly:true  
  59.                             },   
  60.                             {   
  61.                                 xtype:"datefield",   
  62.                                 format:"Y-m-d",   
  63.                                 value:"1984-12-03",   
  64.                                 readOnly:true,   
  65.                                 fieldLabel:"Birth",   
  66.                                 listeners:{   
  67.                                     "blur":function(_df){   
  68.                                         var _age = _df.ownerCt.findByType("textfield")[2];   
  69.                                         _age.setValue(new Date().getFullYear() - _df.getValue().getFullYear());   
  70.                                     }   
  71.                                 }   
  72.                             },   
  73.                             {fieldLabel:"Phone"},   
  74.                             {fieldLabel:"Email"}   
  75.                         ]   
  76.                     },   
  77.                     {   
  78.                         columnWidth:.5,   
  79.                         layout:"form",   
  80.                         style:"padding:10px 10px 0 10px",   
  81.                         labelWidth:45,   
  82.                         baseCls:"x-plain",   
  83.                         items:[   
  84.                             {   
  85.                                 xtype:"textfield",    
  86.                                 inputType:"image",   
  87.                                 width:150,   
  88.                                 height:140,   
  89.                                 fieldLabel:"Photo"  
  90.                             }   
  91.                         ]   
  92.                     }   
  93.                 ]   
  94.             },{   
  95.                 fieldLabel:"ID",   
  96.                 width:"400"  
  97.             },{   
  98.                 fieldLabel:"Address",   
  99.                 width:"400"  
  100.             },{   
  101.                 xtype:"panel",   
  102.                 layout:"column",   
  103.                 baseCls:"x-plaint",   
  104.                 items:[{   
  105.                     columnWidth:.5,   
  106.                     layout:"form",   
  107.                     labelWidth:45,   
  108.                     baseCls:"x-plaint",   
  109.                     items:[{   
  110.                         fieldLabel:"Depart",   
  111.                         xtype:"combo",   
  112.                         anchor:"100%",   
  113.                         displayField:"depart",   
  114.                         mode:"local",   
  115.                         triggerAction:"all",   
  116.                         store: new Ext.data.SimpleStore({   
  117.                                     fields:["depart"],   
  118.                                     data:[["Sale"],["Development"],["Management"],["Other"]]   
  119.                                 })   
  120.                     }]   
  121.                 },{   
  122.                     columnWidth:.5,   
  123.                     layout:"form",   
  124.                     baseCls:"x-plaint",   
  125.                     bodyStyle:"padding-left: 10px",   
  126.                     items:[{   
  127.                         xtype:"button",   
  128.                         text:"Add Depart"  
  129.                     }]   
  130.                 }]   
  131.             }],   
  132.             showLock:false,        
  133.             listeners:{   
  134.                 "show":function(_window){   
  135.                             if(!_window["showLock"]){   
  136.                                 _window.findByType("textfield")[4].getEl().dom.src = "../../../image/default_pic.gif";   
  137.                                 _window["showLock"]=true;                  
  138.                             }   
  139.                                
  140.                             var _depart = _window.findByType("combo")[1];   
  141.                             var _store = _depart.store;   
  142.                             _depart.setValue(_store.getAt(0).get("depart"));   
  143.                          }   
  144.             },   
  145.             buttons:[   
  146.                 {   
  147.                     text:"OK",   
  148.                     handler:function(){   
  149.                         alert(this.ownerCt.buttons[1].text);   
  150.                     }   
  151.                 },   
  152.                 {text:"Cancel"}   
  153.             ]   
  154.         });   
  155.         _window.show();   
  156.     });   
  157.   
  158. </script>   
  159. </head>   
  160. <body>   
  161.   
  162. </body>   
  163. </html>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章