mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-01 20:19:42 +08:00
Finished ActiveForm.
This commit is contained in:
@ -35,14 +35,12 @@
|
|||||||
validatingCssClass: 'validating',
|
validatingCssClass: 'validating',
|
||||||
// the URL for performing AJAX-based validation. If not set, it will use the the form's action
|
// the URL for performing AJAX-based validation. If not set, it will use the the form's action
|
||||||
validationUrl: undefined,
|
validationUrl: undefined,
|
||||||
// a callback that is called before validating every attribute
|
// a callback that is called before submitting the form. The signature of the callback should be:
|
||||||
beforeValidateAttribute: undefined,
|
// function ($form) { ...return false to cancel submission...}
|
||||||
// a callback that is called after validating every attribute
|
beforeSubmit: undefined,
|
||||||
afterValidateAttribute: undefined,
|
// a callback that is called before validating each attribute. The signature of the callback should be:
|
||||||
// a callback that is called before validating ALL attributes when submitting the form
|
// function ($form, attribute, messages) { ...return false to cancel the validation...}
|
||||||
beforeValidate: undefined,
|
beforeValidate: undefined,
|
||||||
// a callback that is called after validating ALL attributes when submitting the form
|
|
||||||
afterValidate: undefined,
|
|
||||||
// the GET parameter name indicating an AJAX-based validation
|
// the GET parameter name indicating an AJAX-based validation
|
||||||
ajaxVar: 'ajax'
|
ajaxVar: 'ajax'
|
||||||
};
|
};
|
||||||
@ -66,10 +64,6 @@
|
|||||||
enableAjaxValidation: false,
|
enableAjaxValidation: false,
|
||||||
// function (attribute, value, messages), the client-side validation function.
|
// function (attribute, value, messages), the client-side validation function.
|
||||||
validate: undefined,
|
validate: undefined,
|
||||||
// callback called before validating the attribute
|
|
||||||
beforeValidate: undefined,
|
|
||||||
// callback called after validating an attribute.
|
|
||||||
afterValidate: undefined,
|
|
||||||
// status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating
|
// status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating
|
||||||
status: 0,
|
status: 0,
|
||||||
// the value of the input
|
// the value of the input
|
||||||
@ -122,6 +116,10 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
options: function() {
|
||||||
|
return this.data('yiiActiveForm').settings;
|
||||||
|
},
|
||||||
|
|
||||||
submitForm: function () {
|
submitForm: function () {
|
||||||
var $form = this,
|
var $form = this,
|
||||||
data = $form.data('yiiActiveForm');
|
data = $form.data('yiiActiveForm');
|
||||||
@ -135,14 +133,13 @@
|
|||||||
clearTimeout(data.settings.timer);
|
clearTimeout(data.settings.timer);
|
||||||
}
|
}
|
||||||
data.submitting = true;
|
data.submitting = true;
|
||||||
if (!data.settings.beforeValidate || data.settings.beforeValidate($form)) {
|
if (!data.settings.beforeSubmit || data.settings.beforeSubmit($form)) {
|
||||||
validate($form, function (messages) {
|
validate($form, function (messages) {
|
||||||
var hasError = false;
|
var hasError = false;
|
||||||
$.each(data.attributes, function () {
|
$.each(data.attributes, function () {
|
||||||
hasError = updateInput($form, this, messages) || hasError;
|
hasError = updateInput($form, this, messages) || hasError;
|
||||||
});
|
});
|
||||||
updateSummary($form, messages);
|
updateSummary($form, messages);
|
||||||
if (!data.settings.afterValidate || data.settings.afterValidate($form, messages, hasError)) {
|
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
data.validated = true;
|
data.validated = true;
|
||||||
var $button = data.submitObject || $form.find(':submit:first');
|
var $button = data.submitObject || $form.find(':submit:first');
|
||||||
@ -155,7 +152,6 @@
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
data.submitting = false;
|
data.submitting = false;
|
||||||
}, function () {
|
}, function () {
|
||||||
data.submitting = false;
|
data.submitting = false;
|
||||||
@ -235,7 +231,6 @@
|
|||||||
if (data.submitting || $form.is(':hidden')) {
|
if (data.submitting || $form.is(':hidden')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!attribute.beforeValidate || attribute.beforeValidate($form, attribute)) {
|
|
||||||
$.each(data.attributes, function () {
|
$.each(data.attributes, function () {
|
||||||
if (this.status === 2) {
|
if (this.status === 2) {
|
||||||
this.status = 3;
|
this.status = 3;
|
||||||
@ -249,11 +244,7 @@
|
|||||||
hasError = updateInput($form, this, messages) || hasError;
|
hasError = updateInput($form, this, messages) || hasError;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (attribute.afterValidate) {
|
|
||||||
attribute.afterValidate($form, attribute, messages, hasError);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}, data.settings.validationDelay);
|
}, data.settings.validationDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -271,16 +262,17 @@
|
|||||||
$.each(data.attributes, function () {
|
$.each(data.attributes, function () {
|
||||||
if (data.submitting || this.status === 2 || this.status === 3) {
|
if (data.submitting || this.status === 2 || this.status === 3) {
|
||||||
var msg = [];
|
var msg = [];
|
||||||
|
if (!data.settings.beforeValidate || data.settings.beforeValidate($form, this, msg)) {
|
||||||
if (this.validate) {
|
if (this.validate) {
|
||||||
this.validate(this, getValue($form, this), msg);
|
this.validate(this, getValue($form, this), msg);
|
||||||
|
}
|
||||||
if (msg.length) {
|
if (msg.length) {
|
||||||
messages[this.name] = msg;
|
messages[this.name] = msg;
|
||||||
}
|
} else if (this.enableAjaxValidation) {
|
||||||
}
|
|
||||||
if (this.enableAjaxValidation && !msg.length) {
|
|
||||||
needAjaxValidation = true;
|
needAjaxValidation = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (needAjaxValidation && (!data.submitting || $.isEmptyObject(messages))) {
|
if (needAjaxValidation && (!data.submitting || $.isEmptyObject(messages))) {
|
||||||
|
|||||||
@ -896,6 +896,7 @@ class Html
|
|||||||
$attribute = static::getAttributeName($attribute);
|
$attribute = static::getAttributeName($attribute);
|
||||||
$label = isset($options['label']) ? $options['label'] : static::encode($model->getAttributeLabel($attribute));
|
$label = isset($options['label']) ? $options['label'] : static::encode($model->getAttributeLabel($attribute));
|
||||||
$for = array_key_exists('for', $options) ? $options['for'] : static::getInputId($model, $attribute);
|
$for = array_key_exists('for', $options) ? $options['for'] : static::getInputId($model, $attribute);
|
||||||
|
unset($options['label'], $options['for']);
|
||||||
return static::label($label, $for, $options);
|
return static::label($label, $for, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -84,36 +84,13 @@ class ActiveField extends Component
|
|||||||
* 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;
|
||||||
/**
|
|
||||||
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
|
|
||||||
* the callback that will be invoked BEFORE validating the attribute associated with this field on the client side.
|
|
||||||
*
|
|
||||||
* This callback is called after [[ActiveForm::beforeValidateAttribute]].
|
|
||||||
*
|
|
||||||
* The signature of the callback should be like the following:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
public $beforeValidate;
|
|
||||||
/**
|
|
||||||
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
|
|
||||||
* the callback that will be invoked AFTER validating the attribute associated with this field on the client side.
|
|
||||||
*
|
|
||||||
* This callback is called before [[ActiveForm::afterValidateAttribute]].
|
|
||||||
*
|
|
||||||
* The signature of the callback should be like the following:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
public $afterValidate;
|
|
||||||
/**
|
/**
|
||||||
* @var array the jQuery selectors for selecting the container, input and error tags.
|
* @var array the jQuery selectors for selecting the container, input and error tags.
|
||||||
* The array keys should be "container", "input", and/or "error", and the array values
|
* The array keys should be "container", "input", and/or "error", and the array values
|
||||||
* are the corresponding selectors. For example, `array('input' => '#my-input')`.
|
* are the corresponding selectors. For example, `array('input' => '#my-input')`.
|
||||||
*
|
*
|
||||||
* The selectors are used under the context of the form.
|
* The container selector is used under the context of the form, while the input and the error
|
||||||
|
* selectors are used under the context of the container.
|
||||||
*
|
*
|
||||||
* You normally do not need to set this property as the default selectors should work well for most cases.
|
* You normally do not need to set this property as the default selectors should work well for most cases.
|
||||||
*/
|
*/
|
||||||
@ -149,7 +126,9 @@ class ActiveField extends Component
|
|||||||
|
|
||||||
protected function getClientOptions()
|
protected function getClientOptions()
|
||||||
{
|
{
|
||||||
if ($this->enableClientValidation || $this->enableClientValidation === null && $this->form->enableClientValidation) {
|
$enableClientValidation = $this->enableClientValidation || $this->enableClientValidation === null && $this->form->enableClientValidation;
|
||||||
|
$enableAjaxValidation = $this->enableAjaxValidation || $this->enableAjaxValidation === null && $this->form->enableAjaxValidation;
|
||||||
|
if ($enableClientValidation) {
|
||||||
$attribute = Html::getAttributeName($this->attribute);
|
$attribute = Html::getAttributeName($this->attribute);
|
||||||
$validators = array();
|
$validators = array();
|
||||||
foreach ($this->model->getActiveValidators($attribute) as $validator) {
|
foreach ($this->model->getActiveValidators($attribute) as $validator) {
|
||||||
@ -164,19 +143,14 @@ class ActiveField extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->enableAjaxValidation || $this->enableAjaxValidation === null && $this->form->enableAjaxValidation) {
|
if ($enableAjaxValidation) {
|
||||||
$options['enableAjaxValidation'] = 1;
|
$options['enableAjaxValidation'] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($options['validate']) || isset($options['enableAjaxValidation'])) {
|
if ($enableClientValidation || $enableAjaxValidation) {
|
||||||
$inputID = Html::getInputId($this->model, $this->attribute);
|
$inputID = Html::getInputId($this->model, $this->attribute);
|
||||||
$options['name'] = $inputID;
|
$options['name'] = $inputID;
|
||||||
if ($this->model instanceof ActiveRecord && !$this->model->getIsNewRecord()) {
|
|
||||||
$option['status'] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$names = array(
|
$names = array(
|
||||||
'enableAjaxValidation',
|
|
||||||
'validateOnChange',
|
'validateOnChange',
|
||||||
'validateOnType',
|
'validateOnType',
|
||||||
'validationDelay',
|
'validationDelay',
|
||||||
@ -191,15 +165,6 @@ class ActiveField extends Component
|
|||||||
} else {
|
} else {
|
||||||
$options['error'] = isset($this->errorOptions['tag']) ? $this->errorOptions['tag'] : 'span';
|
$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;
|
return $options;
|
||||||
} else {
|
} else {
|
||||||
return array();
|
return array();
|
||||||
@ -359,12 +324,30 @@ class ActiveField extends Component
|
|||||||
*
|
*
|
||||||
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
|
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
|
||||||
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
|
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
|
||||||
|
* @param boolean $enclosedByLabel whether to enclose the radio within the label.
|
||||||
|
* If true, the method will still use [[template]] to layout the checkbox and the error message
|
||||||
|
* except that the radio is enclosed by the label tag.
|
||||||
* @return string the generated radio button tag
|
* @return string the generated radio button tag
|
||||||
*/
|
*/
|
||||||
public function radio($options = array())
|
public function radio($options = array(), $enclosedByLabel = true)
|
||||||
{
|
{
|
||||||
|
if ($enclosedByLabel) {
|
||||||
|
$hidden = '';
|
||||||
|
$radio = Html::activeRadio($this->model, $this->attribute, $options);
|
||||||
|
if (($pos = strpos($radio, '><')) !== false) {
|
||||||
|
$hidden = substr($radio, 0, $pos + 1);
|
||||||
|
$radio = substr($radio, $pos + 1);
|
||||||
|
}
|
||||||
|
$label = isset($this->labelOptions['label']) ? $this->labelOptions['label'] : Html::encode($this->model->getAttributeLabel($this->attribute));
|
||||||
|
return $this->begin() . "\n" . $hidden . strtr($this->template, array(
|
||||||
|
'{input}' => Html::label("$radio $label", null, array('class' => 'radio')),
|
||||||
|
'{label}' => '',
|
||||||
|
'{error}' => $this->error(),
|
||||||
|
)) . "\n" . $this->end();
|
||||||
|
} else {
|
||||||
return $this->render(Html::activeRadio($this->model, $this->attribute, $options));
|
return $this->render(Html::activeRadio($this->model, $this->attribute, $options));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a checkbox tag for the given model attribute.
|
* Generates a checkbox tag for the given model attribute.
|
||||||
@ -379,12 +362,30 @@ class ActiveField extends Component
|
|||||||
*
|
*
|
||||||
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
|
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
|
||||||
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
|
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
|
||||||
|
* @param boolean $enclosedByLabel whether to enclose the checkbox within the label.
|
||||||
|
* If true, the method will still use [[template]] to layout the checkbox and the error message
|
||||||
|
* except that the checkbox is enclosed by the label tag.
|
||||||
* @return string the generated checkbox tag
|
* @return string the generated checkbox tag
|
||||||
*/
|
*/
|
||||||
public function checkbox($options = array())
|
public function checkbox($options = array(), $enclosedByLabel = true)
|
||||||
{
|
{
|
||||||
|
if ($enclosedByLabel) {
|
||||||
|
$hidden = '';
|
||||||
|
$checkbox = Html::activeCheckbox($this->model, $this->attribute, $options);
|
||||||
|
if (($pos = strpos($checkbox, '><')) !== false) {
|
||||||
|
$hidden = substr($checkbox, 0, $pos + 1);
|
||||||
|
$checkbox = substr($checkbox, $pos + 1);
|
||||||
|
}
|
||||||
|
$label = isset($this->labelOptions['label']) ? $this->labelOptions['label'] : Html::encode($this->model->getAttributeLabel($this->attribute));
|
||||||
|
return $this->begin() . "\n" . $hidden . strtr($this->template, array(
|
||||||
|
'{input}' => Html::label("$checkbox $label", null, array('class' => 'checkbox')),
|
||||||
|
'{label}' => '',
|
||||||
|
'{error}' => $this->error(),
|
||||||
|
)) . "\n" . $this->end();
|
||||||
|
} else {
|
||||||
return $this->render(Html::activeCheckbox($this->model, $this->attribute, $options));
|
return $this->render(Html::activeCheckbox($this->model, $this->attribute, $options));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a drop-down list for the given model attribute.
|
* Generates a drop-down list for the given model attribute.
|
||||||
|
|||||||
@ -106,51 +106,7 @@ class ActiveForm extends Widget
|
|||||||
*/
|
*/
|
||||||
public $ajaxVar = 'ajax';
|
public $ajaxVar = 'ajax';
|
||||||
/**
|
/**
|
||||||
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
|
* @var array the client validation options for individual attributes. Each element of the array
|
||||||
* the callback that will be invoked BEFORE validating EACH attribute on the client side.
|
|
||||||
* The signature of the callback should be like the following:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
public $beforeValidateAttribute;
|
|
||||||
/**
|
|
||||||
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
|
|
||||||
* the callback that will be invoked AFTER validating EACH attribute on the client side.
|
|
||||||
* The signature of the callback should be like the following:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
public $afterValidateAttribute;
|
|
||||||
/**
|
|
||||||
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
|
|
||||||
* the callback that will be invoked BEFORE validating ALL attributes on the client side when the validation
|
|
||||||
* is triggered by form submission (that is, [[validateOnSubmit]] is set true).
|
|
||||||
*
|
|
||||||
* This callback is called before [[beforeValidateAttribute]].
|
|
||||||
*
|
|
||||||
* The signature of the callback should be like the following:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
public $beforeValidate;
|
|
||||||
/**
|
|
||||||
* @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing
|
|
||||||
* the callback that will be invoked AFTER validating ALL attributes on the client side when the validation
|
|
||||||
* is triggered by form submission (that is, [[validateOnSubmit]] is set true).
|
|
||||||
*
|
|
||||||
* This callback is called after [[afterValidateAttribute]].
|
|
||||||
*
|
|
||||||
* The signature of the callback should be like the following:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
public $afterValidate;
|
|
||||||
/**
|
|
||||||
* @var array list of attributes that need to be validated on the client side. Each element of the array
|
|
||||||
* represents the validation options for a particular attribute.
|
* represents the validation options for a particular attribute.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
@ -201,21 +157,6 @@ class ActiveForm extends Widget
|
|||||||
if ($this->validationUrl !== null) {
|
if ($this->validationUrl !== null) {
|
||||||
$options['validationUrl'] = Html::url($this->validationUrl);
|
$options['validationUrl'] = Html::url($this->validationUrl);
|
||||||
}
|
}
|
||||||
$callbacks = array(
|
|
||||||
'beforeValidateAttribute',
|
|
||||||
'afterValidateAttribute',
|
|
||||||
'beforeValidate',
|
|
||||||
'afterValidate',
|
|
||||||
);
|
|
||||||
foreach ($callbacks as $callback) {
|
|
||||||
$value = $this->$callback;
|
|
||||||
if ($value instanceof JsExpression) {
|
|
||||||
$options[$callback] = $value;
|
|
||||||
} elseif (is_string($value)) {
|
|
||||||
$options[$callback] = new JsExpression($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $options;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user