Extjs4中的經常使用組件:Grid、Tree和Form

至此咱們已經學習了Data包和佈局等API。下面咱們來學習做爲Extjs框架中咱們用得最多的用來展示數據的Grid、Tree和Form吧!
目錄:
    5.1.3.4. 無限滾動
 
5.1. Grid panel                                          
     Grid應該是咱們在開發時使用的最多的組件之一。Extjs4對其進行了重大的改進。
     Extjs4與Extjs3的Grid生成不一樣的HTML。Sencha稱其爲智能渲染(Intelligent Rendering)。Extjs3中即便不須要Grid的全部特性,它也會生成整套HTML。而Extjs4就只會渲染Grid所用到的特性,這樣就使渲染最小化且提升了性能。
     在學習Extjs4中Grid的新特性前,讓咱們先了解在Extjs4中如何建立一個簡單的Grid吧!
Ext.create("Ext.grid.Panel", {
     store: Ext.create("Ext.data.ArrayStore", {
          fields: [{name: "book", name: "author"}],
          data: [["Ext  JS 4: First Look", "Loiane Groner"]]
     }),
     columns: [{
          text: "Book",
          flex: 1,
          sortable: false,
          dataIndex: "book"
     },{
          text: "Author",
          width: 100,
          sortable: true,
          dataIndex: "author"
     }],
     height: 80,
     widht: 300,
     title: "Simple Grid",
     renderTo: Ext.getBody()
});
經過上述的代碼片斷,咱們能夠知道Extjs4和Extjs3在建立簡單Grid時是無差異的。
 
5.1.1. Columns                                            
     Extjs4中將Grid的column類概括到一個獨立的Ext.grid.column包中。
     如今咱們一塊兒學習各種型的column吧。
     首先定義Model類和Store並加載示例數據:
     Ext.define('Book', {

extend: 'Ext.data.Model',php

fields: [html

{name: 'book'},node

{name: 'topic', type: 'string'},ajax

{name: 'version', type: 'string'},json

{name: 'released', type: 'boolean'},api

{name: 'releasedDate', type: 'date'},數組

{name: 'value', type: 'number'}服務器

]併發

});app

var store = Ext.create('Ext.data.ArrayStore', {

model: 'Book',

data: [

['Ext JS 4: First Look','Ext JS','4',false,null,0],

['Learning Ext JS 3.2','Ext JS','3.2',tr ue,'2010/10/01',40.49],

['Ext JS 3.0 Cookbook','Ext JS','3',true,'2009/10/01',44.99],

['Learning Ext JS','Ext JS','2.x',true,'2008/11/01',35.99],

]

});  
 
