利用ExtJs的Anchor可以为ExtJs自带的表单Form各个组件进行布局,当然,使用《【ExtJs】带日期组件的文本输入框、容器与Ext.Msg.alert告警框告警两次》(点击打开链接)中的vbox也是可以的。其实ExtJs的表单插件与表单布局并不是关键,ExtJs的表单验证还好,就几行语句就能够完成。关键是ExtJs的表单提交必须通过Ajax方式,而在后台必须传回一个Json完成表单的提交,可能有点复杂,下面就以php作为ExtJs的后台处理来说明问题ExtJs的表单。aspx,jsp等各位只要改好参数获取语句一样可以的。
一、基本目标
如下图,这是在Windows2003自带的纯种IE6浏览器执行的效果,首先在浏览器中有一个按钮,点击之后可以打开表单窗口,用户填写的信息必须符合要求,如果没有通过验证,表单的“确定”按钮是灰色状态,当然,点击“关闭”按钮能够随时关闭这个对话框的。
这里面有文本框、密码框、复选框、下拉列表、单选框,所有的值都能够传到后台的formSubmit.php处理之后,再传回来前台。这里不推荐使用ExtJs的颜色组件,因为所有不兼容IE6的插件都是骗人的坏人!
二、基本思想
整个表单的布局如下图,皆是纯粹的ExtJs表单组件,没有用到HTML来布置。
而Login.html这个页面的HTML布局仅仅是一个带id=btn1的按钮,其余所有布局皆由JavaScript脚本完成。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Ext表单</title>
<script type="text/javascript" src="js/ext-all.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<script type="text/javascript" src="js/ext-lang-zh_CN.js"></script>
<link href="ext-theme-classic/ext-theme-classic-all.css" rel="stylesheet" type="text/css">
</head>
<body>
<button id="btn1" type="button">打开表单</button>
</body>
</html>
三、核心脚本
1、Login.html
这个前端页面不含有任何的后端语言
(1)首先可以声明一个名为window1的window,里面的就放一个名为form1的form,指明btn1的onclick事件为显示window1。这部分与《【ExtJs】折叠式布局与卡片式布局》(点击打开链接)一模一样。不再赘述了。
var window1=Ext.create('Ext.window.Window', {
renderTo: Ext.getBody(),
header: false,
border: false, //没有边框
resizable: false, //不可以自由调整大小,默认可以
width: 400,
items:[form1]
});
window1.show();
(2)之后再声明表单使用ExtJs未能通过验证的错误消息,如果没有这两行,ExtJs对于未能通过验证的表单,不会有任何错误的提醒。
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
(3)其后是真正的核心,ExtJs的表单
var form1 = Ext.create('Ext.form.Panel', {
width: 400,
method: 'POST',
layout: 'anchor',
title: 'Ext表单',
items: [{
fieldLabel: '用户名',
xtype: 'textfield',
name: 'username',
regex: /^[A-Za-z]{4,12}$/,//正则表达式
regexText: '必须4-12个英文字符',
anchor: '90%'
}, {
fieldLabel: '密码',
xtype: 'textfield',
inputType: 'password',//密码
name: 'password',
regex: /^[A-Za-z]{4,12}$/,//正则表达式
regexText: '必须4-12个英文字符',
anchor: '90%'
}, {
fieldLabel: '复选选框',
xtype: 'checkboxgroup',
items: [{
boxLabel: '选项1',
name: 'c1'
}, {
boxLabel: '选项2',
name: 'c2',
checked: true
}]
}, {
fieldLabel: '下拉列表',
xtype: 'combobox',
layout: 'hbox',
querymode: 'local',
valueField: 'id',//列表value值使用store中的id字段
displayField: 'name',//显示值使用store中的name字段
forceSelection: true,//不得自由输入,不得为空,必须从下拉列表中选择一项
name:'combobox',
allowBlank: false,
store: {
fields: ['id', 'name'],
data: [{
'id': 'c1',
name: 'c1'
}, {
'id': 'c2',
name: 'c2'
}, {
'id': 'c3',
name: 'c3'
}]
}
}, {
fieldLabel: '单选框',
xtype: 'radiogroup',
allowBlank: false,
items: [{
boxLabel: '选项1',
name: 'radiobox',
inputValue: 'r1'
}, {
boxLabel: '选项2',
name: 'radiobox',
inputValue: 'r2'
}, {
boxLabel: '选项3',
name: 'radiobox',
inputValue: 'r3'
}]
}],
bbar: [{
xtype: 'tbfill'
}, {
xtype: 'button',
text: '确定',
disabled: true,
formBind: true,
listeners: {
click: function(){
var thisForm = form1.getForm();
thisForm.submit({
url: "formSubmit.php",
success: function(form, action){
Ext.Msg.alert('Success', action.result.msg, function(){
window1.hide();
});
}
});
}
}
}, {
xtype: 'button',
text: '关闭',
listeners: {
click: function(){
window1.hide();
}
}
}, {
xtype: 'tbfill'
}]
});
声明这个表单的宽度、提交方式、布局为anchor、标题等基本信息之后,关键是items中的内容,这里面就是ExtJs的一个又一个表单组件。
先是基本的输入框,其类型是textfield,name的设置是为了一会儿后端页面formSubmit.php获取时使用。其中regex则是验证的正则表达式,regexText就是未能通过认证时候提示的错误信息。anchor:'90%'指明这个表单占整行的90%。
随后密码框的设置,其类型同样是textfield,但要多补一个inputType: 'password',指明这个输入框为密码框。
复选选框xtype: 'checkboxgroup'与单选组xtype: 'radiogroup',没什么好说,对于单选组,记得补上一个allowBlank: false,禁止未空就可以了。
关键是下拉列表,也就是原来的<select>标签,最为复杂,这东西ExtJs默认是能让用户自由输入的,然后选项都是从后端读取的,十分高端,现在能够改到是一个普通的下拉列表,必须从里面选择一个元素,这才符合我们的思维。
最后在底部的工具栏设置左右占位符与两个按钮,这个bbar在《【ExtJs】tabPanel标签页与修改标签页的内容》(点击打开链接)已经说过了,关键是两个按钮的onclick事件,先说简单的“关闭”按钮,这个按钮必须设置window1是隐藏,不要用close()方法,这个关闭是连这个window1变量的都销毁了,再也打不开了,所以只能是隐藏。最重要的是提交按钮,首先要获取form1这个表单,然后指明其提交之后的属性,action.result.msg是接受,后端在你验证成功之后的信息。这里只写了一种情况,其实还有一个Failure的情况,完整的写法是这样的:
listeners: {
click: function(){
var thisForm = form1.getForm();
thisForm.submit({
url: "formSubmit.php",
success: function(form, action){
//成功之后怎么怎么样
},
failure: function(form, action){
//失败之后怎么怎么样
});
}
}
}
其成功与否是根据formSubmit.php这个后端网页,最终打印出来的字符串所决定的,这个字符串就是一个json
如果是这样的json,则表示这个表单提交成功,其传回值为ss的消息给前端
{
"success":true,
"msg":"ss"
}
如果把success的值从true改成failure,则表示这个表单提交失败,同样传回值为ss的消息给前端。
然后表单提交之后,通过弹窗的callback函数完成弹窗其关闭表单窗口动作,这个在《【ExtJs】带日期组件的文本输入框、容器与Ext.Msg.alert告警框告警两次》(点击打开链接)也讲过了。
综上所述,整个Login.html的代码如下,注意刚刚提到的任何代码都要写在Ext.onReady(function(){});的{}里面,这个从《【ExtJs】ExtJs4.2.1的配置与Helloworld》(点击打开链接)开始就已经多次提及。
同时注意你属性与属性之间的声明的逗号,不要以逗号完成json的结尾,否则IE系列无法识别,这在《【JavaScript】数组定义末尾请不要留下逗号》(点击打开链接)已经说过了。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Ext表单</title>
<script type="text/javascript" src="js/ext-all.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<script type="text/javascript" src="js/ext-lang-zh_CN.js"></script>
<link href="ext-theme-classic/ext-theme-classic-all.css" rel="stylesheet" type="text/css">
</head>
<body>
<button id="btn1" type="button">打开表单</button>
</body>
</html>
<script>
Ext.onReady(function(){
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
//以上这两行代码,声明表单错误验证的信息
var form1 = Ext.create('Ext.form.Panel', {
width: 400,
method: 'POST',
layout: 'anchor',
title: 'Ext表单',
items: [{
fieldLabel: '用户名',
xtype: 'textfield',
name: 'username',
regex: /^[A-Za-z]{4,12}$/,//正则表达式
regexText: '必须4-12个英文字符',
anchor: '90%'
}, {
fieldLabel: '密码',
xtype: 'textfield',
inputType: 'password',//密码
name: 'password',
regex: /^[A-Za-z]{4,12}$/,//正则表达式
regexText: '必须4-12个英文字符',
anchor: '90%'
}, {
fieldLabel: '复选选框',
xtype: 'checkboxgroup',
items: [{
boxLabel: '选项1',
name: 'c1'
}, {
boxLabel: '选项2',
name: 'c2',
checked: true
}]
}, {
fieldLabel: '下拉列表',
xtype: 'combobox',
layout: 'hbox',
querymode: 'local',
valueField: 'id',//列表value值使用store中的id字段
displayField: 'name',//显示值使用store中的name字段
forceSelection: true,//不得自由输入,不得为空,必须从下拉列表中选择一项
name:'combobox',
allowBlank: false,
store: {
fields: ['id', 'name'],
data: [{
'id': 'c1',
name: 'c1'
}, {
'id': 'c2',
name: 'c2'
}, {
'id': 'c3',
name: 'c3'
}]
}
}, {
fieldLabel: '单选框',
xtype: 'radiogroup',
allowBlank: false,
items: [{
boxLabel: '选项1',
name: 'radiobox',
inputValue: 'r1'
}, {
boxLabel: '选项2',
name: 'radiobox',
inputValue: 'r2'
}, {
boxLabel: '选项3',
name: 'radiobox',
inputValue: 'r3'
}]
}],
bbar: [{
xtype: 'tbfill'
}, {
xtype: 'button',
text: '确定',
disabled: true,
formBind: true,
listeners: {
click: function(){
var thisForm = form1.getForm();
thisForm.submit({
url: "formSubmit.php",
success: function(form, action){
Ext.Msg.alert('Success', action.result.msg, function(){
window1.hide();
});
},
failure: function(form, action){
Ext.Msg.alert('Failure', action.result.msg, function(){
window1.hide();
});
}
});
}
}
}, {
xtype: 'button',
text: '关闭',
listeners: {
click: function(){
window1.hide();
}
}
}, {
xtype: 'tbfill'
}]
});
var window1=Ext.create('Ext.window.Window', {
renderTo: Ext.getBody(),
header: false, //没有标题
border: false, //没有边框
resizable: false, //不可以自由调整大小,默认可以
width: 400,
items:[form1]
});
window1.show();
Ext.get("btn1").on("click", function(){
window1.show();
});
});
</script>
2、formSubmit.php
因此后端处理页面也就可以这样写了,当然这里没有设置错误的情况,只是获取前端,各个表单组件传过来的值,然后放到msg里面而已。
唯一值得注意的是对复选框的处理,如果前端复选框没有选,它传过来的值就为空,这里必须处理一下,否则一会打印出来的json字符串中的msg部分是不正常的,Login.html这个页面一直等不到想要的Json字符串,会一直处于无法响应的状态。使用Jsp与Aspx的朋友同样要面对这个问题,估计可能会出现空指针什么的。
<?php
$username=$_REQUEST["username"];
$password=$_REQUEST["password"];
if(empty($_REQUEST["c1"])){
$c1="off";
}
else{
$c1=$_REQUEST["c1"];
}
if(empty($_REQUEST["c2"])){
$c2="off";
}
else{
$c2=$_REQUEST["c2"];
}
$combobox=$_REQUEST["combobox"];
$radiobox=$_REQUEST["radiobox"];
echo "{
'success':true,
'msg':'传过来的用户名:{$username}<br>密码:{$password}<br>复选框的值:{$c1},{$c2}<br>下拉列表的值:{$combobox}<br>单选框的值:{$radiobox}'
}";
?>