Ext2.0 的 form 不單增加了時間輸入控件、隱藏輸入控件,還修改了創(chuàng)建方法,通過 formpanel 代替了原來 form , column 也根據新的布局定義更新了定義方式。總體來說,定義一個 form 更簡單便捷了。本文將通過一個實例介紹一下 2.0 的 form 的創(chuàng)建以及其大部分控件的使用方法,因水平有限,錯漏難免,忘大家多多諒解!
我們先來看看我們將要設計的 form 的情況:
呵呵, form 有點雜亂,不過在這個 fomr 里包含了絕大部分 Ext2.0 的控件,我將會和大家一起探討一下這些控件的使用。
在創(chuàng)建一個 form 之前,我們先增加以下語句:
Ext.QuickTips.init(); Ext.form.Field.prototype.msgTarget = 'side'; |
第一句的目的是為需要的元件提供提示信息功能, form 的主要提示信息就是客戶端驗證的錯誤信息了。
第二句的目的就是設置控件的錯誤信息顯示位置,主要可選的位置有:
位置值 |
描述 |
qtip
|
當鼠標移動到控件上面時顯示提示 |
title |
在瀏覽器的標題顯示,但是測試結果是和 qtip 一樣的 |
under |
在控件的底下顯示錯誤提示 |
side |
在控件右邊顯示一個錯誤圖標,鼠標指向圖標時顯示錯誤提示 |
[element id]
|
錯誤提示顯示在指定 id 的 HTML 元件中 |
這個大家可以根據各人喜好設置,我習慣使用“ side ”,這里有一點要注意的,就是注意控制控件的寬度,以防不夠寬度顯示錯誤圖標,這個下面會說到。
好了,現在創(chuàng)建我們的 form , 2.0 的方法就是直接創(chuàng)建一個 formpanel :
var simpleForm = new Ext.FormPanel({ labelAlign: 'left', title: ' 表單例子 ', buttonAlign:'right', bodyStyle:'padding:5px', width: 600, frame:true, labelWidth:80, items: [], buttons: [] }); simpleForm.render(document.body); |
在 formpanle 里,我們定義了 form 控件的標題是在左邊的( labelAlign: 'left' ); form 的標題欄顯示標題“表單的例子”;它的按鈕位置是在右對齊的( buttonAlign:'right' );邊的類型設置了內補丁 5px ( bodyStyle:'padding:5px' );總寬度是 600px ;設置了面板的邊角是圓弧過度的( frame:true ),我設置這個屬性主要目的不是因為邊角,而是因為背景,如果不設置這個,背景顏色將為白色,設置了這個將會加入海藍色的背景圖,好看點;還設置了 form 控件的標題寬度是 80px ( labelWidth:80 )。還有一些其它的設置選項,我這里就不多說,大家可以參看 2.0 的 API 。
items 數組的設置是我們的重點了, form 上的所有控件都是在這里設置的。
從 form 的結構圖中看到, form 整體上是分了兩列的(實際上不是的,呵呵)。因為要分列,所以要使用 columnLayout 類。在使用 columnLayout 類之前,我們需要了解一下 CSS 中 float 屬性的作用,改屬性主要作用是設置對象是否及如何浮動,屬性值為 none 、 left 和 right 三個。 column 設置是 left ,意思就是對象浮在左邊的。那這個有什么作用呢?其實這個和我們在 word 中輸入文字,默認文字是左對齊的,當一行文字的寬度超過頁面的寬度時將自動換行是一樣的。 我們通過一個例子來說明一下。
首先我們定義一個 div ,背景色是黑色,寬度和高度都是 200 :
<div style='background:black;width:200px;height:200px;'> </div> |
然后在里面加入 2 個 div ,每個寬度和高度都是 200 ,背景色一個是紅色,一個是綠色:
<div style='background:black;width:200px;height:200px;'> <div style='background:red;width:50px;height:50px;'></div> <div style='background:green;width:50px;height:50px;'></div> </div> |
我們來看看效果:
在沒有使用 float 之前,兩個子 div 是分別各占一行的。好,現在我們在兩個子 div 中加入“ float:left ”在看看效果:
<div style='background:black;width:200px;height:200px;'> <div style='background:red;width:50px;height:50px;float:left;'></div> <div style='background:green;width:50px;height:50px;float:left;'></div> </div> |
兩個子 div 出現在同一行了。我們復制一下兩個子 div ,粘貼兩次,然后看看效果:
<div style='background:black;width:200px;height:200px;'> <div style='background:red;width:50px;height:50px;float:left;'></div> <div style='background:green;width:50px;height:50px;float:left;'></div> <div style='background:red;width:50px;height:50px;float:left;'></div> <div style='background:green;width:50px;height:50px;float:left;'></div> <div style='background:red;width:50px;height:50px;float:left;'></div> <div style='background:green;width:50px;height:50px;float:left;'></div> </div> |
6 個子 div 有序的按左對齊方式排列在一起了,當一行的子 div 的寬度超過了父 div 的寬度時,子 div 自動換行到了第二行。
不知道大家是否看得明白?看不明白自己再動手改變一下子 div 的寬度和高度,看看效果。 column 的工作方式就是這樣的。明白這個很重要,因為在定義 checkbox 和 radio 的時候,如果想它們的選項在同一行,就要注意 column 的寬度,不然就無法讓他們在同一行。不過現在 column 是通過百分比來定義寬度的,我們只要控制好百分比就行了。
好了,我們繼續(xù)寫 form ,因為要用到 column ,所以我們先在 formpanel 的 itmes 加入一個 column 的定義:
{ layout:'column', border:false, labelSeparator:' : ', items:[] } |
代碼里定義了在這里使用的是 columnlayout ( layout:'column' );沒有邊( border:false );標題的分隔符號我們用中文冒號代替英文的冒號( labelSeparator:' : ' )。 coulmnLayout 里的控件將定義在 items 里。
我們首先在 items 里加入一個常用輸入控件,是用來輸入姓名的:
{ columnWidth:.5, layout: 'form', border:false, items: [{ xtype:'textfield', fieldLabel: ' 姓名 ', name: 'name', anchor:'90%' }] } |
我們設置了該列的寬度占總寬度的 50% ( columnWidth:.5 );在布局里放了一個 formlayout 用來放置控件( layout: 'form' ); formlayout 也是沒有邊的( border:false )。在 formlayout 里有一個類型為 textfield' ( xtype:'textfield' )的輸入控件。控件標題為姓名( fieldLabel: ' 姓名 ' ),輸入框( input )的 name 屬性設置“ name ”( name: 'name' ),輸入框的長度為列寬減去標題的寬度后的 90% ( anchor:'90%' ),余下的 10% 的是給顯示錯誤信息圖標用的。
在加入性別的 radio 控件時就要注意了,這里需要加入兩個 radio ,第一 radio 是有標題的,第二是沒有的,而且兩個 radio 加起來的寬度應該正好是余下的列寬( 50% ):
{ columnWidth:.25, layout: 'form', border:false, items: [{ style:'margin-top:5px', xtype:'radio', fieldLabel: ' 性別 ', boxLabel:' 男 ', name: 'sex', checked:true, inputValue:' 男 ', anchor:'95%' }] },{ columnWidth:.25, layout: 'form', labelWidth:0, labelSeparator:'', hideLabels:true, border:false, items: [{ style:'margin-top:5px', xtype:'radio', fieldLabel: '', boxLabel:' 女 ', name: 'sex', inputValue:' 女 ', anchor:'95%' }] } |
從代碼中可以看到,除了列寬設置為 25% 外,其它的列設置和第一控件是一樣。 Formlayout 里加入了一個類型為 radio 的控件。控件的標題是性別,控件的選擇顯示文本是男( boxLabel:' 男), input 的 name 屬性值是 sex ( name: 'sex' ),該控件默認是已選的( checked:true ),控件的值( value )是男( inputValue:' 男 ' ), input 的寬度是 95% 。在這里我還設置一個 css 屬性,頂部的外補丁為 5px ( style:'margin-top:5px' ),原因是為了選擇按鈕和標題對齊,大家可以將該屬性去掉然后看看效果。
第二個 raido 控件的列設置就有所不同,因為它不需要標題,所以要設置隱藏標題( hideLabels:true ),標題的寬度設置為 0 ( labelWidth:0 ) , 還要設置其標題分隔符號為空( labelSeparator:'' )。其余的設置和第一個 radio 的設置沒有不同,只是 input 的值不同了。
我們已經設置了 3 列, 3 列的列寬分別為 50% 、 25% 、 25% ,根據 float 的原則,下一列將從第二行開始。
在第二行第一列我們要增加的是一個日期選擇控件:
{ columnWidth:.5, layout: 'form', border:false, items: [{ xtype:'datefield', fieldLabel: ' 出生日期 ', name: 'birthday', anchor:'90%' }] } |
日期控件的列寬也是 50% ,列的其它設置沒有變化。控件的類型為 datefield ,標題是出生日期, input 的 name 屬性是 birthday , intput 寬度也是設置了 90% ,出來留出空位給錯誤信息外,還可以讓控件與上一行的姓名的寬度相同,整列看起來比較整齊。
日期控件的設置和普通文本輸入的設置一樣簡單,這里就不多說了。不過要說到的是漢化的問題。在 2.0 版自帶的本地化文件 ext-lang-zh.js 中存在一些小 bug ,我們需要自己修改一下。
首先要修改的是周的顯示,原來的定義是:
Date.dayNames = [ " 周日 ", " 周一 ", " 周二 ", " 周三 ", " 周四 ", " 周五 ", " 周六 " ]; |
因為在日期選擇中顯示的區(qū)域不夠寬,只能顯示一個漢字,所以需要將上面定義的把“周”去掉,修改為:
Date.dayNames = [ " 日 ", " 一 ", " 二 ", " 三 ", " 四 ", " 五 ", " 六 " ]; |
在年份和月份選擇中的按鈕文字還是英文“ ok ”和“ cancel ”的,這里我們也需要修改一下:
if(Ext.DatePicker){ Ext.apply(Ext.DatePicker.prototype, { todayText : " 今天 ", minText : " 日期在最小日期之前 ", maxText : " 日期在最大日期之后 ", disabledDaysText : "", disabledDatesText : "", monthNames : Date.monthNames, dayNames : Date.dayNames, nextText : ' 下月 (Control+Right)', prevText : ' 上月 (Control+Left)', monthYearText : ' 選擇一個月 (Control+Up/Down 來改變年 )', todayTip : "{0} (Spacebar)", okText : " 確定 ",
cancelText : " 取消 ",
format : "y 年 m 月 d 日 " }); } |
上面定義中黑色字體部分就是要加入的代碼。如果不喜歡默認格式是“ y 年 m 月 d 日”,需要修改:
if(Ext.form.DateField){ Ext.apply(Ext.form.DateField.prototype, { disabledDaysText : " 禁用 ", disabledDatesText : " 禁用 ", minText : " 該輸入項的日期必須在 {0} 之后 ", maxText : " 該輸入項的日期必須在 {0} 之前 ", invalidText : "{0} 是無效的日期 - 必須符合格式: {1}", format : "Y-m-d"
}); } |
修改 DatePicker 不會改變 DateField 的格式的,這個自己根據情況決定,呵呵。
我們繼續(xù),現在需要加入一個學歷的下拉選擇控件。下來選擇控件最重要的一個定義就是數據的定義的,數據定義錯誤,可能得不到我們需要的效果,也是很多朋友感覺最麻煩的地方。
{ columnWidth:.5, layout: 'form', border:false, items: [{ xtype:'combo', store: new Ext.data.SimpleStore( { fields: ["retrunValue", "displayText"], data: [[1,' 小學 '],[2,' 初中 '],[3,' 高中 '],[4,' 中專 '],[5,' 大專 '],[6,' 大學 ']] }), valueField :"retrunValue", displayField: "displayText", mode: 'local', forceSelection: true, blankText:' 請選擇學歷 ', emptyText:' 選擇學歷 ', hiddenName:'education', editable: false, triggerAction: 'all', allowBlank:false, fieldLabel: ' 學歷 ', name: 'education', anchor:'90%' }] } |
列的定義就不說了,沒變化。在 items 里,類型設置成 combo 了,在這里定義了一個 sotre 屬性,就是選擇值存儲的地方,因為是在客戶端的數據,所以使用了一個簡單存儲( SimpleStore )。在存儲里,我們通過一個數組定義了 retrunValue 和 displayText 兩個字段。 retrunValue 字段指定是提交給后臺的值, displayText 字段指定是在下拉中顯示的選擇值。然后我們在 data 里定義了幾組數據( data: [[1,' 小學 '],[2,' 初中 '],[3,' 高中 '],[4,' 中專 '],[5,' 大專 '],[3,' 大學 ']] ),我們可以看到,每組數據都是根據 fiedls 的定義來組成的,數組里第一個值就是 retrunValue 的值,第二個值就是 displayText 的值,例如 [1,' 小學 '] ,就表示 retrunValue 是 1 , displayText 是小學。
下面就是很重要的一步了,設置下拉選擇框的值和顯示文本。本例中設置了下拉選擇框的提交值對象的是存儲中的 retrunValue 字段( valueField :"retrunValue" ),顯示文本是存儲中的 displayText 字段( displayField: "displayText" ),通過這兩個設置就可將存儲中的數據和下拉框對應起來。
因為數據是在本地,所以設置了模式為 local ( mode: 'local' )。該下拉列表只允許選擇,不允許輸入( editable: false ),而且是必須選擇一個選項( forceSelection: true )。在沒有選擇值時顯示為選擇學歷( emptyText:' 選擇學歷 ' )。提交 form 時,該項如果沒有選擇,則提示錯誤信息“請選擇學歷”( blankText:' 請選擇學歷 ' )。該選項值不允許為空( allowBlank:false )。 大家要注意的是 hiddenName 和 name 屬性, name 只是改下拉的名稱,作用是可通過,而 hiddenName 才是提交到后臺的 input 的 name 。如果沒有設置 hiddenName ,在后臺是接收不到結構的,這個大家一定要注意。
因為這個下拉是只能選擇的,所以一定要設置屬性 triggerAction 為 all ,不然當你選擇了某個選項后,你的下拉將只會出現匹配選項值文本的選擇項,其它選擇項是不會再顯示了,這樣你就不能更改其它選項了。
如果要為控件設置默認值,就設置屬性 value , value 的值要設置為提交給后臺的值,不要設置為顯示文本。例如本例要設置大學為默認值得,則設置 value 的值為 6 。
現在到第三行了,我們要創(chuàng)建一個 checkbox 選項輸入:
{ columnWidth:.35, layout: 'form', border:false, items: [{ xtype:'checkbox', fieldLabel: ' 權限組 ', boxLabel:' 系統(tǒng)管理員 ', name: 'popedom', inputValue:'1', anchor:'95%' }] },{ columnWidth:.2, layout: 'form', labelWidth:0, labelSeparator:'', hideLabels:true, border:false, items: [{ xtype:'checkbox', fieldLabel: '', boxLabel:' 管理員 ', name: 'pepedom', inputValue:'2', anchor:'95%' }] },{ columnWidth:.2, layout: 'form', labelWidth:0, labelSeparator:'', hideLabels:true, border:false, items: [{ xtype:'checkbox', fieldLabel: '', boxLabel:' 普通用戶 ', name: 'pepedom', inputValue:'3', anchor:'95%' }] },{ columnWidth:.25, layout: 'form', labelWidth:0, labelSeparator:'', hideLabels:true, border:false, items: [{ xtype:'checkbox', fieldLabel: '', boxLabel:' 訪客 ', name: 'pepedom', inputValue:'4', anchor:'95%' }] } |
checkbox 的設置和 radio 的設置大同小異,大家注意列寬的定義就行。
第四行的兩個輸入框主要是測試通過 vtypes 屬性來驗證輸入框的輸入的:
{ columnWidth:.5, layout: 'form', border:false, items: [{ xtype:'textfield', fieldLabel: ' 電子郵件 ', name: 'email', vtype:'email', allowBlank:false, anchor:'90%' }] },{ columnWidth:.5, layout: 'form', border:false, items: [{ xtype:'textfield', fieldLabel: ' 個人主頁 ', name: 'url', vtype:'url', anchor:'90%' }] }] } |
這里的定義和普通的文本輸入框沒什么區(qū)別,只是多了一個 vtypes 的屬性定義。 Vtypes 里總共定義了 email 、 url 、 alpha 和 alphanum 四種類型數據格式, email 和 url 這個不用介紹了,呵呵。 alpha 是字母和下劃線的組合, alphanum 是字母、下劃線和數字的組合。
下面要加入一個 tabpanel ,加入 3 個 tab 頁。
{ xtype:'tabpanel', plain:true, activeTab: 0, height:235, defaults:{bodyStyle:'padding:10px'}, items:[] } |
要注意的是,這個 tabpanel 不是在上面 coulmn 的 items 里加的,因為不在 column 里。我們加在 formpanel 里。把 item 類型設置為 'tabpanel' 就行了,然后將標簽頁頭的背景設置為透明的( plain:true ),當前活動的標簽頁是第一頁( activeTab: 0 ),高度設置為 235px ( height:235 ), tab 頁的面板使用內補丁 10px ( defaults:{bodyStyle:'padding:10px'} )。
好了,現在在 tabpanel 的 items 加入標簽頁。第一頁主要有兩個輸入控件,一個是 vtypes 類型 alphanum 的登錄輸入框和一個密碼輸入框。
{ title:' 登錄信息 ', layout:'form', defaults: {width: 230}, defaultType: 'textfield',
items: [{ fieldLabel: ' 登錄名 ', name: 'loginID', allowBlank:false, vtype:'alphanum', allowBlank:false },{ inputType:'password', fieldLabel: ' 密碼 ', name: 'password', allowBlank:false }] } |
在標簽定義了,設置了標簽標題是登錄信息( title:' 登錄信息 ' ),控件容器是 formlayout ( layout:'form' ),控件的默認寬度是 230px ( defaults: {width: 230} ),默認控件類型是 textfield ( defaultType: 'textfield' )。
兩個控件的定義與前面的 textfield 定義沒什么區(qū)別,只是密碼輸入框需要定義 input 控件的類型為 password ( inputType:'password' )。兩個控件都不允許為空( allowBlank:false )。
第二個標簽頁里有 numberfield 、 timefield 和 textfield 三個控件:
{ title:' 數字時間字母 ', layout:'form', defaults: {width: 230}, defaultType: 'textfield',
items: [{ xtype:'numberfield', fieldLabel: ' 數字 ', name: 'number' },{ xtype:'timefield', fieldLabel: ' 時間 ', name: 'time' },{ fieldLabel: ' 純字母 ', name: 'char', vtype:'alpha' }] } |
Numberfield 顧名思義就是只能輸入數字的輸入控件。在該例子,沒做最大值、最小值任何限制,如果要設置最大值和最小值,分別設置 maxValue 和 minValue 兩個屬性就行了。如果要設置數字輸入長度,例如身份證號碼,可以設置 maxLength 和 minLength 兩個屬性。可以通過設置 maxText 、 minText 、 maxLengthText 和 minLengthText 設置各自的驗證出錯信息。可通過 allowDecimals 屬性設置是否只允許輸入整型值,默認值是 true ,允許輸入浮點數。設置 allowNegative 設置是否只允許輸入正數,默認值是 true ,允許輸入正負數。通過 decimalPrecision 屬性可設置小數點后的位數,默認值是 2 位。
timefield 是新增加的時間輸入控件,起彌補日期輸入控件不能輸入時間的作用。它的定義也很簡單,設置類型為 timefield 就行了。 timefield 默認時間格式是 12 小時制的,我們可通過修改 format 屬性來修改其數據格式。通過設置 increment 屬性可設置下拉選擇值得時間區(qū)間,默認值是 15 分鐘的。還可以和數字輸入控件一樣設置最大值和最小值。下拉的設置和 combobox 是一樣的。
在目前的版本中, timefield 類還沒有漢化,所以我們要在本地文件中加入 timefield 的漢化定義:
if(Ext.form.TimeField){ Ext.apply(Ext.form.TimeField.prototype, { format:'G:i:s', minText : " 該輸入項的時間必須大于或等于: {0}", maxText : " 該輸入項的時間必須小于或等于: {0}", invalidText : "{0} 不是有效的時間 ", }); } |
在這里,我默認定義了時間格式是 24 小時制的,小時為個位數是不加前綴 0 。
最后一個加入的是測試純字母輸入的,和 email 等是一樣的,我就不介紹了。
在最后一個 tab 頁中加入了一個 textarea 輸入:
{ title:' 文本區(qū)域 ', layout:'fit', items: { xtype:'textarea', id:'area', fieldLabel:'' } } |
和 textfield 一樣,只要設置類型為 textarea 就可以了,唯一的區(qū)別是為了讓 textarea 和面板自適應面板,使用了 fitlayout 作為它的容器,所以在這里我們不用設置 textarea 的寬度和高度。
最后一步就是為 form 添加按鈕了,在 formpanel 的 buttons 屬性中我們加入了一個保存按鈕和取消按鈕:
buttons: [{ text: ' 保存 ', handler:function(){ if(simpleForm.form.isValid()){ this.disabled=true; simpleForm.form.doAction('submit',{ url:'test.asp', method:'post', params:'', success:function(form,action){ Ext.Msg.alert(' 操作 ',action.result.data); this.disabled=false; }, failure:function(){ Ext.Msg.alert(' 操作 ',' 保存失敗! '); this.disabled=false; } }); } } },{ text: ' 取消 ', handler:function(){simpleForm.form.reset();} }] |
在 formpanel 類中, form 屬性指向的是 formpanle 里的 basicform 對象,我們可通過 formpanle.form 來使用該 basicform 對象。在被例子,我們已經將 formpanel 對象賦值給了 simpleForm 這個變量,所以我們可以通過 simpleForm.form 訪問面板里的 basicform 對象。
在 buttons 里定義的按鈕默認是 Ext.Button ,所以按鈕的屬性定義可以查看 Ext.Button 的 API 。在這里兩個按鈕都沒用到其它屬性,只是設置了顯示文本( text )和單擊事件。
保存按鈕要做的就是先做 basicform 的客戶端驗證( simpleForm.form.isValid() ),驗證通過了則設置該按鈕狀態(tài)為 disable ,防止 2 次提交。然后調用 simpleForm.form.doAction 方法提交數據。 doAction 方法的第一個參數“ submit ”的意思是表示執(zhí)行的是提交操作,提交的后臺頁面是 test.asp ( url:'test.asp' ),提交方式是 post ( method:'post' ),沒有其它提交參數( params:'' ),提交成功后執(zhí)行 success 定義的函數,本例只是顯示一個保存成功信息。 后臺返回的數據格式是需要我們注意的,一定要 json 格式,而且必須包含“ success:true ”,不然不會執(zhí)行 success 定義的函數。 success 定義的函數返回兩個參數,第一是 form 本身,第二個是 ajax 返回的響應結果,在 action.result 這個 json 數組了保存了后臺返回的數據。例如本例后臺返回的 json 結構是“ {success:true,data:~~~} ”,其中 data 部分我將提交的數據將字段名和數據組合成一個字符串。在 success 函數中,我通過“ Ext.Msg.alert(' 操作 ',action.result.data); ”將 data 數據顯示出來。我們還定義 failure 函數,就是網絡通訊存在問題的時候將顯示錯誤信息。
取消按鈕就是簡單的 reset 一下 form 的控件。
如果想 form 按以前的老辦法提交,可以在 formpanel 的定義中加入一下設置:
} |
第一個設置的目的是取消 formpanel 的默認提交函數。第二就是設置新的提交方式為舊方式提交。
至此,我們已經簡單的學習一次 2.0 版中的 form 控件,希望大家能從中獲得收益。如果有什么疑問和建議,請聯系我。多謝!
本例子的代碼請單擊 這里 下載,例子在 form 目錄下。
本例子的完整代碼:
|
后臺文件的代碼 (ASP) :
|
CSS 屬性 float 的測試文件代碼:
|
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