而後就是建立Grid了:
Ext.create('Ext.grid.Panel', {
store: store,
width: 550,
title: 'Ext JS Books',
renderTo: 'grid-example',
selModel: Ext.create('Ext.selection.CheckboxModel'), //1
columns: [
Ext.create('Ext.grid.RowNumberer'), //2
{
text: 'Book',//3
flex: 1,
dataIndex: 'book'
},{

text: 'Category', //4

xtype:'templatecolumn',

width: 100,

tpl: '{topic} {version}'

},{

text: 'Already Released?', //5

xtype: 'booleancolumn',

width: 100,

dataIndex: 'released',

trueText: 'Yes',

falseText: 'No'

},{

text: 'Released Date', //6

xtype:'datecolumn',

width: 100,

dataIndex: 'releasedDate',

format:'m-Y'

},{

text: 'Price', //7

xtype:'numbercolumn',

width: 80,

dataIndex: 'value',

renderer: Ext.util.Format.usMoney

},{

xtype:'actioncolumn', //8

width:50,

items: [{

icon: 'images/edit.png',

tooltip: 'Edit',

handler: function(grid, rowIndex, colIndex) {

var rec = grid.getStore().getAt(rowIndex);

Ext.MessageBox.alert('Edit',rec.get('book'));

}

},{

icon: 'images/delete.gif',

tooltip: 'Delete',

handler: function(grid, rowIndex, colIndex) {

var rec = grid.getStore().getAt(rowIndex);

Ext.MessageBox.alert('Delete',rec.get('book'));

}

}]

}]

 
});
效果以下:
1. 經過selModel配置項設置選擇模式,具體有三種選擇模式:RowModel、CellModel和CheckboxModel,其中CheckboxModel會自動插入Checkbox列做爲Grid的第一列;
2. 在配置columns時咱們建立了一個序號列(Ext.create("Ext.panel.RowNumberer"));
3. Book列沒有指定列類型,那麼默認以string數據類型來展示數據;
4. Category列指定列類型爲templatecolumn,就是說能夠經過tpl屬性來設置該列數據呈現的樣式。tpl屬性爲string數據類型,可經過{Model實例中name}的形式來訪問記錄中任意的字段值;
5. Already Released?列指定列類型爲booleancolumn,就是說該列對應的Model實例屬性值爲boolean類型,並且咱們能夠經過trueText和falseText來設置值爲真/假時分別呈現什麼內容;
6. Released Date列指定列類型爲datecolumn,並經過format屬性來設置以某種格式來呈現日期信息;
7. Price列指定列類型爲numbercolumn,而這裏經過設置renderer:Ext.util.Format.usMoney來設置該列的呈現樣式。renderer屬性是從Column類(全部Column類型的父類)繼承獲得的,因此各個column類都可設置該屬性,屬性值爲function(value){........; return "呈現的內容";},參數value爲該單元格中對應的Model實例的屬性值。而Ext.util.Format.usMoney是內置的格式化函數,固然咱們能夠自定義Ext.util.Format.rmbMoney的函數啦;
8. 最後一列沒有表頭並指定列類型爲actioncolumn,該列用於添加行級的增、刪、查、改等操做按鈕。
 
 
5.1.2. Feature                                        
     若是咱們想在Extjs3中爲grid添加新功能,咱們通常要建立或擴展GridPanel類。但官方沒有提供一種統一的方式去處理這個問題。在Extjs4中咱們能夠經過繼承Ext.grid.feature.Feature(類中含有公用方法和屬性)來實現上述的需求。(譯者語:具體如何定義Ext.grid.feature.Feature子類,我還沒試過)
     在Ext.grid.feature包中有7個類:AbstractSummary,Chunking,Feature,Grouping,GroupingSummary,RowBody和Summary。
     下面咱們來學習如何使用feature,具體以下
     features:[{
          groupHeaderTpl: "Publisher: {name}",
          ftype: "groupingsummary"
     }]
 
5.1.2.1. Ext.grid.feature.Grouping                                  
     直接上代碼吧!

Ext.define('Book', {

extend: 'Ext.data.Model',

fields: ['name', 'topic']

});

var Books = Ext.create('Ext.data.Store', {

model: 'Book',

groupField: 'topic',

data: [{

name: 'Learning Ext JS',

topic: 'Ext JS'

},{

name: 'Learning Ext JS 3.2',

topic: 'Ext JS'

},{

name: 'Ext JS 3.0 Cookbook',

topic: 'Ext JS'

},{

 
name: 'Expert PHP 5 Tools',

topic: 'PHP'

},{

name: 'NetBeans IDE 7 Cookbook',

topic: 'Java'

},{

name: 'iReport 3.7',

topic: 'Java'

},{

name: 'Python Multimedia',

topic: 'Python'

},{

name: 'NHibernate 3.0 Cookbook',

topic: '.NET'

},{

name: 'ASP.NET MVC 2 Cookbook',

topic: '.NET'

}]

});

Ext.create('Ext.grid.Panel', {

renderTo: Ext.getBody(),

frame: true,

store: Books,

width: 350,

height: 400,

title: 'Books',

features: [Ext.create('Ext.grid.feature.Grouping',{

groupHeaderTpl: 'topic: {name} ({rows.length} Book{[values.rows.length > 1 ? "s" : ""]})'

})],

columns: [{

text: 'Name',

flex: 1,

dataIndex: 'name'

},{

text: 'Topic',

flex: 1,

dataIndex: 'topic'

}]

 
});
 
經過上面的代碼片斷,咱們能夠看到要使用Ext.grid.feature.Grouping還要在Store中設置groupField屬性來設置分組字段名。而後經過groupHeaderTpl屬性來設置分組頭,{name}就是訪問groupField指向的字段的值,{rows.length}就是組記錄數目。
 
