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',
fields: [
{name: 'book'},
{name: 'topic', type: 'string'},
{name: 'version', type: 'string'},
{name: 'released', type: 'boolean'},
{name: 'releasedDate', type: 'date'},
{name: 'value', type: 'number'}
]
});
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的使用有一定的了解。当然这里只是简单的介绍它们,要想用得好还是要靠大家多实践的!
转载请标明出处哦!http://www.cnblogs.com/fsjohnhuang/archive/2013/03/06/2945311.html