深入浅出ExtJS 第四章 表单与输入控件

 4.1 制作表单
var form = new Ext.form.FormPanel({
title:'form',
defaultType:'textfield',
buttonAlign:'center',
frame:true,
width:220,
fieldDefaults:{
labelAlign:'right',
labelWidth:70
},
tiems:[{ //子组件;
fieldLabel:'文本框' //文本框组件;
}],
buttons:[{
text:'按钮'
}]
});
form.render('form');
 4.2 FormPanel和BasicForm详解
FormPanel是Ext.Panel的一个子类;实际上,表单的功能是在Ext.form.BasicForm中实现的;在获得Ext.form.FormPanel之后,随时都可以用getForm()方法获得BasicForm对象;可以在获得的BasicForm上执行"提交"和"重置"等操作;
可以把Ext.form.FormPanel放到Ext.Viewport中作为整个页面布局的一个部分,同时用items指定Ext.form.FormPanel内部的子组件;可以通过xtype来指定每个子组件的类型;
 4.3 Ext支持的输入组件
4.3.1 控件继承图
>.Ext.from.Field
>1.Ext.form.Checkbox //复选框
Ext.form.Radio //单选框
>2.Ext.form.Hidden //隐藏域
>3.Ext.form.TextField //文本输入
>1.Ext.form.NumberField //数字输入控件
>2.Ext.form.TextArea //多行文本输入
>3.Ext.form.TriggerField //选择控件
>1.Ext.form.ComboBox //下拉控件
Ext.form.TimeField //时间选取控件
>2.Ext.form.DateField //日期控件
>4.Ext.HtmlEditor //编辑器控件 4.3.2 表单控件
Ext.onReady(function(){
Ext.QuickTips.init();    //控件初始化; var form = new Ext.form.FormPanel({ //实例化对象
buttonAlign:'center', //按钮居中;
width:600,
title:'form',
frame:true, //为组件提供圆角边框;
fieldDefaults:{ //对象内部的属性都会被应用到下面的实例中(注意优先级问题);
labelAlign:'right', //右浮动;
labelWidth:70 //宽度;
},
items:[{ //单个组件或者是组件集合;
xtype:'container',
layout:'column', //布局为列;
items:[{
columnWidth:.7,
xtype:'fieldset',
checkboxToggle:true, //控件组 组头;用复选框来设置控件的展开和收缩;
title:'单纯输入', //fieldset的legend;
autoHeight:true,
defaults:{width:300}, //应用所有的子组件的宽度;
defaultType:'textfield',
items:[{ //单个组件
fieldLabel:'文本', //域标签;文本域;
name:'text'
},{
xtype:'numberfield',
fieldLabel:'数字',
name:'number'
},{
xtype:'combo',
fieldLabel:'选择',
name:'combo',
store:new Ext.data.SimpleStore({
fields:['value','text'], //将模型的字段绑定到轴;
data:[
['value1','text1'],
['value2','text2']
]
}),
displayField:'text', //
valueField:'value', //相关的数据值绑定到ComboBox;
mode:'local', //?
emptyText:'请选择'
},{
xtype:'datefield', //带有日期选择器下拉框并会自动进行日期验证的日期输入表单项;
feildLabel:'日期',
name:'date'
},{
xtype:'timefield', //带有时间下拉框和自动时间验证的input表单项;
fieldLabel:'时间',
name:'tiem'
},{
xtype:'textarea',
fieldLabel:'多行',
name:'textarea'
},{
xtype:'hidden',
name:'hidden'
}]
},{
xtype:'container',
columnWidth:.3,
layout:'form',
items:[{
xtype:'fieldset',
checkboxToggle:true,
title:'多选',
autoHeight:true,
defaultType:'checkbox',
hideLabels:true,
style:'margin-left:10px;',
bodyStyle:'margin-left:20px;',
itmes:[{
boxLabel:'穿暖',
name:'check',
value:'1',
checked:true,
width:auto
},{
boxLabel:'吃饱',
name:'check',
value:'2',
checked:true,
width:'auto'
}]
},{
xtype:'fieldset',
checkboxToggle:true,
title:'单选',
autoHeight:true,
defaultType:'radio',
hideLabels:true,
style:'margin-left:10px;',
bodyStyle:'margin-left:20px;',
items:[{
boxLabel:'*',
name:'rad',
value:'1',
checked:true
},{
boxLabel:'爱情',
name:'rad',
value:'2'
}]
}]
}]
},{
xtype:'container',
layout:'form',
items:[{
labelAlign:'top',
xtype:'htmleditor',
fieldLabel:'在线编辑器',
id:'editor',
anchor:'98%',
height:200
}]
}],
buttons:[{
text:'保存'
},{
text:'读取'
},{
text:'取消'
}]
}); form.render('form');
}) 4.3.3 基本输入控件Ext.form.Field
Ext.form.Field是所有输入控件的基类;它定义了输入控件通用的属性和功能函数;
>1.页面显示样式:clearCls/cls/fieldClass,它们分别用来定义不同状态下输入框采用的样式;
>2.控件参数配置:autoCreate/disabled,它们主要用来设置输入控件生成的DOM内容和标签内容;
>3.数据有效性校验:invalidText/msgFx,它们用来设置数据校验的方式以及如何显示错误信息;
//这些控件默认会监听blur事件,如果校验失败,就会根据msgTarget中的设置显示错误信息;通常会被设置qtip,用QuickTip显示错误信息;其他参数值:title/side/under;
var field1 = new Ext.form.Field({
fieldLabel:'qtip',
msgTarget:'qtip'
});
field1.markInvalid();
//markInvalid()函数用来显示field校验出错样式; 4.3.4 文本输入控件TextField
//专门用来输入文本数据的输入控件;
var text = new Ext.form.TextField({
fieldLabel:'单行', //<label>标签内容;
allowBlank:false, //非空检测;
emptyText:'空', //输入框默认显示信息;
maxLength:50, //最大值;
minLength:10 //最小值;
}); //表单控件最后都是放入表单中,然后渲染到div标签中;
var from = new Ext.form.FormPanel({
title:'form',
frame:true,
items:[text],
renderTo:'form'
}); 4.3.5 多行文本输入控件TextArea
var area = new Ext.form.TextArea({
width:200, //宽度;
grow:true, //根据输入内容修改自身高度;
preventScrollbars:true, //禁止滚动条,内容超出范围,自动隐藏;
fieldLabel:'多行',
...
}) 4.3.6 日期输入控件DateField
var date = new Ext.form.DateField({
fieldLabel:'日期',
emptyText:'请选择',
format:'Y-m-d', //如何保存并显示选中的日期;
disabledDays:[0,6] //禁止选择一周内的第一天和第七天;
}) 4.3.7 时间输入控件TimeField
var time = new Ext.form.TimeField({
fieldLabel:'时间',
empty:'请选择',
minValue:'10:00 AM', //设置起始时间;
maxValue:'14:00 PM',
increment:30 //设置时间间隔;
}); 4.3.8 在线编辑器HtmlEditor
var html = new Ext.form.HtmlEditor({
fieldLabel:'在线编辑器',
enableAlignments:true,
enableColors:true,
...
})
//应用对应的enable选项启用或禁用对应的功能按钮; 4.3.9 隐藏域Hidden
var hidden = new Ext.form.Hidden({
name:'hidden'
});
hidden.setValue('some thing'); //对隐藏域赋值;
var value = hidden.getValue(); //取值; 4.3.10 如何使用input type="image"
//Ext没有提供对应的控件,我们可以根据需要使用inputType对Ext.form.TextField进行修改;
var image = new Ext.form.TextField({
fieldLabel:'证件照片',
name:'smallimg',
inputType:'image',
inputAttrTpl:['src="../img/img1.png"'],
width:140,
height:120
});
//autoCreate使用的是DomHelper的语法,生成一个带有src的DOM;
 4.4 ComboBox详解