5.1.2.2. Ext.grid.feature.Summary                                            
     Ext.grid.feature.Summary實在Grid全部記錄行的最後插入總結行。該類繼承於Ext.grid.feature.AbstractSummary類。

Ext.create('Ext.grid.Panel', {

renderTo: Ext.getBody(),

frame: true,

store: Books,

width: 350,

height: 300,

title: 'Books',

features: [{

ftype: 'summary'

}],

columns: [{

text: 'Name',

flex: 1,

dataIndex: 'name',

summaryType: 'count',

summaryRenderer: function(value){

return Ext.String.format('{0} book{1}',

value, value !== 1 ? 's' : '');

}

},{

text: 'Topic',

flex: 1,

dataIndex: 'topic'

}]

}); 

從上述代碼片斷可知道,features配置項中咱們只需配置{ftype: "summary"},而後在須要做概括總結的列中配置summaryType和summaryRenderer便可(也就是說,不配置這兩項,那麼該列將不出現概括總結的內容)。
summaryType: 內置值有count,average,sum,min,max,能夠賦形式爲function(records){return "輸出內容";}的方法,參數records爲model實例數組;
summaryRenderer: 用於設置總結列的呈現樣式,可賦形式爲function(value, summaryValue, field){return "呈現內容";}的方法,參數value是概括總結後的值(就是通過summaryType處理後的值),參數summaryValue是全部的記錄,參數field是Model實例的當前總結列的列名。
效果以下:
 
5.1.2.3. Ext.grid.feature.GroupingSummary                              
     Ext.grid.feature.GroupingSummary是在Ext.grid.feature.Grouping和Ext.grid.feature.Summary的基礎上,爲每個分組添加了一行總結行。具體代碼以下:

Ext.create('Ext.grid.Panel', {

renderTo: Ext.getBody(),

frame: true,

store: Books,

width: 350,

height: 400,

title: 'Books',

features: [{

groupHeaderTpl: 'Topic: {name}',

ftype: 'groupingsummary'

}],

columns: [{

text: 'Name',

flex: 1,

dataIndex: 'name',

summaryType: 'count',

summaryRenderer: function(value){

return Ext.String.format('{0} book{1}',

value, value !== 1 ? 's' : '');

}

},{

text: 'Topic',

flex: 1,

dataIndex: 'topic'

}]

 
}); 
 
5.1.2.4. Ext.grid.feature.RowBody                                      
     該特性會在每行的底部插入一個<tr><td><div></div></td></tr>,供咱們現實額外的信息。
Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
frame: true,
store: Books,
width: 350,
height: 300,
title: 'Books',
features: [{
ftype: 'rowbody',
getAdditionalData: function(data, idx, record, orig) {
return {
rowBody: Ext.String.format(
'<div>->topic:<span> {0}</span></div>',
data.topic)
};
}
}],

columns: [{

text: 'Name',

flex: 1,

dataIndex: 'name'

}]

 
}); 
使用了rowBody特性後必需要定義getAdditionalData屬性,不然rowBody將不起做用。getAdditionalData值爲形如
function(data, rowIndex, record, orig){
     ........ 
     return {
          rowBody: "額外信息的展示HTML標籤",
          rowBodyCls: "額外信息的展示的CSS樣式",
          rowBodyColspan: 合併列數
     };
},其中參數data爲爲該行的數據,參數rowIndex爲行索引,參數record爲該行的model對象,參數orig表明原始的消息對象。
注意:當設置了rowBody特性後,Grid對象會有rowbodyclick、rowbodydbclick和rowbodycontextmenu三個事件可供訂閱。
 
5.1.3. Grid Plugins                                          
     Extjs4中引入了plugin包,其中包含Editing、CellEditing、RowEditing、HeaderResizing和DragDrop五個類。Editing類是一個提供通用方法和屬性給可編輯Grid的抽象類。CellEditing和RowEditing是Editing的子類。
(譯者語:本人對於features和plugins的理解是,二者都是Grid的插件,但features與Grid的耦合性更大,如Summary Feature會直接影響到Grid的Columns的配置;而plugins與Grid的耦合性較小,是在Grid上再加一層外衣,不用修改Grid的配置)
(譯者語:對於Grid Plugins這一章本人並無太多實踐經驗,由於在開發lppExt(一個搭建在Extjs框架之上,旨在更高效地開發各類管理系統的框架)時爲求通用性不多采用Grid Plugins,本節內容均以原文內容爲主)
 
