Yii的Ajax的校验效果是通过CSS来实现的,上文提到一个input框可以存在四个状态:
初始化,校验,错误和成功。
每个状态对应不同CSS样式类。
初始化和校验这两个状态我们不需要关心,我们只注重用户校验失败和成功时,该input框的CSS样式。
此外当校验失败的时候,我们还要定义错误信息的样式,从翻译过来的静态文本来来,我们需要定义errorMessage类。
以下是我的CSS类:
/*标签是否换行*/
.formlabel{font-size:
12px;display:
block;}
/*属性是否必填项,客户端根据model的rule方法而定*/
.formspan.required{color:
red;}
/*校验出错时标签CSS样式*/
.form.errorlabel{color:
#FFCC33;}
/*校验出错时输入框的CSS样式*/
.form.errorinput{background:
#FEE;border-color:
#C00;}
/*校验出错时错误信息的CSS样式,我们可以设置其display属性让其不换行。
*/
.form.errorMessage{display:
inline;color:
red;font-size:
12px;}
/*校验成功时标签CSS样式*/
.form.successlabel{color:
#000000;}
/*校验成功时输入框的CSS样式*/
.form.successinput{background:
#E6EFC2;border-color:
#C6D880;}
以上的CSS注释已经很详细了,我们来看看校验流程,首先我们需要先渲染我们的页面:
$model=newLoginForm;
$this->render('index',array('model'=>$model));
注意,这里我们必须使用render()方法对其进行渲染。
我们的actionLogin如下:
publicfunctionactionLogin()
{
$model=newLoginForm;
//ajaxvalidate
if(isset($_POST['ajax'])&&$_POST['ajax']==='login-form')
{
echoCActiveForm:
:
validate($model);
Yii:
:
app()->end();
}
//submithandleandvalidate
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
if($model->validate()){
//nobusinesslogichandle
$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
这个组件没有太多讲的,主要注意行列的属性配置,使用代码:
phpecho$form->textArea($model,'textArea',array('rows'=>10,'cols'=>50));?
>
2.fileField
虽然Yii封装了这个组件,但是它并没有做更多的支持,它的上传需要更多的配置,它也不支持Ajax校验。
使用代码:
phpecho$form->fileField($model,'fileField');?
>
3.radioButtonList
这是一个radio集合组件。
使用代码:
phpecho$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之间使用
间隔,即两个radio不在同一行上,我们可以使用separator属性更改其间隔方式,这里我们使用空格符来间隔两个radio,这样他们显示在同一行上。
另外在同一个radio中,其标签和实体也是换行的,原因在于标签
radioButtonList对应模型类中的属性值不是数组,只是一个单一数值或者字符而已,虽然他是一个集合组件,但是他是单选的,所以最终只有一个单一值提交服务器端。
另外值得注意的是,Yii封装的这些组件的初始值不能够在标签中设置,Yii自动会从模型类中读取属性值,然后在组件上显示出来。
所以,如果你想在页面渲染前初始化一些组件的默认值,那么你可以直接初始化模型类就可以了。
4.checkBoxList
这是一个checkBox集合组件,使用代码:
phpecho$form->checkBoxList($model,'checkBoxList',
array('1'=>'Football','2'=>'Music','3'=>'Game','4'=>'basketball'),
array('separator'=>' ','labelOptions'=>array('class'=>'checkboxlabel'))
)?
>
这个组件同上,唯一不同的是这个组件是多选的,所以他对应的模型类的属性应该是一个数组。
这个组件将你选中的每个checkBox的值构造成一个数组提交服务器端。
例如我们选中了Football和Game,那个该组件构造的数组将是array(‘1’,’3’),没有选中的checkBox不会被构造进这个数组中。
反之从服务器段读取数组,然后显示该组件也是同样的道理。
5.listBox
本质上它是一个select,但是它会显示所有的option。
使用代码如下:
phpecho$form->listBox($model,'listBox',
array('1'=>'Football','2'=>'Music','3'=>'Game','4'=>'basketball'),
array('size'=>8,'multiple'=>false,'class'=>'listbox')
)?
>
需要说明的属性'size'表示该select的大小,虽然我只定义了4个option,但是我仍然想让它占据8个option的高度。
属性multiple为是否多选。
属性class为select的CSS样式类,但是貌似不起作用。
在需要说明的一点是,虽然它可以单选和多选,但是他对应的模型类的属性始终是一个数组。
6.dropDownList
本质上它是一个真正意义上select,因为他不会显示所有的option,使用代码如下:
php
$models=person:
:
model()->findAll(array('order'=>'age'));
$list=CHtml:
:
listData($models,'id','username');
echo$form->dropDownList($model,'dropDownList',$list,array('empty'=>'Selectauser')
)?
>
这个组件的使用跟select差不多,对应模型层的属性是一个单一数值或者字符,而不是数组。
属性empty指定了select的第一个option,相当于初始化值。
这里我们需要说明的是以上这些集合组件的数据来源。
本质上其实我们就是查询数据库,将结果集封装成一个数组,其实查询数据结果集本来就是一个数组。
这里我们使用AR类person按年龄查询所有的记录,然后使用CHtml的listData方法将查询记录中的id字段和username字段构造成一个简单的数组$list,然后我们只需要在dropDownList的标签配置中应用即可。
最后我们介绍一下服务器端获取页面数据,因为我们已经将模型类和我们的页面标签相关联,所以使用标签显示模型类属性或者从显示标签中获取模型类属性是十分简单的。
在服务器端我们获取页面数据的时候,可以使用如下代码:
$model=newForm;
$model->attributes=$_POST['Form'];
以上代码会将用户提交的数据自动填充到模型类的属性中,这个方式称为安全特性分配。
首先我们的页面中必须已经将标签和模型类Form关联。
需要注意的是$_POST的参数就是模型类的名称Form,而不是标签名称。
最重要的问题在于我们模型类中的属性必须是安全的,否则我们的安全特性分配将会失败。
指定模型类中的属性为安全的是通过实现模型类中的
Rules方法,即校验规则方法。
我们可以直接将模型类的指定属性指定为”safe”或者指定其他校验规则,因为Yii因为如果一个属性通过某个校验后它就可以被认为是安全的了。
publicfunctionrules()
{
returnarray(
array('property','safe')
);
}
CactiveDataProvider讲解
CactiveDataProvider是基于ActiveRecord的一个数据提供者,同时它也继承自CDataProvider。
它提供了ActiveRecord对象的集合。
我们可以使用“modelClass”属性指定CactiveDataProvider所要提供的ActiveRecord对象的类型。
CactiveDataProvider可以使用AR方法CActiveRecord:
:
findAll从数据库中检索信息。
它还可以使用criteria来指定查询条件,排序以及分页等等。
CActiveDataProvider的时候方法如下:
$dataProvider=newCActiveDataProvider('Post',array(
'criteria'=>array(
'condition'=>'status=1ANDtagsLIKE:
tags',
'params'=>array(':
tags'=>$_GET['tags']),
'with'=>array('author'),
),
'pagination'=>array(
'pageSize'=>20,
'currentPage'=>0,
),
));
在Yii的blog案例中,很很多地方用到了CactiveDataProvider,尤其是在读取很多数据且需要分页的情况下,CactiveDataProvider是很出色的。
CactiveDataProvider只是一个数据的集合,并不是一个显示组件,所以在blog案例中,它是和CGridView一起使用的,CGridView确切的说是一个使用表格显示数据的widget。
其实包含了很多的封装,在这里我们不是用CGridView,只使用CActiveDataProvider来进行分页查询。
使用CActiveDataProvider进行分页查询最重要的是“currentPage”属性,默认它是0。
在以上的CActiveDataProvider使用代码中,我们配置了它的两个属性:
criteria和pagination。
Criteria属性值就是CDbCriteria类的实例,而pagination值并非一个CPagination类的实例,而是一个数组而已。
实例化CPagination类需要表中记录总数作为参数。
以下是我action的代码:
publicfunctionactionPage()
{
$currentPage=0;
$pageSize=5;
if(isset($_GET['id'])){
$currentPage=$_GET['id'];
}
$criteria=newCDbCriteria(array('order'=>'agedesc',));
$pagination=array('currentPage'=>$currentPage,'pageSize'=>$pageSize,);
$dataProvider=new
CActiveDataProvider('person',array('pagination'=>$pagination,'criteria'=>$criteria,));
$totalItemCount=$dataProvider->getTotalItemCount();
$pageCount=ceil($totalItemCount/$pageSize);
$itemCount=$dataProvider->getItemCount();
$page=array('totalItemCount'=>$totalItemCount,
'pageCount'=>$pageCount,'itemCount'=>$itemCount,'currentPage'=>$currentPage,);
$data=$dataProvider->getData();
$this->render('all',array('data'=>$data,'page'=>$page,));
}
以上代码我们将数据信息data和分页信息page分开存放,并传递到被渲染的页面。
上文提到了“currentPage”,其实是CPagination类的一个属性,它默认
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1