//Ext中提供的ComboBox与HTML中原生的select无任何关系,它是用div重写的; 4.4.1 ComboBox简介
var data = [ //二维数组,ComboBox将要显示的数据;
['value1','text1'],
['value2','text2']
]; var store = new Ext.data.ArrayStore({ //将二维数组转成对象;
fields:['value','text'],
data:data
});
store.load(); var combo = new Ext.form.ComboBox({
store:stroe, //传入数据;
empty:'请选择',
mode:'local', //设置:数据已经读取到本地了;
valueField:'value', //读取store里的value(对应的在data里的value);
dispalyField:'text', //读取store里的text(实际是data里的text);
triggerAction:'query', //自动补全;
value:'value1', //设置combo的value值;
renderTo:'combo' //渲染到的必须是<imput id="combo" type="text" />
}) 4.4.2 将Select转换成ComboBox
<select id="combo">
<option value='value1'>text1</option>
...
</select> var combo = new Ext.form.ComboBox({
emptyText:'请选择',
mode:'local',
triggerAction:'all',
transform:'combo' //把id="combo"的select的数据抽离出来;添加到ComboBox里;
}); 4.4.3 ComboBox结构详解
var combo = new Ext.form.ComboBox({
...
hiddenName:'comboId' //让ComboBox又增加了一个type="hidden"的input,并且它的name和id都是"comboId"
});
//若没有设置hiddenName,ComboBox提交的都是用户看到的text值;设置之后,才可以向后台提交text对应的value值; 4.4.4 ComboBox读取远程数据
var store = new Ext.data.Store({
proxy:{
type:'ajax',
url:'xxx.txt',
reader:{
type:'array'
},
fields:[
{name:'value'},{name:'text'}
]
}
}); var combo = new Ext.form.ComboBox({
..
mode:'remote', //读取远程数据;
}); 4.4.5 ComboBox高级设置
>1.添加分页功能
var combo = new Ext.form.ComboBox({
..
mode:'remote', //参数必须是remote;因为分页的前提是先到store中分批获取数据;
minListWidth:200, //下拉列表的宽度;
pageSize:5 //每次显示多少条记录;
}); >2.是否允许用户自己填写内容
//ComboBox的显示框是一个type="text"输入框,所以默认可以输入数据的;
var combo = new Ext.form.ComboBox({
...
editable:false //禁止用户填写数据;
}); 4.4.6 监听用户选择的数据
//设置事件机制监听ComboBox的事件,从而获知用户选择了哪条数据;
combo.on('select',function(comboBox){
alert(comboBox.getValue()+'-'+comboBox.getRawValue());
//getValue():返回对象的value值(value);
//getRawValue():返回表单项的原始值(text);
});
//on():要监听绑定的combo对象;
//select:要监听的事件;\
//comboBox:是被监听的combo对象本身; 4.4.7 使用本地数据实现省/市/县级联
comboProvince.on('select',function(comboBox){
var province = comboBox.getValue();
if(province == '河北'){
storeCity.proxy.data = dataCityHebei; //动态设置市;
}else if (province == '内蒙古'){
storeCity.proxy.data = dataCityNeimenggu;
}
});
comboCity.on('select',function(comboBox){
var city = comboBox.getValue(); //动态设置区;
if(city == "唐山"){
storeCounty.proxy.data = dataCountyTangshan;
}else{
storeCounty.proxy.data = dataCountyUnknow;
}
});
comboCounty.on('select',function(comboBox){
alert(comboProvince.getValue()+'-'+comboCity.getValue()+'-'+comboCounty.getValue());
});
 4.5 复选框和单选框
