深入剖析ExtJS 2.2实现及应用连载(8):表单布局及验证码
2.3.2表单布局
深入剖析ExtJS 2.2实现及应用连载 版权所有,谢绝转载 作者:彭仁夔 QQ:546711211
上一小节中,我们的form表单只是用一幅图片来代替,现在我们要把它换成真正的form表单,从图中我们可以看出form区域也是需要布局的区域。因为它的内部有三个元素。这三个元素分成三行。Ext的formPanel是Panel子类,它采用了默认是form布局的形式来进行form元素的布局。
form的布局与其它的布局是有点不同,那是因为每个form元素都会有分成label部分加上输入框部分。这部分是form布局所特有的。同时它还使用每个元素都占用一行的位置。下面我们就来实现它:
代码清单2.4 login.js中代码
var form = new Ext.form.FormPanel( { ①
defaultType : 'textfield', ②
labelAlign : 'right',
labelWidth : 60,
region : "center",
defaults:{ border : false },
items : [ { ③
fieldLabel : '登录帐号',
name : 'user'
}, { ④
fieldLabel : '登录密码',
inputType : 'password',
name : 'pass'
},{ ⑤
fieldLabel : '效 验 码',
name : 'checkcode'
}],
buttons : [ { ⑥
text : '登陆'
}, {
text : '取消'
}]
});
通过new Ext.form.FormPanel既能实现form的布局,又能实现form的表单相关的功能,如验证、提交等。我们可以看到FormPanel的配置对象和Panel中有一部分是相同的,如defaults、items都是从Panel中继承来的。
因为每个items中元素都是代表form布局中一行。那么我们得定义三个Item元素。这里的item元素,实际上就是form元素。如③、④、⑤分别定义三个文本框输入组件。每个组件都应该指定其fieldLabel作为其label。name是form元素用来提交时标识,也是必不可少的。对于密码,我们还要指定其inputType来说明其采用密码的形式。
⑥处buttons是用来指定其提交和复位按钮,用它来触发提交动作发生。在②处的labelAlign、labelWidth配置项是form布局特有的配置项,它在panel中会传到form布局中做为整个form子元素的默认的配置项,也就是说如果items中组件没有指定labelAlign、labelWidth,就采用这两个值作为其对齐方式和label的宽度。②处defaultType则是指定默认组件类型,这个也是为items中子组件没有指定类型的组件提供默认的方式。Panel默认是defaultType是panel。
我们还看到region配置项,这个前一节中页面布局的region区域,说明这个form面板是在页面布局中的center区域中。这样,我们就可以看一下其效果是什么样子。发现不像原来的图片中的那样。我们会发现三个form子元素都对齐于左上角区域,而button则对齐于布局下面底部的中间区域,两者间隔太大了,不协调,那怎么办呢?这个时候,我们得通过style来让form子元素整体都移到合适的位置上来,在上面代码中②加style : padding:25px 35px 30px 16px;',的配置项,这样就移到正中的上来。但是所有paddind占位的区域和button的背景色都是默认的淡蓝色。我们要把它变成相配的白色,这个时候,只要在style改成style : 'background:#ffffff;padding:25px 35px 30px 16px;',就可以了。
上面的布局实现三行的form子元素的排列关系,但是在第三行中检验码中,它和前面二个是不太一同的。因为同行还有一个检验码的图片要显示。这个必须是在同一行中。这个是对于form布局是有点麻烦,在网上有很多解决方式,比如采用CSS来进行浮动定位,因为这里的整个页面布局元素是采用绝对定位的形式,采用CSS浮动验验码图片会出现整个布局都会混乱的情况。
在这里我们还是采用form的嵌套其它的布局的方法,尽管有点麻烦,但是不出现问题,在后面的布局章节,我们会扩展一个更简单的tabelForm布局。既能采用table来布局又有着form的特性。
所谓的嵌套其它的布局,就是先把这一行采用Panel的面板来代替,这个面板包括两个元素,一个是form子组件,一个是图片。对于这样的布局,我们可以采用column布局,把它们分成两列。按照上面布局的来仿照,我们一般会如下实现:
{ xtype : 'panel',
layout : 'column',
items : [ {
columnWidth : .6,
fieldLabel : '效 验 码',
name : 'checkcode'
}, {
xtype : 'panel',
columnWidth : .4,
html : '<img src="pic/code.gif"/>'
}]
}
如果是这样的话,那就称不上复杂了。如果把这段代码替换代码2.4中⑤处的组件代码,你会发现第三行会加出边框线出来,而且检验码输入框什么都不会显示,这是什么原因呢,是因为panel中缺省的配置项并没有应用到该panel中的items子项中来,也就是说'checkcode'组件的类型不是缺省的'textfield',而是panel。每个panel默认都是有边框线的。所以这两个都出现边框线。这个只要加上defaults:{border : false},就可以解决。而panel类型对于fieldLabel等解析不了,所以就出现空白区域。
那好,我们在'checkcode'组件中加 xtype:'textfield',这样总可以解析吧,是的,但是这个时候出现仅仅是默认是输入框,而没有标签。这也是什么原因,是因为form布局它也不会解析非form子布局中的组件。即解析其fieldLabel。现在是相当于fieldLabel无效了。这就是form布局中的麻烦之处。
我们怎么办呢?为了让formPanel能识别到checkcode'组件,我们要在该组件外面再套上一个form布局,使它成为form布局面板中的子组件,改成如下的形式:
{ columnWidth : .6,
layout : 'form',
items:[{ xtype:'textfield', fieldLabel : '效 验 码', name : 'checkcode' }]
},
这样就可以显示出标签出来了,但是输入框却出不来。因为这里要采用锚定位,一定要checkcode'组件中加anchor的配置项。我们在这里加其配置为anchor : '98%',。到现在为止,我们已经实现了form元素的布局。其验证码图片现在是静止,在下一节中,我们来实现它。
2.3.3 验证码
在上一节中,我们采用静态图片作为验证码图片,而在实际中都是动态生成的图片。这个图片是服务器端动态生成,之后写入到输出流中。因为其输出的是一个图片,所以只要在图片的src中指明这个请求生成动态图片的地址就可以得到该图片。如<img src=’getPic.jsp’>。在这里我们采用Servlet技术来动态生成图片。
首先我们得在web.xml文件中配置该Servlet及路径。在web.xml中加上如下片断:
<servlet>
<servlet-name>validationcodeServlet</servlet-name>
<servlet-class>com.morik.util.ValidationCodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>validationcodeServlet</servlet-name>
<url-pattern>/IMG.action</url-pattern>
</servlet-mapping>
这样的话,我们就可以通过如<img src=’ IMG.action’>的形式来取得图片。当然我们还得实现其生成的Servlet代码。这段代码主要是根据指定宽、高来动态生成含数字或文字的图片。生成之后写入输出流。同时把图片上的内容(数字或文字)写在session中。如果要判断就可以通过session来取得其保存的值和用户输入的值进行比较。读者可以通过网络去找到相关的实现。在光盘中给出com.morik.util.ValidationCodeServlet的实现。也可以采用这样来生成图片。
通过<img src=’IMG.action’/>只是一次获得图片,怎么实现每次点击就会更换图片呢并且不会刷新整个页面。这里我们需要了解的图片的请求和页面的请求并不是同步的。也就是说我只要再次请求该图片就可以实现局部上的刷新。只要在img标签上加onclick=“this.src= ’IMG.action?time=’+new Date()”就可以了。为什么要加上动态的时间呢,这里主要是为了防止浏览器缓存图片,对于不同的请求,它才会看作是不同的图片。
我们只要把上面代码清单中的checkcode的图片代码用下面的代码来替换:
{ width : 60,
border:false,
html : '<img id=\'checkpic\' src="IMG.action"
onclick="this.src=\'IMG.action?\'+new Date()"/>'
}
就可以动态去获取到图片。在第17章,我们会把这个checkCode生成的图片做一个组件,那么调用就更为方便了。
深入剖析ExtJS 2.2实现及应用连载 版权所有,谢绝转载 作者:彭仁夔 QQ:546711211