5.1.3.1. Ext.grid.plugin.CellEditing                              
     CellEditing插件可讓咱們編輯Grid中特定的單元格。但咱們點擊某個可編輯的單元格時,就會呈現編輯器(editor)並供咱們編輯單元格的值。
下面是實例:
Ext.define('Contact', {
extend: 'Ext.data.Model',
fields: ['name', 'email','phone']
});
var Contacts = Ext.create('Ext.data.Store', {
model: 'Contact',
data: [
{name: 'Loiane', email: 'me@loiane.com', phone: '1234-5678'},
{name: 'Peter', email: 'peter@email.com', phone: '2222-2222'},
{name: 'Ane', email: 'ane@email.com', phone: '3333-3333'},
{name: 'Harry', email: 'harry@email.com', phone: '4444-4444'},
{name: 'Camile', email: 'camile@email.com', phone: '5555-5555'}
]
});
 
 

Ext.create('Ext.grid.Panel', {

renderTo: Ext.getBody(),

frame: true,

store: Contacts,

width: 350,

title: 'Contacts',

selType: 'cellmodel',

columns: [{

text: 'Name',

flex: 1,

dataIndex: 'name'

 
},{

text: 'Email',

flex: 1,

dataIndex: 'email',

editor: {

xtype:'textfield',

allowBlank:false

}

},{

text: 'Phone',

flex: 1,

dataIndex: 'phone',

editor: {

xtype:'textfield',

allowBlank:false

}

}],

plugins: [

Ext.create('Ext.grid.plugin.CellEditing', {

clicksToEdit: 1

})

]

 
});
上述代碼中,咱們須要注意下列幾點:
1. 除了plugins屬性設置爲CellEditing外,咱們還要設置clicksToEdit屬性。clicksToEdit屬性表示用戶點擊單元格多少次會進入編輯模式;
2. 要經過配置columns屬性中各列的editor屬性來決定該列是否爲可編輯列,editor的值類型爲Ext.form.field.Field。只有配置了editor屬性的列,在點擊其單元格時纔可進入編輯模式;
3. 另外咱們還要配置selType爲cellModel,從而使選擇模式改成可選擇單元格。該屬性默認爲rowModel,選擇模式爲選擇一整行。
 
5.1.3.2. Ext.grid.plugins.RowEditing                                    
     RowEditing插件讓咱們可對特定的行進行編輯。但咱們點擊某一行時,該行就轉換爲編輯模式了。
代碼以下:

Ext.create('Ext.grid.Panel', {

renderTo: Ext.getBody(),

frame: true,

store: Contacts,

width: 350,

title: 'Contacts',

selType: 'rowmodel',

columns: [{

text: 'Name',

flex: 1,

dataIndex: 'name'

},{

text: 'Email',

flex: 1,

dataIndex: 'email',

editor: {

xtype:'textfield',

allowBlank:false

}

},{

text: 'Phone',

flex: 1,

dataIndex: 'phone',

editor: {

xtype:'textfield',

allowBlank:false

 
}

}],

plugins: [

Ext.create('Ext.grid.plugin.RowEditing', {

clicksToEdit: 1

})

]

 
}); 
與CellEditing同樣,咱們也要設置clicksToEdit屬性。並且要爲可編輯列配置editor屬性。而selType要設置爲rowModel
 
5.1.3.3. 保存數據到服務器端                                           
     爲了將操做結果保存到服務器端,咱們須要修改Store來支持CRUD操做,具體代碼以下:

var Contacts = Ext.create('Ext.data.Store', {

model: 'Contact',

proxy: {

type: 'ajax',

api: {

read : 'contact/view.php',

 
create : 'contact/create.php',

update: 'contact/update.php',

destroy: 'contact/delete.php'

},

reader: {

type: 'json',

root: 'data',

successProperty: 'success'

},

writer: {

type: 'json',

writeAllFields: true,

encode: false,

root: 'data'

}

}

 
}); 
咱們想在工具欄中添加「新增」和「刪除按鈕」,代碼以下:

var rowEditor = Ext.create('Ext.grid.plugin.RowEditing', {

clicksToEdit: 1

 
})
 