4.5.1 复选框
var form = new Ext.form.FormPanel({
title:'form',
buttonAlign:'center',
frame:true, //提供圆角;
url:'xxx.jsp', //Ext.form.Checkbox
items:[{ //在表单中添加控件容器;
xtype:'fieldset', //控件组,包装一组输入域的容器;渲染为HTML的fieldset;
title:'多选', //渲染为fieldset的legend;
autoHeigth:true,
defaultType:'checkbox',
hideLabels:true,
items:[ //在控件容器中添加复选框控件;
{boxLabel:'多选一',inputValue:'1',checked:true}, //默认选中;
{boxLabel:'多选二',inputValue:'2'},
{boxLabel:'多选三',inputValue:'3'},
]
}], buttons:[{
text:'提交',
handler:function(){
form.getForm.submit();
}
}]
});
form.render('form'); 4.5.2 单选按钮
//单选按钮是继承自复选框的,所以Checkbox中的所有功能都能在Radio中使用;
items:[{
xtype:'fieldset',
title:'单选',
defaultType:'radio', //findField('radio')对应的field;
hideLabels:true,
items:[
{boxLabel:'单选一',name:'radio',inputValue:'1',checked:true},
{boxLabel:'单选二',name:'radio',inputValue:'2'}
//具有相同name值的Radio控件会放在同一组;这样保证单选功能;
]
}],
buttons:[{
text:'提交',
handler:..
},{
text:'getGroupValue', //添加一个按钮;
handler:function(){ //触发器;
Ext.Msg.alert('信息',form.getForm().findField('radio').getGroupValue());
//信息弹出框;获取radio的inputValue值;
}
}] 4.5.3 CheckboxGroup和RadioGroup控件
//为复选框和单选按钮控件实现各种复杂的排列方式;
>1.横向排列
{
xtype:'checkboxgroup', //默认横排;
fieldLabel:'自动布局',
...
}
>2.竖向排列
{
xtype:'checkboxgroup',
fieldLabel:'单列',
columns:1, //显示为一竖列;
...
}
>3.多列排列
{
xtype:'checkboxgroup',
columns:3, //显示为三竖列;
vertical:true, //垂直优先;
itemsCls:'x-check-group-alt', //向组件添加Class;
...
}
 4.6 滑动条表单控件
