PHP完全自学手册(珍藏版) 中文pdf扫描版下载
CActiveForm提供了一些方法,这些方法能够方便的去创建一个与数据模型相关联的Form表单。CActiveForm继承自CWidget,所以他需要实现CWidget的init() 和 run() 方法,同时它也实现了一些自己的封装方法。CActiveForm很重要的一个特性就是它支持Ajax校验。我们可以设置CActiveForm的enableAjaxValidation属性为ture来启动Ajax校验。例如,当用户在input框中输入一些值后就会触发Ajax校验。CActiveForm会向服务器提交Ajax请求,用来校验用户当前输入的值。服务器的校验一般是调用模型类Model的validate()方法。如果校验失败,相对应的错误信息将会被返回并显示给用户。即使用户在浏览器禁用javascript,他也会通过整个页面的提交自动回滚到传统的页面验证。
在客户端,Yii认为input框可以存在四个状态:初始化,校验,错误和成功。为了区分这些状态,CActiveForm自动指定了不同的CSS样式给包含此input框的HTML
element。默认情况下,这些CSS样式类的名字为:validating,error,success。当然我们可以使用CActiveForm的options属性去自定义他们。
CActiveForm的提交和校验是基于Ajax模式的。如果你的Form表单中有很大量的数据需要提交,那么这种Ajax模式的提交可能就不那么好了。这种情况下,你可以设计自己轻量级的Ajax校验。使用Yii对JQuery的支持?
使用CActiveForm来做Ajax校验,我们需要使用两个JS库:jquery.js和jquery.yiiactiveform.js。他们的位置在工程根目录下:assets\5ce53e17\文件夹中。不用担心,这些JS库Yii会自动发布到你的工程中。虽然这些动作Yii会悄悄的做,当你必须知道。
首先我们来看我们的模型类,这里我们使用CFormModel:
1 class LoginForm extends CFormModel 2 { 3 public $username; 4 public $password; 5 public function rules() 6 { 7 return array( 8 array('username, password', 'required'), 9 array('username', 'authenticate'), 10 ); 11 } 12 public function authenticate($attribute,$params) 13 { 14 if($this->username=='admin') 15 $this->addError('username','can not login with admin!'); 16 } 17 }
我们的模型类非常简单,只有username和passsword两个属性。username的校验规则是不为空,且不能是“admin”,而password的校验规则只是不为空。注意,当我们检查到用户输入的username的值为“admin”时候,校验失败,我们添加错误信息为“can
not login with admin”,这段信息会在页面中的Yii提供的error元素中输出。
我们可以在rules方法中指定任何一条验证规则的错误信息,我们需要使用message属性。例如:array(‘username’, ‘required’,'message’=>’not
null’),当‘username’的内容为空的时候,我们会使用message指定的内容在页面上显示错误信息。当然我们可以使用中文,如果出现乱码,可以这样设置:array(‘username’,
‘required’,'message’=>iconv(“gb2312″,”utf-8″,”不能为空“))
你将main.php里的app配置加上language=>’zh_cn’,系统默认的提示就是中文的了!
其他验证规则案例:
array(‘title, content,
status’, ‘required’),
array(‘title’, ‘length’,
‘max’=>128),
array(‘status’, ‘in’,
‘range’=>array(0, 1, 2)),
array(‘tags’, ‘match’,
‘pattern’=>’/^[\w\s,]+$/’,'message’=>’Tags can only contain word
characters.’),
我们的页面代码如下:
1 <div class="form"> 2 <?php $form=$this->beginWidget('CActiveForm', 3 array('id'=>'login-form','enableAjaxValidation'=>true,'action'=>array('site/login'))); ?> 4 <div class="row"> 5 <?php echo $form->labelEx($model,'username'); ?> 6 <?php echo $form->textField($model,'username'); ?> 7 <?php echo $form->error($model,'username'); ?> 8 </div> 9 <div class="row"> 10 <?php echo $form->labelEx($model,'password'); ?> 11 <?php echo $form->passwordField($model,'password'); ?> 12 <?php echo $form->error($model,'password'); ?> 13 </div> 14 <div class="row submit"> 15 <?php echo CHtml::submitButton('Login'); ?> 16 </div> 17 <?php $this->endWidget(); ?> 18 </div>
对于每一个模型属性的页面表示来说,我们都会有一个Label来说明其属性名,还有一个input框用来输入该属性值,最后有个error元素来显示校验失败时的错误信息。Yii对Form及其子元素封装的太多,我们将以上php代码翻译成静态页面为:
1 <div class="form"> 2 <form id="login-form" action="/validator/index.php?r=site/login" method="post"> 3 <div class="row"> 4 <label for="LoginForm_username" class="required">Username 5 <span class="required">*</span></label> 6 <input name="LoginForm[username]" id="LoginForm_username" type="text" value="" /> 7 <div id="LoginForm_username_em_" class="errorMessage" style="display:none"></div> 8 </div> 9 <div class="row"> 10 <label for="LoginForm_password" class="required">Password 11 <span class="required">*</span></label> 12 <input name="LoginForm[password]" id="LoginForm_password" type="password" value="" /> 13 <div id="LoginForm_password_em_" class="errorMessage" style="display:none"></div> 14 </div> 15 <div class="row submit"> 16 <input type="submit" name="yt0" value="Login" /> 17 </div> 18 </form> 19 </div>
Yii的Ajax的校验效果是通过CSS来实现的,上文提到一个input框可以存在四个状态:初始化,校验,错误和成功。每个状态对应不同CSS样式类。初始化和校验这两个状态我们不需要关心,我们只注重用户校验失败和成功时,该input框的CSS样式。此外当校验失败的时候,我们还要定义错误信息的样式,从翻译过来的静态文本来来,我们需要定义errorMessage类。以下是我的CSS类:
/*标签是否换行*/
.form label {
font-size:12px; display:block; }
/*属性是否必填项,客户端根据model的rule方法而定*/
.form span.required {
color:red; }
/*校验出错时标签CSS样式*/
.form .error label {
color:#FFCC33; }
/*校验出错时输入框的CSS样式*/
.form .error input {
background:#FEE; border-color:#C00; }
/*校验出错时错误信息的CSS样式,我们可以设置其display属性让其不换行。*/
.form .errorMessage {
display:inline; color:red; font-size:12px; }
/*校验成功时标签CSS样式*/
.form .success label {
color:#000000; }
/*校验成功时输入框的CSS样式*/
.form .success input {
background:#E6EFC2; border-color:#C6D880; }
以上的CSS注释已经很详细了,我们来看看校验流程,首先我们需要先渲染我们的页面:
$model = new LoginForm;
$this->render(‘index’,array(‘model’=>$model));
注意,这里我们必须使用render()方法对其进行渲染。
我们的actionLogin如下:
public function actionLogin() { $model = new LoginForm; //ajax validate if(isset($_POST['ajax']) && $_POST['ajax']==='login-form') { echo CActiveForm::validate($model); Yii::app()->end(); } //submit handle and validate if(isset($_POST['LoginForm'])) { $model->attributes = $_POST['LoginForm']; if($model->validate()){ //no business logic handle $this->renderPartial('success'); Yii::app()->end(); } } $this->render('index',array('model'=>$model)); }
当input框失去焦点的时候,页面会向服务器提交Ajax请求,服务器端就会根据模型类LoginForm中定义的校验规则就其就行验证。如果校验成功,则input框会按指定的success样式类去显示,如果校验失败,则input框会按指定的error样式类去显示,同时还会按照errorMessage指定的样式类显示错误信息。
需要注意的是,如果我们对用户输入的信息进行了校验,而且有可能校验失败,但是用户在校验失败的情况下,仍然可以提交Form表单。所以当用户提交Form表单的处理代码中,我们仍需要对用户的输入进行校验。
CActiveForm其他组件的使用
1. textArea
这个组件没有太多讲的,主要注意行列的属性配置,使用代码:
<?php echo
$form->textArea($model,’textArea’,array(‘rows’=>10,’cols’=>50)); ?>
2. fileField
虽然Yii封装了这个组件,但是它并没有做更多的支持,它的上传需要更多的配置,它也不支持Ajax校验。使用代码:
<?php echo $form->fileField($model,’fileField’);
?>
3. radioButtonList
这是一个radio集合组件。使用代码:
<?php echo
$form->radioButtonList($model,’radioButtonList’,
array(’1′=>’Male’,’0′=>’Female’),
array(‘separator’=>’ ’,'labelOptions’=>array(‘class’=>’radiolabel’))
)?>
Yii框架封装的元素集合组件大致为4个参数:
$model,$property,$data,$htmlOptios
前面两个参数是我们关联模型类和指定的属性。第三个参数是一个数组,他是元素集合组件的数据来源,上面的代码中配置了两个数组元素,则会对应生成两个radio,radio的值为1或者0,radio的标签为Male或者Female。Yii默认将两个radio之间使用<br/>间隔,即两个radio不在同一行上,我们可以使用separator属性更改其间隔方式,这里我们使用空格符来间隔两个radio,这样他们显示在同一行上。另外在同一个radio中,其标签和实体也是换行的,原因在于标签<label>会换行,我们可以给label标签添加CSS样式,改变其display值为inline将其与radio实体排列在一行。
radioButtonList对应模型类中的属性值不是数组,只是一个单一数值或者字符而已,虽然他是一个集合组件,但是他是单选的,所以最终只有一个单一值提交服务器端。
另外值得注意的是,Yii封装的这些组件的初始值不能够在标签中设置,Yii自动会从模型类中读取属性值,然后在组件上显示出来。所以,如果你想在页面渲染前初始化一些组件的默认值,那么你可以直接初始化模型类就可以了。
4. checkBoxList
这是一个checkBox集合组件,使用代码:
<?php echo $form->checkBoxList($model,’checkBoxList’, array(’1′=>’Football’,’2′=>’Music’,’3′=>’Game’,’4′=>’basketball’), array(‘separator’=>’ ’,'labelOptions’=>array(‘class’=>’checkboxlabel’)) )?>