Introduction ¶
I had a validation challenge long time a go. The challenge was that I had to validate an attribute only if other attributes where of certain values or fulfilled some rules. For example, in order to validate for an attribute to be an email I needed to check if a dropdown parameter was sent with value 'email'.
One solution was to use beforeValidate and setup selection statements, but I thought that would be better to have a validator that could just plug set some rules and if they are passed without errors, then the important one was executed.
I have created a GitHub repository for those willing to contribute on any of the extensions I created. Please, check the link at the bottom of this wiki.Usage ¶
Download and extract on protected/components/validators (for the sake of the following example). For the sake of the example I am going to use one of the issues a fellow Yii'er had and requested this extension to help him out.
From its post and only the first and easiest requirement, for more advance example, please look at the post:
- province is required only if country has value = 86
public function rules(){
return array(
array(
'province', 'application.components.validators.EConditionalValidator',
'conditionalRules' => array('country', 'compare', 'compareValue' => 86),
'rule' => array('required')
),
);
}
For enhancements, bug reports, etc. Please use the Forum Post
Change Log ¶
- version 1.0.1 Initial public release
- version 1.0.2 Fixed bug for multiple rules (thanks ToolMayNARD)
Resources ¶
web development has never been so fun
www.2amigos.us
Things to improve
Useful extension, but it doesn't work if conditional rules are defined in the model and not in the database. Because you use getAttributes().
Fix for manually set attributes
For the validator to read correctly all the set attributes replace line 75
with
$arrAttributes = $object->getAttributes(); foreach ($arrAttributes as $strKey => $mixVal) $obj->setAttribute($strKey, $mixVal);
Slice instead of Splice?
Just tried out your extension and it looks like it will solve my problem quite nicely. Thanks for you efforts!
I did notice one thing when I was trying to get it going and that was pass additional parameters to the "rule". My example is
array( 'start_date_absoluteDate', 'ext.EConditionalValidator', 'conditionalRules' => array('start_date_selected', 'compare', 'compareValue' => "absolute" ), 'rule' => array('date', "format" => "yyyy-MM-dd" ), ), array( 'start_date_relativeVal', 'ext.EConditionalValidator', 'conditionalRules' => array('start_date_selected', 'compare', 'compareValue' => "relative" ), 'rule' => array( 'numerical', "allowEmpty" => false ), ),
I noticed that the format and allowEmpty parameters weren't being passed on to the validator.
in Function validateAttribute on line 80 there is an array_splice, which I think should be an array_slice? Otherwise we are removing the additional parameters and passing the name of the validator instead?
78 return false; 79 80 $validator = CValidator::createValidator($this->rule[0], $object, $attribute, array_slice($this->rule, 1)); 81 $validator->validate($object); 82 $obj = null;
It seemed to solve my problem anyway.
enableClientValidation ?
Is it supported?
'enableClientValidation'=>true, 'enableAjaxValidation'=>true,
Not being able to make it work with a form having the above params.
Regards
Cass
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.