//可以将滑动条作为一个表单空间爱你放在表单面板中进行布局,实现表单数据的修改/读取与提交功能;
>1.滑动条
var huadong = new Ext.form.FormPanel({
widrth:400,
title:'滑动条控件',
bodyStyle:'padding:10px;',
renderTo:'container',
defaultType:'sliderfield', defaults:{
anchor:'95%',
tipText:function(thumb){
return String(thumb.value)+'%';
}
},
items:[{
fieldLabel:'Sound Effects',
value:50,
name:'fx'
},{
fieldLabel:'Ambient Sounds',
value:80,
name:'ambient'
}]
}); >2.多滑块滑动条
var horizontal = new Ext.Slider({
renderTo:'multi-slider-horizontal',
width:214,
minValue:0,
maxValue:100,
values:[10,50,90],
plugins:new Ext.slider.Tip();
})
 4.7 表单布局
4.7.1 默认平铺布局
var form = new Ext.form.FormPanel({
defaultType:'textfiled',
frame:true,
fieldDefaults:{
labelWidth:60
},
items:[{fieldLabel:'默认布局'}],
}); 4.7.2 平分列布局
//使用"layout:'column'"来说明下面要使用的是列布局;然后在items指定每列中使用'columnWidth'设置每列所占总宽度的百分比;
//须手动指定使用layout:'form',这样才能在每列中正常显示输入框和对应标签;
var from = new Ext.form.FormPanel({
..
items:[{
layout:'column', //列布局;
items:[{
columnWidth:0.4, //本列占总宽度的百分比;
layout:'form', //组件内部默认布局;
defaultType:'textfield',//以下组件为文本输入控件;
items:[
{fieldLabel:'平分列1'},
{fieldLabel:'平分列2'},
]
}]
}]
}); 4.7.3 在布局中使用fielset
//在标准HTML中,需把输入项都放到fieldset中,以此来显示分组结构;
items:[
xtype:'feildset', //使用fieldset;
title:'使用fieldset', //fieldset的legend;
columnWidth:0.5,
lsyout:'form',
autoHeight:true,
defaultType:'textfield',//定义以下组件xtype;
items:[{fieldLabel:'汉字'}]
] 4.7.4 在fieldset中使用布局
//创建FieldSet对象,包含分列布局,再传入到FormPanel中; 4.7.5 自定义布局
//因为Ext.form.FormPanel继承自Ext.Panel,所以可以使用layout和items提供各种内部布局形式;
//除了Ext.form.Field之类的输入控件外,还可以使用其他Panel来装饰表单;
//使用xtype:'panel',在它里边使用img来显示图片;
{
..
items:[
{fieldLabel:'文字',xtype:'textfield'},
{xtype:'panel',html:'<div><img src='user.png' /></div>'}
]
}
 4.8 数据校验
