Commit aa8061b0 by Qiang Xue

form wip

parent 62fc5cf6
...@@ -18,7 +18,7 @@ yii.validation = (function ($) { ...@@ -18,7 +18,7 @@ yii.validation = (function ($) {
return { return {
required: function (value, messages, options) { required: function (value, messages, options) {
var valid = false; var valid = false;
if (options.requiredValue === undefined) { if (options.requiredValue === undefined) {
if (options.strict && value !== undefined || !options.strict && !isEmpty(value, true)) { if (options.strict && value !== undefined || !options.strict && !isEmpty(value, true)) {
valid = true; valid = true;
...@@ -27,7 +27,7 @@ yii.validation = (function ($) { ...@@ -27,7 +27,7 @@ yii.validation = (function ($) {
valid = true; valid = true;
} }
if(!valid) { if (!valid) {
messages.push(options.message); messages.push(options.message);
} }
}, },
...@@ -39,7 +39,7 @@ yii.validation = (function ($) { ...@@ -39,7 +39,7 @@ yii.validation = (function ($) {
var valid = !options.strict && (value == options.trueValue || value == options.falseValue) var valid = !options.strict && (value == options.trueValue || value == options.falseValue)
|| options.strict && (value === options.trueValue || value === options.falseValue); || options.strict && (value === options.trueValue || value === options.falseValue);
if(!valid) { if (!valid) {
messages.push(options.message); messages.push(options.message);
} }
}, },
...@@ -90,7 +90,7 @@ yii.validation = (function ($) { ...@@ -90,7 +90,7 @@ yii.validation = (function ($) {
var valid = !options.not && $.inArray(value, options.range) var valid = !options.not && $.inArray(value, options.range)
|| options.not && !$.inArray(value, options.range); || options.not && !$.inArray(value, options.range);
if(!valid) { if (!valid) {
messages.push(options.message); messages.push(options.message);
} }
}, },
...@@ -112,7 +112,7 @@ yii.validation = (function ($) { ...@@ -112,7 +112,7 @@ yii.validation = (function ($) {
var valid = value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern)); var valid = value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern));
if(!valid) { if (!valid) {
messages.push(options.message); messages.push(options.message);
} }
}, },
...@@ -147,7 +147,7 @@ yii.validation = (function ($) { ...@@ -147,7 +147,7 @@ yii.validation = (function ($) {
for (var i = v.length - 1, h = 0; i >= 0; --i) { for (var i = v.length - 1, h = 0; i >= 0; --i) {
h += v.charCodeAt(i); h += v.charCodeAt(i);
} }
if(h != hash) { if (h != hash) {
messages.push(options.message); messages.push(options.message);
} }
}, },
...@@ -190,7 +190,7 @@ yii.validation = (function ($) { ...@@ -190,7 +190,7 @@ yii.validation = (function ($) {
break; break;
} }
if(!valid) { if (!valid) {
messages.push(options.message); messages.push(options.message);
} }
} }
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
* @copyright Copyright (c) 2008 Yii Software LLC * @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets; namespace yii\widgets;
use yii\base\Component; use yii\base\Component;
use yii\db\ActiveRecord;
use yii\helpers\Html; use yii\helpers\Html;
use yii\base\Model; use yii\base\Model;
use yii\helpers\JsExpression; use yii\helpers\JsExpression;
...@@ -79,8 +79,8 @@ class ActiveField extends Component ...@@ -79,8 +79,8 @@ class ActiveField extends Component
*/ */
public $validateOnType; public $validateOnType;
/** /**
* @var integer number of milliseconds that the validation should be delayed when a user is typing in an input field. * @var integer number of milliseconds that the validation should be delayed when the input field
* This property is used only when [[validateOnType]] is true. * is changed or the user types in the field.
* If not set, it will take the value of [[ActiveForm::validationDelay]]. * If not set, it will take the value of [[ActiveForm::validationDelay]].
*/ */
public $validationDelay; public $validationDelay;
...@@ -121,28 +121,13 @@ class ActiveField extends Component ...@@ -121,28 +121,13 @@ class ActiveField extends Component
public function begin() public function begin()
{ {
$inputID = Html::getInputId($this->model, $this->attribute); $options = $this->getClientOptions();
$attribute = Html::getAttributeName($this->attribute); if ($options !== array()) {
$this->form->attributes[$this->attribute] = $options;
$validators = array();
foreach ($this->model->getActiveValidators($attribute) as $validator) {
/** @var \yii\validators\Validator $validator */
if (($js = $validator->clientValidateAttribute($this->model, $attribute)) != '') {
$validators[] = $js;
}
}
$jsOptions = array(
'name' => $this->attribute,
'container' => ".field-$inputID",
'input' => "#$inputID",
'error' => '.help-inline',
);
if ($validators !== array()) {
$jsOptions['validate'] = new JsExpression("function(attribute, value, messages) {" . implode('', $validators) . '}');
} }
$this->form->attributes[$this->attribute] = $jsOptions;
$inputID = Html::getInputId($this->model, $this->attribute);
$attribute = Html::getAttributeName($this->attribute);
$options = $this->options; $options = $this->options;
$class = isset($options['class']) ? array($options['class']) : array(); $class = isset($options['class']) ? array($options['class']) : array();
$class[] = "field-$inputID"; $class[] = "field-$inputID";
...@@ -152,9 +137,8 @@ class ActiveField extends Component ...@@ -152,9 +137,8 @@ class ActiveField extends Component
if ($this->model->hasErrors($attribute)) { if ($this->model->hasErrors($attribute)) {
$class[] = $this->form->errorCssClass; $class[] = $this->form->errorCssClass;
} }
$options['class'] = implode(' ', $class); $options['class'] = implode(' ', $class);
return Html::beginTag($this->tag, $options); return Html::beginTag($this->tag, $options);
} }
...@@ -163,6 +147,65 @@ class ActiveField extends Component ...@@ -163,6 +147,65 @@ class ActiveField extends Component
return Html::endTag($this->tag); return Html::endTag($this->tag);
} }
protected function getClientOptions()
{
if ($this->enableClientValidation || $this->enableClientValidation === null && $this->form->enableClientValidation) {
$attribute = Html::getAttributeName($this->attribute);
$validators = array();
foreach ($this->model->getActiveValidators($attribute) as $validator) {
/** @var \yii\validators\Validator $validator */
$js = $validator->clientValidateAttribute($this->model, $attribute);
if ($validator->enableClientValidation && $js != '') {
$validators[] = $js;
}
}
if ($validators !== array()) {
$options['validate'] = new JsExpression("function(attribute,value,messages){" . implode('', $validators) . '}');
}
}
if ($this->enableAjaxValidation || $this->enableAjaxValidation === null && $this->form->enableAjaxValidation) {
$options['enableAjaxValidation'] = 1;
}
if (isset($options['validate']) || isset($options['enableAjaxValidation'])) {
$inputID = Html::getInputId($this->model, $this->attribute);
$options['name'] = $inputID;
if ($this->model instanceof ActiveRecord && !$this->model->getIsNewRecord()) {
$option['status'] = 1;
}
$names = array(
'enableAjaxValidation',
'validateOnChange',
'validateOnType',
'validationDelay',
);
foreach ($names as $name) {
$options[$name] = $this->$name === null ? $this->form->$name : $this->$name;
}
$options['container'] = isset($this->selectors['container']) ? $this->selectors['container'] : ".field-$inputID";
$options['input'] = isset($this->selectors['input']) ? $this->selectors['input'] : "#$inputID";
if (isset($this->errorOptions['class'])) {
$options['error'] = '.' . implode('.', preg_split('/\s+/', $this->errorOptions['class'], -1, PREG_SPLIT_NO_EMPTY));
} else {
$options['error'] = isset($this->errorOptions['tag']) ? $this->errorOptions['tag'] : 'span';
}
foreach (array('beforeValidate', 'afterValidate') as $callback) {
$value = $this->$callback;
if ($value instanceof JsExpression) {
$options[$callback] = $value;
} elseif (is_string($value)) {
$options[$callback] = new JsExpression($value);
}
}
return $options;
} else {
return array();
}
}
/** /**
* Generates a label tag for [[attribute]]. * Generates a label tag for [[attribute]].
* The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]]. * The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]].
......
...@@ -88,7 +88,7 @@ class ActiveForm extends Widget ...@@ -88,7 +88,7 @@ class ActiveForm extends Widget
* @var boolean whether to perform validation when an input field loses focus and its value is found changed. * @var boolean whether to perform validation when an input field loses focus and its value is found changed.
* If [[ActiveField::validateOnChange]] is set, its value will take precedence for that input field. * If [[ActiveField::validateOnChange]] is set, its value will take precedence for that input field.
*/ */
public $validateOnChange = false; public $validateOnChange = true;
/** /**
* @var boolean whether to perform validation while the user is typing in an input field. * @var boolean whether to perform validation while the user is typing in an input field.
* If [[ActiveField::validateOnType]] is set, its value will take precedence for that input field. * If [[ActiveField::validateOnType]] is set, its value will take precedence for that input field.
...@@ -96,12 +96,16 @@ class ActiveForm extends Widget ...@@ -96,12 +96,16 @@ class ActiveForm extends Widget
*/ */
public $validateOnType = false; public $validateOnType = false;
/** /**
* @var integer number of milliseconds that the validation should be delayed when a user is typing in an input field. * @var integer number of milliseconds that the validation should be delayed when an input field
* This property is used only when [[validateOnType]] is true. * is changed or the user types in the field.
* If [[ActiveField::validationDelay]] is set, its value will take precedence for that input field. * If [[ActiveField::validationDelay]] is set, its value will take precedence for that input field.
*/ */
public $validationDelay = 200; public $validationDelay = 200;
/** /**
* @var string the name of the GET parameter indicating the validation request is an AJAX request.
*/
public $ajaxVar = 'ajax';
/**
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
* the callback that will be invoked BEFORE validating EACH attribute on the client side. * the callback that will be invoked BEFORE validating EACH attribute on the client side.
* The signature of the callback should be like the following: * The signature of the callback should be like the following:
...@@ -192,6 +196,7 @@ class ActiveForm extends Widget ...@@ -192,6 +196,7 @@ class ActiveForm extends Widget
'errorCssClass' => $this->errorCssClass, 'errorCssClass' => $this->errorCssClass,
'successCssClass' => $this->successCssClass, 'successCssClass' => $this->successCssClass,
'validatingCssClass' => $this->validatingCssClass, 'validatingCssClass' => $this->validatingCssClass,
'ajaxVar' => $this->ajaxVar,
); );
if ($this->validationUrl !== null) { if ($this->validationUrl !== null) {
$options['validationUrl'] = Html::url($this->validationUrl); $options['validationUrl'] = Html::url($this->validationUrl);
...@@ -204,11 +209,10 @@ class ActiveForm extends Widget ...@@ -204,11 +209,10 @@ class ActiveForm extends Widget
); );
foreach ($callbacks as $callback) { foreach ($callbacks as $callback) {
$value = $this->$callback; $value = $this->$callback;
if (is_string($value)) {
$value = new JsExpression($value);
}
if ($value instanceof JsExpression) { if ($value instanceof JsExpression) {
$options[$callback] = $value; $options[$callback] = $value;
} elseif (is_string($value)) {
$options[$callback] = new JsExpression($value);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment