ComboBox
ComboBox是指下拉菜單,在API中找到ComboBox對應的xtype是 combo
應用 Window 佈局的筆記中的窗體,其中性別 Gender 這一項選項只有兩個(male, female),可以使用 ComboBox 控件,爲Gender 一項加上 xtype,值爲 combo
- {
- 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向下箭頭的時候纔會從服務器端發出加載數據請求,這樣會產生用戶體驗的延遲)
來看代碼:
- {
- 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定義中加上這一句:
- /* 顯示所有結果 */
- triggerAction:"all",
這樣,當選中一個結果之後,再次點擊向下箭頭,所有的結果都可以被選擇。
照葫蘆畫瓢,在 Depart 這一項也把 textfield 換成 comboBox
首先Depart這個textfield有點長,我們要把它變的短一些,但是前面在整個 Window 的佈局中使用的錨點佈局而使 width 這個構造參數失效了,要改變 textfield 的長度還是需要 再使用 錨點 來進行調整
- {
- fieldLabel:"Depart",
- anchor:"46.5%"
- }
寬度調整到46.5%以和上面的文本框對齊
- {
- 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的時候默認顯示下拉菜單中的第一個選項:
- showLock:false,
- listeners:{
- "show":function(_window){
- if(!_window["showLock"]){
- _window.findByType("textfield")[4].getEl().dom.src = "http://www.cnblogs.com/../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 該怎麼辦呢?這就需要用到前面說到的列布局,需要小改動一下代碼:
- {
- 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中的佈局 就可以了, 都是一樣一樣一樣地。
這篇有點兒長了,下篇繼續吧。
這部分的代碼:
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>ComboBox in Window</title>
- <link type="text/css" rel="stylesheet" href="http://www.cnblogs.com/../ext/resources/css/ext-all.css">
- <script type="text/javascript" src="http://www.cnblogs.com/../ext/adapter/ext/ext-base.js"></script>
- <script type="text/javascript" src="http://www.cnblogs.com/../ext/ext-all.js"></script>
- <script type="text/javascript" src="http://www.cnblogs.com/../ext/build/locale/ext-lang-zh_CN.js"></script>
- <script type="text/javascript">
- Ext.onReady(function(){
- var _window=new Ext.Window({
- title:"New Person",
- width:500,
- height:320,
- plain:true,
- layout:"form",
- defaultType:"textfield",
- labelWidth:45,
- bodyStyle:"padding-top: 10px; padding-left:10px;",
- defaults:{anchor:"95%"},
- items:[{
- xtype:"panel",
- baseCls:"x-plain",
- layout:"column",
- items:[{
- columnWidth:.5,
- layout:"form",
- defaults:{xtype:"textfield", width:170},
- labelWidth:45,
- baseCls:"x-plain",
- /*bodyStyle:"padding-top: 10px; padding-left:10px;",*/
- items:[
- {fieldLabel:"Name"},
- {
- fieldLabel:"Gender",
- xtype:"combo",
- /* 顯示 data 的 field 名稱 */
- displayField:"gender",
- /* 從本地加載數據 */
- mode:"local",
- /* 顯示所有結果 */
- triggerAction:"all",
- readOnly:true,
- store:new Ext.data.SimpleStore({
- /* 定義 dataStore 名稱 */
- fields:["gender"],
- /* 定義 data 內容 */
- data:[["Male"],["Female"]]
- })
- },
- {
- fieldLabel:"Age",
- value:"25",
- readOnly:true
- },
- {
- xtype:"datefield",
- format:"Y-m-d",
- value:"1984-12-03",
- readOnly:true,
- fieldLabel:"Birth",
- listeners:{
- "blur":function(_df){
- var _age = _df.ownerCt.findByType("textfield")[2];
- _age.setValue(new Date().getFullYear() - _df.getValue().getFullYear());
- }
- }
- },
- {fieldLabel:"Phone"},
- {fieldLabel:"Email"}
- ]
- },
- {
- columnWidth:.5,
- layout:"form",
- style:"padding:10px 10px 0 10px",
- labelWidth:45,
- baseCls:"x-plain",
- items:[
- {
- xtype:"textfield",
- inputType:"image",
- width:150,
- height:140,
- fieldLabel:"Photo"
- }
- ]
- }
- ]
- },{
- fieldLabel:"ID",
- width:"400"
- },{
- 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"
- }]
- }]
- }],
- showLock:false,
- listeners:{
- "show":function(_window){
- if(!_window["showLock"]){
- _window.findByType("textfield")[4].getEl().dom.src = "http://www.cnblogs.com/../image/default_pic.gif";
- _window["showLock"]=true;
- }
- var _depart = _window.findByType("combo")[1];
- var _store = _depart.store;
- _depart.setValue(_store.getAt(0).get("depart"));
- }
- },
- buttons:[
- {
- text:"OK",
- handler:function(){
- alert(this.ownerCt.buttons[1].text);
- }
- },
- {text:"Cancel"}
- ]
- });
- _window.show();
- });
- </script>
- </head>
- <body>
- </body>
-
</html>