//在Firefox下校验失败,调用submit()也不会提交;
//在IE下必须先使用form.isValid()自行判断,如果返回false,就不能在调用submit(),否则仍然会将非法数据提交到后台;
Ext.QuickTips.init(); //提示功能所需函数;
new Ext.form.TextField({
name:'text',
fieldLabel:'不为空',
allowBlank:false //输入框不能为空;
}); 4.8.2 最大长度和最小长度
new Ext.form.TextField({
fieldLabel:'字符长度',
name:'text',
minLength:5,
maxLength:10
}); 4.8.3 借助vtype
//为vtype设置属性,即可校验;
new Ext.form.TextField({
fieldLabel:'vtype校验',
name:'text',
vtype:'email/url/alpha/alphanum'
//验证邮箱/网址/英文字符/英文字符和数字;
}); 4.8.4 自定义校验规则
//允许自定义一个regex对输入数据进行校验;
new Ext.form.TextField({
fieldLabel:'自定义校验',
regex:/^[\u4E00-\u9FA5]+$/,
regexText:'只能输入汉字'
}); 4.8.5 NumberField校验
//NumberField控件不允许用户输入不符合要求的数据;
items:[{
fieldLabel:'数字',
xtype:'numberfield', //数字控件;
allowNegative:false, //不允许负值;
allowDecimals:false, //不允许小数;
decimalPrecision:4, //精确到小数点后几位;
minValue:0,
maxValue:150,
maskRe:/\d/ //阻止小数和符号的输入;
}] 4.8.6 使用后台返回的校验信息
//在服务器返回的相应中可以包含校验失败的信息;
items:[{
fieldLabel:'输入框1',
name:'text1'
},{
fieldLabel:'输入框2',
name:'text2'
}],
buttons:[{
text:'按钮',
handler:function(){
form.getForm().submit({
success:function(form,action){
Ext.Msg.alert('信息',action.result.msg);
},
failure:function(form,action){
if(action.failureType == Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('错误','后台校验失败');
}else{
Ext.Msg.alert('错误','无法访问后台');
}
}
});
}
}]
//通过actioin的failureType来判断响应失败是因为校验失败还是因为HTTP链接发生错误;
>.后台响应信息
{success:false,errors:{text1:'有问题1',text2:'有问题2'}}
//errors对应一个JSON对象,里边包含的就是错误信息;与输入框的text1和text2对应起来,最终显示在页面上;
 4.9 使用表单提交数据
>.一种原始的HTML表单形式的提交和两种Ajax形式的提交;
4.9.1 Ext默认的提交形式
Ext.onReady(function(){
var form = new Ext.form.FormPanel({
defaultType:'textfield',
title:'表单提交',
...
url:'xxx.jsp', //提交路径;
items:[{
fieldLabel:'文本框',
name:'text' //后台判断来自哪个控件;
}],
buttons:[{
text:'提交', //按钮显示文字;
handler:function(){ //提交按钮调用函数;
form.getForm.submit({ //为submit封装回调函数;
//只有后台响应为true,或响应的JSON中包含success:true时,执行;
success:function(form,action){
//参数直接调用form对象;
//action可直接从返回信息中调用JSON数据 ↓↓
Ext.Msg.alert('信息',action.result.msg);
},
failure:function(){
//Ext规定:如果响应的JSON中的success不是true,并且JSON中包含errors:{},则是判断后的业务错误;
//如果没有包含errors:{},则是链接失败;
Ext.Msg.alert('错误','操作失败!');
}
})
}
}]
});
form.render('form');
}); 4.9.2 使用HTML原始的提交形式
//Ext默认的提交形式是不会进行页面跳转的;主要是"one page one application"的形式;
//在Ext.form.FormPanel里找到form,在它上面调用submit()就可以了;
//Ext动态生成了表单,却没有把action部分添加上;
//所以需要修改按钮的handler函数↓↓↓
handler:function(){
form.getForm().getEl().dom.action = 'xxx.jsp';
//Ext中所有的控件都有el,el都是有DOM的;这个DOM模型就是Ext控件在页面上真实对应的部分了;
form.getForm().getEl().dom.submit();
//应用了HTML原始的提交形式;
} 4.9.3 单纯Ajax
//若使用外部Ajax,需要从中把字段的数据取出来;
>.form.getValues():若参数是true,就返回JSON组装的字符串;若参数是false,就返回JSON对象;
>.findField():获取表单里的控件;
var text = form.getForm().findField('text');
//用getValues(true)函数来配合Ajax获得数据;然后用Ajax传递给后台;最后判断回调;
handler:function(){
var text = form.getForm().findField('text'); Ext.Ajax.request({
method:'POST',
url:'xxx.jsp',
success:function(response){
var result = Ext.decode(response.responseText);
Ext.Msg.alert('信息',result.msg);
},
failure:function(){},
params:form.getForm().getValues(true)
})
} 4.9.4 文件上传
//为Ext.form.Field设置inputType:'file'即可;
var file = new Ext.form.FormPanel({
...
title:'文件上传',
fileUpload:true,
items:[{
xtype:'textfield',
fieldLabel:'上传',
name:'file',
inputType:'file'
}]
}) 4.9.5 文件上传控件
//FileUploadField更加美化了上传选择控件;
var fileUpload = new Ext.form.FormPanel({
..
title:'File Upload Field',
fileUpload:true,
items:[{
xtype:'fileuploadfield',
fieldLabel:'上传控件',
name:'fielduploadfield'
}]
});
 4.10 自动把数据填充到表单中
//使用Ext.data.JsonReader来负责数据的读取和转换操作;
[{text:'textField',number:12.34,dat:'2015-01-01',combo:1}]
//↑↑这里提供了JSON数据,表单中需要配置对应的reader↓↓;
var reader = new Ext.data.JsonReader({},[
{name:'text',type:'string'},
{name:'number',type:'float'},
{name:'date',type:'date',dateFormat:'Y-m-d'},
{name:'combo',type:'int'}
]);
//现在将设置好的reader放到表单中,后台返回的JSON会在这里被JsonReader()转换成对应的数据类型,供表单使用;
var form = new Ext.form.FormPanel({
..
reader:reader,
items:[{
xtype:'textfield',
fieldLabel:'文本',
name:'text'
},{
xtype:'numberfield',
fieldLabel:'数字',
name:'number'
},{
xtype:'datefield',
fieldLabel:'日期',
name:'date'
},{
xtype:'combo',
fieldLabel:'下拉',
name:'combo',
store:new Ext.data.SimpleStore({
fields:['value','text'],
data:[[1,'text1'],[2,'text2'],[3,'text3']]
}),
triggerAction:'all',
valueField:'value',
displayField:'text'
}]
})
//当调用form.load()函数时,表单会使用Ajax去后台读取需要的数据;
{
text:'读取',
handler:function(){
form.getFomr().load({url:'xx2.txt'});
}
}
//为load()传递一个url参数,指定读取数据的网址;这个网址返回的信息就是上面提到的用于向表单填充数据的JSON字符串;
上一篇:VS2010 编译 sqlite3 生成动态库和链接库


下一篇:[Day3]Scanner类、Random类、流程控制语句