yii 使用cactiveform 创建表单时候遇到的一些验证问题和使用ajax_form时重置验证规则的解决办法

yii  cactiveform 在添加验证信息的时候, 有时候稍有不慎,可能导致客户端验证不起作用,尤其是像我这种初学者来说,更是无解了, 好在今天有点时间, 一路追查这个问题,最后从js 端一直追到了php中, 终于找到了罪魁祸首,原来还是我们自己,哈哈  接下来就简单分享一下:

首先让我们来看看所有的客户端js验证是怎么添加上去的:

在CActiveForm.php :383行 中有这么一句话:

$options=CJavaScript::encode($options);
		$cs->registerCoreScript('yiiactiveform');
		$id=$this->id;
		$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");

这就是根据模型中的规则来添加js验证

同样在492行有这么一段话:(这就是解决client不验证的关键)

if($model instanceof CActiveRecord && !$model->isNewRecord)
   $option['status']=1;

这段代码的意思就是 model必须继承CActiveRecord,但是追重要的是isNewRecord (我就是通过这个status从js追到php的), 然后在继续,到这里瞬间明白了,去看同事的代码,得出以下

Object::model();  isNewRecord  =  false
new Object();       isNewRecord  =  true

话说到这里,为什么我就认定了这个status呢, 当然不是我凭空想的,我是在jquery.yiicactiveform.js中一步一步追查到的,如果你有兴趣一可以看看, 最后在这个js最后发现了他的文件说明,也明显的说明了这一点:就因为使用了Object::model(); 这样这个对象就不是一个新记录了,status就被设置1了,设置为了1在验证中就代表validated了,所以自然就死活都不验证了!

/**
		 * list of attributes to be validated. Each array element is of the following structure:
		 * {
		 *     id: 'ModelClass_attribute', // the unique attribute ID
		 *     model: 'ModelClass', // the model class name
		 *     name: 'name', // attribute name
		 *     inputID: 'input-tag-id',
		 *     errorID: 'error-tag-id',
		 *     value: undefined,
		 *     status: 0,  // 0: empty, not entered before,  1: validated, 2: pending validation, 3: validating
		 *     validationDelay: 200,
		 *     validateOnChange: true,
		 *     validateOnType: false,
		 *     hideErrorMessage: false,
		 *     inputContainer: undefined,
		 *     errorCssClass: 'error',
		 *     successCssClass: 'success',
		 *     validatingCssClass: 'validating',
		 *     enableAjaxValidation: true,
		 *     enableClientValidation: true,
		 *     clientValidation: undefined, // function (value, messages, attribute) | client-side validation
		 *     beforeValidateAttribute: undefined, // function (form, attribute) | boolean
		 *     afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
		 * }
		 */

第二个问题:

想必大家也可能有这种需求, 就是一个提交信息的form表单, 比如购物网站的订单页面,这个页面里会有好些信息需要我们填写

为了说明我的问题,就拿两个信息来举这个例子, 首先最前面会有一个添加收货地址,然后下面会有一些发票信息填写,然后最下面会有一个提交按钮, 当所有的信息都填写完成后,最后统一提交, 那么问题来了,添加收货地址这里肯定会是一个异步form提交,(当然不使用form也可以,但是咱们使用yii吗,就利用他的优势吧), 说到这里这个地址的提交可以使用yii form ajax ,详细不说上代码

<?php
$form = $this->beginWidget('CActiveForm', array(
    'id' => 'addressForm',
    'enableClientValidation' => true, //是否启用客户端验证
    'clientOptions' => array(
        'validateOnSubmit' => true, //提交时验证
        'afterValidate' => 'js:function(form,data,hasError){
            if(!hasError){
                $.ajax({
                    "type":"POST",
                    "url":url,
                    "data":$("#addressForm").serialize(),
                    "success":function(data){
                        var res = eval("("+data+")");
                        if("success"==res.code){
                            if(res.addressId>0){
                                $("#addressId").val(res.addressId);
                            }
                            $("#address_info").prepend(res.html);
                            clearAddr();
                        }else{
                            clearAddr();
                        }
                        },
                    });
                }
            }'
    ),
));
?>

为了更直接在上一张图片

想必看到这里大家都明白了吧!

当然刚一进来这个表单肯定是隐藏的,需要点击添加新收货地址才显示出来, 

接下来一个一个分析, 当我添加到一半的时候我不想添了,那么我肯定要点击取消按钮, 这样那些错误信息需要隐藏, 为了使客户端验证在下次点开的时候还能继续使用,我们必须也要初始化yiicactiveform的验证环境,这里由于之前不知道怎么初始化,所以当点击取消后,当再次添加的时候不是验证不能使用就是出现别的问题, 那么还是看jquery.yiicactiveform.js
 :177 行

$form.bind('reset', function () {
				/*
				 * because we bind directly to a form reset event, not to a reset button (that could or could not exist),
				 * when this function is executed form elements values have not been reset yet,
				 * because of that we use the setTimeout
				 */
				setTimeout(function () {
					$.each(settings.attributes, function () {
						this.status = 0;
						var $error = $form.find('#' + this.errorID),
							$container = $.fn.yiiactiveform.getInputContainer(this, $form);

						$container.removeClass(
							this.validatingCssClass + ' ' +
							this.errorCssClass + ' ' +
							this.successCssClass
						);

						$error.html('').hide();

						/*
						 * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value
						 */
						this.value = getAFValue($form.find('#' + this.inputID));
					});
					/*
					 * If the form is submited (non ajax) with errors, labels and input gets the class 'error'
					 */
					$form.find('label, :input').each(function () {
						$(this).removeClass(settings.errorCss);
					});
					$('#' + settings.summaryID).hide().find('ul').html('');
					//.. set to initial focus on reset
					if (settings.focus !== undefined && !window.location.hash) {
						$form.find(settings.focus).focus();
					}
				}, 1);
			});

