So the static validation for the following "require at least n" validator works alright, but when AJAX validation is enabled, the error messages are not cleared properly.
I think the issue might be that, while the errors are cleared on the server-side stuff and the JSON array of messages it returns omits the errors for the attributes once conditions are met, the function called to update a field on change, $.fn.yiiactiveform.updateInput(), only updates that single attribute.
Any suggestions? How could I get it to update all the attributes’ messages so the errors are consistent?
<?php
class RequireAtLeastNValidator extends CValidator {
/**
* @var int the number of attributes that are required to have a specific value or be non-empty
*/
public $countRequired = 1;
/**
* @var mixed the desired value that the attribute must have.
* If this is null, the validator will validate that the specified attribute does not have null or empty value.
* If this is set as a value that is not null, the validator will validate that
* the attribute has a value that is the same as this property value.
* Defaults to null.
*/
public $requiredValue;
/**
* @var boolean whether the comparison to {@link requiredValue} is strict.
* When this is true, the attribute value and type must both match those of {@link requiredValue}.
* Defaults to false, meaning only the value needs to be matched.
* This property is only used when {@link requiredValue} is not null.
*/
public $strict = false;
private $_validCount = 0;
protected function validateAttribute($object, $attribute) {
}
/**
* Validates the specified object.
* @param CModel $object the data object being validated
* @param array $attributes the list of attributes to be validated. Defaults to null,
* meaning every attribute listed in {@link attributes} will be validated.
*/
public function validate($object, $attributes = null) {
if(is_array($attributes))
$attributes = array_intersect($this->attributes, $attributes);
else
$attributes = $this->attributes;
if($this->countRequired > count($attributes))
$this->countRequired = count($attributes);
//count number of attributes with valid values
$this->_validCount = 0;
foreach($attributes as $attribute) {
$value = $object->$attribute;
if($this->requiredValue!==null) {
if(($this->strict && $this->requiredValue === $value) ||
(!$this->strict && $this->requiredValue == $value))
$this->_validCount++;
} else {
$this->_validCount += $this->isEmpty($value, true) ? 0 : 1;
}
}
//check if there are sufficient attributes with valid values
if($this->_validCount < $this->countRequired) {
//add errors to attributes
foreach($attributes as $a)
$this->addError($object, $a, $this->getMessage($object, $attributes));
}
}
/**
* Returns the appropriate message given the properties of this validator
* @param array $attributes the list of attributes validated. Defaults to null,
* meaning every attribute listed in {@link attributes} will be validated.
*/
private function getMessage($object, $attributes = null) {
if(!is_null($this->message))
return $this->message;
else {
if(is_array($attributes))
$attributes = array_intersect($this->attributes, $attributes);
else
$attributes = $this->attributes;
$messageParams = array(
'{n}' => $this->countRequired,
'{attributeList}' => '',
'{requiredValue}' => $this->requiredValue,
);
for($i = 0; $i < count($attributes); $i++)
$messageParams['{attributeList}'] .= (($i != 0) ? ', ' : '') . $object->getAttributeLabel($attributes[$i]);
if($this->requiredValue!==null)
$message = Yii::t('yii', 'At least {n} of {attributeList} must be {requiredValue}.', $messageParams);
else
$message = Yii::t('yii', 'At least {n} of {attributeList} must not be empty.', $messageParams);
return $message;
}
}
}