var grid = Ext.create('Ext.grid.Panel', {

//other config options

plugins: rowEditor,

dockedItems: [{

xtype: 'toolbar',

items: [{

text: 'Add',

handler : function() {

rowEditor.cancelEdit();

// Create a record instance through the ModelManager

var r = Ext.ModelManager.create({

name: 'New Contact',

email: 'newcontact@email.com',

phone: '1111-1111'

}, 'Contact');

Contacts.insert(0, r);

rowEditor.startEdit(0, 0);

}

},{ 

text: 'Delete',

handler: function() {

var sm = grid.getSelectionModel();

rowEditor.cancelEdit();

Contacts.remove(sm.getSelection());

if (Contacts.getCount() > 0) {

     sm.select(0);

}

}

}]

}]

 
}); 
此時咱們對Grid的任何修改將暫時保存在客戶端的Store中,要保存到服務端就要調用Contacts.sync()了。
若打算每次操做後立刻將操做結果保存到服務端,就要爲Contacts配置autoSync屬性爲true了。
 
5.1.3.4. 無限滾動                                                  
     (譯者語:因沒有在API文檔中找到對應的配置項說明,並實踐中也沒有成功過,因此不打算翻譯該節內容,若你們成功實現該功能,請告之,謝謝)
 
5.2. Tree                                                      
     和Grid同樣Tree在Extjs4中被大大地簡化了。Tree和Grid同樣是Ext.panel.Table的子類,也就是說Grid中大部分能使用的功能,一樣能在Tree中使用。
咱們先回顧一下如何在Extjs3中建立一棵簡單的Tree吧

new Ext.tree.TreePanel({

renderTo: 'tree-example',

title: 'Simple Tree',

width: 200,

rootVisible: false,

root: new Ext.tree.AsyncTreeNode({

expanded: true,

children: [

{ text: "Menu Option 1", leaf: true },

{ text: "Menu Option 2", expanded: true,

children: [

{ text: "Sub Menu Option 2.1", leaf: true },

{ text: "Sub Menu Option 2.2", leaf: true}

] },

{ text: "Menu Option 3", leaf: true }

]

})

 
}); 
而在Extjs4中,咱們按以下方式建立一棵簡單樹

Ext.create('Ext.tree.Panel', {

title: 'Simple Tree',

width: 200,

store: Ext.create('Ext.data.TreeStore', {

root: {

expanded: true,

children: [

{ text: "Menu Option 1", leaf: true },

{ text: "Menu Option 2", expanded: true,

children: [

{ text: "Sub Menu Option 2.1", leaf: true },

{ text: "Sub Menu Option 2.2", leaf: true}

] },

 
{ text: "Menu Option 3", leaf: true }

]

}

}),

rootVisible: false,

renderTo: 'tree-example'

 
}); 
二者效果圖同樣的:
在Extjs4中咱們能夠看到三個與Tree相關的類:
1. NodeInterface:對Node API的封裝,表示每個數節點(譯者語:使用上與Model差很少);
2. Tree:維護各個NodeInterface實例的關係;
3. TreeStore:Store的子類,專門用於配置Tree的數據源。
 
5.2.1. Drag-and-drop and sorting                                  
     拖拽在從新排列樹節點位置時十分有用。經過下面的代碼咱們能夠實現拖拽特性:

Ext.create('Ext.tree.Panel', {

store: store,

viewConfig: {

plugins: {

ptype: 'treeviewdragdrop'

      }

},

//other properties

 
}); 

var store = Ext.create('Ext.data.TreeStore', {

proxy: {

type: 'ajax',

api: {

read : '../data/drag-drop.json',

create : 'create.php'

}

},

writer: {

type: 'json',

writeAllFields: true,

encode: false

},

autoSync:true

 
}); 
 
而實現樹節點排序代碼以下:

Ext.create('Ext.data.TreeStore', {

folderSort: true,

sorters: [{

property: 'text',

direction: 'ASC'

}]

 
});
(譯者語:本人以爲樹節點排序的功能不大實用)
 
5.2.2. Check Tree                                        
要實現可複選的樹是一件十分簡單的事情,不信請看下列實例吧:
這是樹節點的數據