原来yii 已经给我们实现了, 它已经绑定好reset事件了, 所以 我们只需要恰当的执行

document.getElementById("addressForm").reset();

所有的工作yii 就都给我们处理了!

好了就分享到这里,列兵菜鸟一个如果有什么问题欢迎各位积极提出, 一起进步.

时间: 2024-07-30 19:13:56

yii 使用cactiveform 创建表单时候遇到的一些验证问题和使用ajax_form时重置验证规则的解决办法的相关文章

activiti自定义流程之整合(二):使用angular js整合ueditor创建表单

注:整体环境搭建:activiti自定义流程之整合(一):整体环境配置 基础环境搭建完毕,接下来就该正式着手代码编写了,在说代码之前,我觉得有必要先说明一下activit自定义流程的操作. 抛开自定义的表单不谈,通过之前的了解,我们知道一个新的流程开始,是在启动流程实例(processIntence)的时候,而流程实例依赖于流程定义(processDefinition),流程定义又依赖于流程模型(model). 我们用到的自定义表单需要在创建模型,画模型图的时候就指定表单的名称formKey,需

activiti自己定义流程之整合(二):使用angular js整合ueditor创建表单

基础环境搭建完成,接下来就该正式着手代码编写了,在说代码之前.我认为有必要先说明一下activit自己定义流程的操作. 抛开自己定义的表单不谈.通过之前的了解,我们知道一个新的流程開始.是在启动流程实例(processIntence)的时候,而流程实例依赖于流程定义(processDefinition).流程定义又依赖于流程模型(model). 我们用到的自己定义表单须要在创建模型,画模型图的时候就指定表单的名称formKey.须要保证这个formKey和我们创建的表单名称一致. 表单并不在创建

创建表单以及表单元素的使用

创建表单 其基本语法 <form action="url" method=get|post> <input type=submit> <input type=reset> </form> 其中应用的属性 action=url:定义提交表单的格式,可以是url或者电子邮件地 method=get|post:指明提交表单HTTP的方法  在网页中提供一个空格 text:定义单行文本输入框 Password:定义密码 rows:属性定义多行文本

activiti自己定义流程之自己定义表单(二):创建表单

注:环境配置:activiti自己定义流程之自己定义表单(一):环境配置 在上一节自己定义表单环境搭建好以后,我就正式開始尝试自己创建表单,在后台的处理就比較常规,主要是针对ueditor插件的功能在前端进行改动. 因为自己的前端相关技术太渣.因此好多东西都不会用,导致改动实现的过程也是破费了一番功夫.头皮发麻了好几天. 既然是用别人的插件进行改动,那么我想假设仅仅是单独的贴出我改动后的代码,可能没有前后进行对照好理解,因此这里就把原代码和改动后的同一时候对照着贴出,以便于朋友们能从对照中更快的

activiti自定义流程之自定义表单(二):创建表单

注:环境配置:activiti自定义流程之自定义表单(一):环境配置 在上一节自定义表单环境搭建好以后,我就正式开始尝试自己创建表单,在后台的处理就比较常规,主要是针对ueditor插件的功能在前端进行修改. 由于自己的前端相关技术太渣,因此好多东西都不会用,导致修改实现的过程也是破费了一番功夫,头皮发麻了好几天. 既然是用别人的插件进行修改,那么我想如果只是单独的贴出我修改后的代码,可能没有前后进行对比好理解,因此这里就把原代码和修改后的同时对比着贴出,以便于朋友们能从对比中更快的得到启发.

webform快速创建表单内容文件--oracle 数据库

使用方法 前台页面这样写就足够了 <form class="stdform" runat="server"> <div id="field_tab_content" runat="server"></div> </form> 新增编辑加载页面(改页面需要继承CreateModel类) Type type; public decimal id = 0; protected void

Sharepoint创建表单权限叠加

根据用户需求,创建表单,要求是用户可以填表并提交表单,而且提交后只能看到和修改自己的记录.而管理员或者授权人员可以查看到所有记录. 在sharepoint 2007 server上的实现 首先创建一个sharepoint site: https://portal.xxx.com/ 建好后,点右上角,Site Actions -> Create -> Custom List,建好后,进入刚建的List,如test1,然后点Settings -> Create Column 将Column一

YII用户注冊表单的实现熟悉前台各个表单元素操作方式

模还是必须定义两个基本方法.还有部分label标签映射为汉字,假设进行表单验证,还要定义一些验证规则: <? php /* * 用户模型 * */ class user extends CActiveRecord{ //获得数据模型 public static function model($classname = __CLASS__){ return parent::model($classname); } //定义数据表名字 public function tableName(){ retu

yii初体验(3)表单提交

初体验 model层 控制层调用 浏览器显示信息: 实战 http://yiitest:7888/index.php?r=site/entry 方法 view 视图使用了一个功能强大的小部件 yii\widgets\ActiveForm 去生成 HTML 表单.其中的 begin() 和 end() 分别用来渲染表单的开始和关闭标签.在这两个方法之间使用了 yii\widgets\ActiveForm::field() 方法去创建输入框.第一个输入框用于 “name”,第二个输入框用于 “ema