diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 0834a14..f99c62b 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -23,6 +23,16 @@ }; var defaults = { + enableAjaxValidation: false, + enableClientValidation: true, + // the URL for performing AJAX validation. If not set, it will use the the form's action + validationUrl: undefined, + // number of milliseconds of validation delay. This is used when validateOnType is true. + validationDelay: 200, + // whether to perform validation when a change is detected on the input. + validateOnChange: true, + // whether to perform validation when the user is typing. + validateOnType: false, // the container CSS class representing the corresponding attribute has validation error errorCssClass: 'error', // the container CSS class representing the corresponding attribute passes validation @@ -43,17 +53,22 @@ * - input: string, the jQuery selector of the input field * - error: string, the jQuery selector of the error tag * - value: string|array, the value of the input + * - validationDelay: integer, number of milliseconds of validation delay. + * This is used when validateOnType is true. If not set, it will take the value + * of the corresponding global setting. + * - validateOnChange: boolean, whether to perform validation when a change is detected on the input. + * If not set, it will take the value of the corresponding global setting. + * - validateOnType: boolean, defaults to false, whether to perform validation when the user is typing. + * If not set, it will take the value of the corresponding global setting. + * - enableAjaxValidation: boolean, whether to enable AJAX-based validation. + * If not set, it will take the value of the corresponding global setting. + * - enableClientValidation: boolean, whether to enable client-side validation. + * If not set, it will take the value of the corresponding global setting. + * - validate: function (attribute, value, messages), the client-side validation function. + * - beforeValidate: function ($form, attribute), callback called before validating an attribute. If it + * returns false, the validation will be cancelled. + * - afterValidate: function ($form, attribute, data, hasError), callback called after validating an attribute. * - status: integer, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating - * - validationDelay: 200, - * - validateOnChange: true, - * - validateOnType: false, - * - hideErrorMessage: false, - * - inputContainer: undefined, - * - 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) * * @param options object the configuration for the plugin. The following options can be set: */ diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index acfc261..83e0497 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -11,7 +11,33 @@ */ yii.validation = (function ($) { - var pub = { + var isEmpty = function (value, trim) { + return value === null || value === undefined || value == [] + || value === '' || trim && $.trim(value) === ''; + }; + + return { + required: function (value, messages, options) { + var valid = false; + if (options.requiredValue === undefined) { + if (options.strict && value !== undefined || !options.strict && !isEmpty(value, true)) { + valid = true; + } + } else if (!options.strict && value == options.requiredValue || options.strict && value === options.requiredValue) { + valid = true; + } + + valid || messages.push(options.message); + }, + + boolean: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + var valid = !options.strict && (value == options.trueValue || value == options.falseValue) + || options.strict && (value === options.trueValue || value === options.falseValue); + + valid || messages.push(options.message); + } }; - return pub; })(jQuery); diff --git a/framework/validators/BooleanValidator.php b/framework/validators/BooleanValidator.php index e336cf5..dd72c67 100644 --- a/framework/validators/BooleanValidator.php +++ b/framework/validators/BooleanValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; /** * BooleanValidator checks if the attribute value is a boolean value. @@ -82,16 +83,23 @@ class BooleanValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - '{true}' => $this->trueValue, - '{false}' => $this->falseValue, - )); - return " -if(" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . "value!=" . json_encode($this->trueValue) . " && value!=" . json_encode($this->falseValue) . ") { - messages.push(" . json_encode($message) . "); -} -"; + $options['message'] = array( + 'trueValue' => $this->trueValue, + 'falseValue' => $this->falseValue, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + '{true}' => $this->trueValue, + '{false}' => $this->falseValue, + ))), + ); + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; + } + if ($this->strict) { + $options['strict'] = 1; + } + + return 'yii.validation.boolean(value, messages, ' . json_encode($options) . ');'; } } diff --git a/framework/validators/RequiredValidator.php b/framework/validators/RequiredValidator.php index f4746e6..7202ec3 100644 --- a/framework/validators/RequiredValidator.php +++ b/framework/validators/RequiredValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; /** * RequiredValidator validates that the specified attribute does not have null or empty value. @@ -60,13 +61,10 @@ class RequiredValidator extends Validator */ public function validateAttribute($object, $attribute) { - $value = $object->$attribute; - if ($this->requiredValue === null) { - if ($this->strict && $value === null || !$this->strict && $this->isEmpty($value, true)) { + if (!$this->validateValue($object->$attribute)) { + if ($this->requiredValue === null) { $this->addError($object, $attribute, $this->message); - } - } else { - if (!$this->strict && $value != $this->requiredValue || $this->strict && $value !== $this->requiredValue) { + } else { $this->addError($object, $attribute, $this->message, array( '{requiredValue}' => $this->requiredValue, )); @@ -99,27 +97,24 @@ class RequiredValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { + $options = array(); if ($this->requiredValue !== null) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, + $options['message'] = strtr($this->message, array( '{requiredValue}' => $this->requiredValue, )); - return " -if (value != " . json_encode($this->requiredValue) . ") { - messages.push(" . json_encode($message) . "); -} -"; + $options['requiredValue'] = $this->requiredValue; } else { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - return " -if($.trim(value) == '') { - messages.push(" . json_encode($message) . "); -} -"; + $options['message'] = $this->message; + } + if ($this->strict) { + $options['strict'] = 1; } + + $options['message'] = Html::encode(strtr($options['message'], array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))); + + return 'yii.validation.required(value, messages, ' . json_encode($options) . ');'; } }