[{

"text": "Cartesian",

"cls": "folder",

"expanded": true,

"children": [{

"text": "Bar",

"leaf": true,

"checked": true

},{

"text": "Column",

"leaf": true,

"checked": true

},{

"text": "Line",

"leaf": true,

"checked": false

}]

},{

"text": "Gauge",

"leaf": true,

"checked": false

},{

"text": "Pie",

     "leaf": true, 

"checked": true

 
}] 
 
操做代碼以下:

var store = Ext.create('Ext.data.TreeStore', {

proxy: {

type: 'ajax',

url: 'data/check-nodes.json'

},

sorters: [{

 
property: 'leaf',

direction: 'ASC'

}, {

property: 'text',

direction: 'ASC'

}]

});

Ext.create('Ext.tree.Panel', {

store: store,

rootVisible: false,

useArrows: true,

frame: true,

title: 'Charts I have studied',

renderTo: 'tree-example',

width: 200,

height: 250

 
});
效果以下:
 
 
5.2.3. Tree Grid                                            
     在Extjs3中Tree Grid做爲額外組件的形式被使用。而在Extjs4中它已變成原生API了。下面咱們經過實例來學習吧!

Ext.define('Book', {

 
extend: 'Ext.data.Model',

fields: [

{name: 'book', type: 'string'},

{name: 'pages', type: 'string'}

]

});

var store = Ext.create('Ext.data.TreeStore', {

model: 'Book',

proxy: {

type: 'ajax',

url: 'data/treegrid.json'

},

folderSort: true

 
}); 
到此咱們已經定義數據源了,下面咱們看Tree Grid組件的使用

Ext.create('Ext.tree.Panel', {

title: 'Books',

width: 500,

height: 300,

renderTo: Ext.getBody(),

collapsible: true,

useArrows: true,

rootVisible: false,

store: store,

multiSelect: true,

singleExpand: true,

columns: [{

xtype: 'treecolumn',

text: 'Task',

flex: 2,

sortable: true,

dataIndex: 'task'

},{

text: 'Assigned To',

flex: 1,

dataIndex: 'user',

sortable: true

}]

 
});
上面的代碼中高亮部分columns屬性和Ext.grid.Panel的columns屬性是同樣的。而要注意的是第一列的列類型爲treecolumn,那麼這列就是可展開的樹節點列了。
 
效果以下:
 
5.3. Form                                            
     Ext.form.Panel提供一個form的容器。咱們一般使用form來管理數據。在Extjs4中form由Fields、FieldContainer、FieldSet、Label和Actions組成。下面咱們先經過實例在學習Fields。
   
5.3.1. Form fields                                              
     Extjs4引入了Ext.form.field包,全部的Form field都屬於該包。咱們經過實例來看各個field的效果吧

Ext.create('Ext.form.Panel', {

frame: true,

title: 'Form Fields',

width: 340,

bodyPadding: 5,

renderTo: 'form-example',

fieldDefaults: {

labelAlign: 'left',

labelWidth: 90,

anchor: '100%'

},

items: [{

xtype: 'hiddenfield', //1

name: 'hiddenfield1',

value: 'Hidden field value'

},{

xtype: 'displayfield', //2

name: 'displayfield1',

fieldLabel: 'Display field',

value: 'Display field <span style="color:red;">value</span>'

},{

xtype: 'textfield', //3

name: 'textfield1',

fieldLabel: 'Text field',

value: 'Text field value'

},{

xtype: 'textfield', //4

name: 'password1',

inputType: 'password',

fieldLabel: 'Password field'

},{

xtype: 'textareafield', //5

name: 'textarea1',

fieldLabel: 'TextArea',

value: 'Textarea value'

},{

 
xtype: 'filefield', // 6

name: 'file1',

fieldLabel: 'File upload'

},{

xtype: 'timefield', //7

name: 'time1',

fieldLabel: 'Time Field',

minValue: '8:00 AM',

maxValue: '5:00 PM',

increment: 30

},{

xtype: 'datefield', //8

name: 'date1',

fieldLabel: 'Date Field',

value: new Date()

},{

xtype: 'combobox', //9

fieldLabel: 'Combobox',

displayField: 'name',

store: Ext.create('Ext.data.Store', {

fields: [

{type: 'string', name: 'name'}

],

data: [

{"name":"Alabama"},

{"name":"Alaska"},

{"name":"Arizona"},

{"name":"Arkansas"},

{"name":"California"}

]

}),

queryMode: 'local',

typeAhead: true

},{

xtype: 'numberfield',

name: 'numberfield1', //10

fieldLabel: 'Number field',

value: 20,

minValue: 0,

maxValue: 50

},{

xtype: 'checkboxfield', //11

name: 'checkbox1',

fieldLabel: 'Checkbox',

 
boxLabel: 'box label'

},{

xtype: 'radiofield', //12

name: 'radio1',

value: 'radiovalue1',

fieldLabel: 'Radio buttons',

boxLabel: 'radio 1'

},{

xtype: 'radiofield', //13

name: 'radio1',

value: 'radiovalue2',

fieldLabel: '',

labelSeparator: '',

hideEmptyLabel: false,

boxLabel: 'radio 2'

},{

xtype: 'multislider', //14

fieldLabel: 'Multi Slider',

values: [25, 50, 75],

increment: 5,

minValue: 0,

maxValue: 100

},{

xtype: 'sliderfield', //15

fieldLabel: 'Single Slider',

value: 50,

increment: 10,

minValue: 0,

maxValue: 100

}]

 
}); 
上述代碼片斷中,咱們設置了fieldDefaults屬性。該屬性會應用到全部label實例的field中(即繼承Ext.form.field.Base或Ext.form.FieldContainer的類)。這裏咱們設置了全部field的labelWidth爲90px,而field將佔用容器100%的寬度。
效果圖以下:
下面咱們來學習各類field吧!
1. hidden field(xtype:"hiddenfield"):用於保存不向用戶顯示但須要保存併發送到服務端的內容。例如Id,咱們並不想將Id值向用戶顯示,但在執行更新等操做時咱們須要將Id值發送到服務端;
2. display field(xtype:"displayfield"):用於顯示只讀內容;
3. text field(xtype:"textfield"):用於輸入簡單文本內容;若inputType設置爲password就會變成密碼輸入框;
4. textarea(xtype:"textareafield"):用於輸入多行簡單文本內容,是textfield的子類;
5. field upload field(xtype:"filefield"):用於文件上傳;
     如下爲繼承Trigger類的field,其中共有Picker類型和Spinner類型的field。Picker類型的field會有一個按鈕,當點擊按鈕時就會彈出一個供選擇值的彈窗。而Spinner類型的field會有個滑動塊來選擇值。
6. time field(xtype:"timefield"):經過配置minValue和maxValue屬性來限定最小和最大的時刻。如上述例子中分別設置最小時刻爲8:00 AM和最大時刻5:00 PM。而且咱們能夠經過increment設置時刻間隔(例子中設置爲30分鐘);
7. date field(xtype:"datefield"):用於設置日期。實例中設置默認值爲當前日期;
8. combox field(xtype:"combobox"或xtype:"combo"):下拉列表,須要使用Store作爲數據源;
9. number field(xtype:"numberfield"):用於輸入純數字值;若不想顯示向上向下按鈕的話就要設置如下的屬性
     hideTrigger:true,
     keyNavEnabled: false,
     mouseWheelEnabled: false
10. checkbox(xtype:"checkboxfield"或xtype:"checkbox");
11. radio field(xtype:"radiofield"或xtype:"radio"):checkbox的子類;
12. multi-slider field(xtype:"multislider"):用於在某個數值範圍內選擇多個值;
13. single slider field(xtype:"slider"或xtype:"sliderfield"):用於在某個數值範圍內選擇單個值。
 
5.3.2. Validation                                              
     對用戶輸入的不信任我想是一種軟件開發的法則了,那麼對用戶輸入的驗證是必不可少的。下面咱們就學習如下吧!

Ext.create('Ext.form.Panel', {

frame: true,

title: 'Form Fields Validation',

width: 340,

bodyPadding: 5,

renderTo: 'form-example',

fieldDefaults: {

labelAlign: 'left',

labelWidth: 90,

anchor: '100%',

msgTarget: 'under'

},

items: [{

xtype: 'textfield',

name: 'textfield1',

fieldLabel: 'Required',

allowBlank: false //1

},{

xtype: 'textfield',

name: 'textfield2',

fieldLabel: 'Min 2',

minLength: 2 //2

},{

xtype: 'textfield',

name: 'textfield3',

fieldLabel: 'Max 5',

maxLength: 5 //3

 
},{

xtype: 'textfield',

name: 'textfield7',

fieldLabel: 'Regex - Phone',

regex: /^\d{3}-\d{3}-\d{4}$/, //4

regexText: 'Must be in the format xxx-xxx-xxxx'

},{

xtype: 'textfield',

name: 'textfield4',

fieldLabel: 'Email',

vtype: 'email' //5

},{

xtype: 'textfield',

name: 'textfield5',

fieldLabel: 'Alpha',

vtype: 'alpha' //6

},{

xtype: 'textfield',

name: 'textfield6',

fieldLabel: 'AlphaNum',

vtype: 'alphanum' //7

},{

xtype: 'textfield',

name: 'textfield6',

fieldLabel: 'Url',

vtype: 'url' //8

},{

xtype: 'textfield',

name: 'textfield8',

fieldLabel: 'Custom: IP Address',

vtype: 'IPAddress' //9

}]

 
}); 
當咱們驗證某個輸入爲不合法時就須要將錯誤信息反饋給用戶,而msgTarget就是能夠配置錯誤信息是在field的side、under仍是top顯示。
驗證的類型有:
1. allowBlank:設置是否容許輸入空內容;
2. maxLength:設置輸入內容的最長字數;
3. minLength:設置輸入內容的最短字數;
4. regex:設置正在表達式來驗證輸入內容;
5. vtype:內置的驗證規則(alpha,alphanum,email,url),用於限制輸入和驗證輸入內容。固然咱們能夠自定義驗證規則

Ext.apply(Ext.form.field.VTypes, {

     IPAddress: function(v) {

     return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(v););

     },

     IPAddressText: 'Must be a numeric IP address',

     IPAddressMask: /[\d\.]/i

     });
這樣咱們就能夠vtype:"IPAddress"來用該驗證規則來限制輸入和驗證輸入內容了。
 
5.3.3. Form label                                       
     label是在form中呈現簡單文本內容的組件。代碼以下:

Ext.create('Ext.form.Panel', {

title: 'Form with Label',

width: 100,

bodyPadding: 10,

renderTo: 'form-example',

items: [{

xtype: 'label',

forId: 'myFieldId',

text: 'Just a Label',

margins: '0 0 0 10'

}]

 
}); 
 
5.3.4. Actions(操做)                                          
     對於form咱們通常執行加載數據和提交數據兩類操做。下面咱們經過實例來學習:

Ext.create('Ext.form.Panel', {

title: 'Book Info',

renderTo: 'form-example',

width: 300,

bodyPadding: 5,

fieldDefaults: {

labelAlign: 'left',

labelWidth: 90,

anchor: '100%'

},

items: [{

xtype: 'hiddenfield',

name: 'bookId'},{

xtype: 'textfield',

name: 'bookName',

fieldLabel: 'Title'

},{

xtype: 'textfield',

name: 'bookAuthor',

fieldLabel: 'Author'

}],

buttons: [{

text: 'Load',

handler: function() {

var form = this.up('form').getForm();

form.load({

url: 'data/form.json',

failure: function(form, action) {

Ext.Msg.alert("Load failed", action.result. errorMessage);

}

});

}

},{

text: 'Submit',

handler: function() {

var form = this.up('form').getForm();

form.submit({

url: 'form-submit.php',

waitMsg: 'Sending the info...',

success: function(fp, o) {

Ext.Msg.alert('Success', 'Form submitted.');

}

});

}

}]

 
}); 
     這裏咱們經過this.up("form").getForm()的方式獲得Ext.form.Basic類,而後才能對錶單進行數據合法性驗證、加載數據和提交數據等操做。
     加載數據時咱們須要調用load操做,具體設置請參考API文檔中的Ext.form.action包下的類。
加載數據的格式以下:

{

success: true,

data: {

bookId: 10,

bookName: "Ext JS 4 First Look",

bookAuthor: "Loiane Groner"

}

 
 
5.4. 總結                                                    
     經過本章的學習,我想你們已經對Grid、Tree和Form的使用有必定的瞭解。固然這裏只是簡單的介紹它們,要想用得好仍是要靠你們多實踐的!
相關文章
相關標籤/搜索