Commit f34b138a by Qiang Xue

Fixes #4225: Added `ActiveForm::validateOnBlur` and `ActiveField::validateOnBlur`

parent 212c5ee3
...@@ -175,6 +175,7 @@ Yii Framework 2 Change Log ...@@ -175,6 +175,7 @@ Yii Framework 2 Change Log
- Fixed PBKDF2 key truncation. - Fixed PBKDF2 key truncation.
- Adjusted API. - Adjusted API.
- Enh #4209: Added `beforeCopy`, `afterCopy`, `forceCopy` properties to AssetManager (cebe) - Enh #4209: Added `beforeCopy`, `afterCopy`, `forceCopy` properties to AssetManager (cebe)
- Enh #4225: Added `ActiveForm::validateOnBlur` and `ActiveField::validateOnBlur` (qiangxue)
- Enh #4297: Added check for DOM extension to requirements (samdark) - Enh #4297: Added check for DOM extension to requirements (samdark)
- Enh #4317: Added `absoluteAuthTimeout` to yii\web\User (ivokund, nkovacs) - Enh #4317: Added `absoluteAuthTimeout` to yii\web\User (ivokund, nkovacs)
- Enh #4360: Added client validation support for file validator (Skysplit) - Enh #4360: Added client validation support for file validator (Skysplit)
......
...@@ -79,6 +79,8 @@ ...@@ -79,6 +79,8 @@
encodeError: true, encodeError: true,
// whether to perform validation when a change is detected on the input // whether to perform validation when a change is detected on the input
validateOnChange: false, validateOnChange: false,
// whether to perform validation when the input loses focus
validateOnBlur: false,
// whether to perform validation when the user is typing. // whether to perform validation when the user is typing.
validateOnType: false, validateOnType: false,
// number of milliseconds that the validation should be delayed when a user is typing in the input field. // number of milliseconds that the validation should be delayed when a user is typing in the input field.
...@@ -235,7 +237,10 @@ ...@@ -235,7 +237,10 @@
if (attribute.validateOnChange) { if (attribute.validateOnChange) {
$input.on('change.yiiActiveForm',function () { $input.on('change.yiiActiveForm',function () {
validateAttribute($form, attribute, false); validateAttribute($form, attribute, false);
}).on('blur.yiiActiveForm', function () { });
}
if (attribute.validateOnBlur) {
$input.on('blur.yiiActiveForm', function () {
if (attribute.status == 0 || attribute.status == 1) { if (attribute.status == 0 || attribute.status == 1) {
validateAttribute($form, attribute, !attribute.status); validateAttribute($form, attribute, !attribute.status);
} }
......
...@@ -95,11 +95,16 @@ class ActiveField extends Component ...@@ -95,11 +95,16 @@ class ActiveField extends Component
*/ */
public $enableAjaxValidation; public $enableAjaxValidation;
/** /**
* @var boolean whether to perform validation when the input field loses focus and its value is found changed. * @var boolean whether to perform validation when the value of the input field is changed.
* If not set, it will take the value of [[ActiveForm::validateOnChange]]. * If not set, it will take the value of [[ActiveForm::validateOnChange]].
*/ */
public $validateOnChange; public $validateOnChange;
/** /**
* @var boolean whether to perform validation when the input field loses focus.
* If not set, it will take the value of [[ActiveForm::validateOnBlur]].
*/
public $validateOnBlur;
/**
* @var boolean whether to perform validation while the user is typing in the input field. * @var boolean whether to perform validation while the user is typing in the input field.
* If not set, it will take the value of [[ActiveForm::validateOnType]]. * If not set, it will take the value of [[ActiveForm::validateOnType]].
* @see validationDelay * @see validationDelay
...@@ -717,7 +722,7 @@ class ActiveField extends Component ...@@ -717,7 +722,7 @@ class ActiveField extends Component
$inputID = Html::getInputId($this->model, $this->attribute); $inputID = Html::getInputId($this->model, $this->attribute);
$options['id'] = $inputID; $options['id'] = $inputID;
$options['name'] = $this->attribute; $options['name'] = $this->attribute;
foreach (['validateOnChange', 'validateOnType', 'validationDelay'] as $name) { foreach (['validateOnChange', 'validateOnBlur', 'validateOnType', 'validationDelay'] as $name) {
$options[$name] = $this->$name === null ? $this->form->$name : $this->$name; $options[$name] = $this->$name === null ? $this->form->$name : $this->$name;
} }
$options['container'] = isset($this->selectors['container']) ? $this->selectors['container'] : ".field-$inputID"; $options['container'] = isset($this->selectors['container']) ? $this->selectors['container'] : ".field-$inputID";
......
...@@ -100,11 +100,16 @@ class ActiveForm extends Widget ...@@ -100,11 +100,16 @@ class ActiveForm extends Widget
*/ */
public $validateOnSubmit = true; public $validateOnSubmit = true;
/** /**
* @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 the value of an input field is 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 = true; public $validateOnChange = true;
/** /**
* @var boolean whether to perform validation when an input field loses focus.
* If [[ActiveField::$validateOnBlur]] is set, its value will take precedence for that input field.
*/
public $validateOnBlur = 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.
* @see validationDelay * @see validationDelay
......
...@@ -268,12 +268,14 @@ EOD; ...@@ -268,12 +268,14 @@ EOD;
$actualValue = $this->activeField->getClientOptions(); $actualValue = $this->activeField->getClientOptions();
$expectedJsExpression = "function (attribute, value, messages, deferred) {return true;}"; $expectedJsExpression = "function (attribute, value, messages, deferred) {return true;}";
$expectedValidateOnChange = true; $expectedValidateOnChange = true;
$expectedValidateOnBlur = true;
$expectedValidateOnType = false; $expectedValidateOnType = false;
$expectedValidationDelay = 200; $expectedValidationDelay = 200;
$actualJsExpression = $actualValue['validate']; $actualJsExpression = $actualValue['validate'];
$this->assertEquals($expectedJsExpression, $actualJsExpression->expression); $this->assertEquals($expectedJsExpression, $actualJsExpression->expression);
$this->assertTrue($expectedValidateOnChange === $actualValue['validateOnChange']); $this->assertTrue($expectedValidateOnChange === $actualValue['validateOnChange']);
$this->assertTrue($expectedValidateOnBlur === $actualValue['validateOnBlur']);
$this->assertTrue($expectedValidateOnType === $actualValue['validateOnType']); $this->assertTrue($expectedValidateOnType === $actualValue['validateOnType']);
$this->assertTrue($expectedValidationDelay === $actualValue['validationDelay']); $this->assertTrue($expectedValidationDelay === $actualValue['validationDelay']);
} }
...@@ -288,6 +290,7 @@ EOD; ...@@ -288,6 +290,7 @@ EOD;
$actualValue = $this->activeField->getClientOptions(); $actualValue = $this->activeField->getClientOptions();
$expectedJsExpression = "function (attribute, value, messages, deferred) {return true;}"; $expectedJsExpression = "function (attribute, value, messages, deferred) {return true;}";
$expectedValidateOnChange = true; $expectedValidateOnChange = true;
$expectedValidateOnBlur = true;
$expectedValidateOnType = false; $expectedValidateOnType = false;
$expectedValidationDelay = 200; $expectedValidationDelay = 200;
$expectedError = ".help-block"; $expectedError = ".help-block";
...@@ -295,6 +298,7 @@ EOD; ...@@ -295,6 +298,7 @@ EOD;
$actualJsExpression = $actualValue['validate']; $actualJsExpression = $actualValue['validate'];
$this->assertEquals($expectedJsExpression, $actualJsExpression->expression); $this->assertEquals($expectedJsExpression, $actualJsExpression->expression);
$this->assertTrue($expectedValidateOnChange === $actualValue['validateOnChange']); $this->assertTrue($expectedValidateOnChange === $actualValue['validateOnChange']);
$this->assertTrue($expectedValidateOnBlur === $actualValue['validateOnBlur']);
$this->assertTrue($expectedValidateOnType === $actualValue['validateOnType']); $this->assertTrue($expectedValidateOnType === $actualValue['validateOnType']);
$this->assertTrue($expectedValidationDelay === $actualValue['validationDelay']); $this->assertTrue($expectedValidationDelay === $actualValue['validationDelay']);
$this->assertTrue(1 === $actualValue['enableAjaxValidation']); $this->assertTrue(1 === $actualValue['enableAjaxValidation']);
...@@ -317,6 +321,7 @@ EOD; ...@@ -317,6 +321,7 @@ EOD;
. "{ return 'yii2' == 'yii2'; }(attribute, value)) { return true; }}"; . "{ return 'yii2' == 'yii2'; }(attribute, value)) { return true; }}";
$expectedValidateOnChange = true; $expectedValidateOnChange = true;
$expectedValidateOnBlur = true;
$expectedValidateOnType = false; $expectedValidateOnType = false;
$expectedValidationDelay = 200; $expectedValidationDelay = 200;
$expectedError = ".help-block"; $expectedError = ".help-block";
...@@ -324,6 +329,7 @@ EOD; ...@@ -324,6 +329,7 @@ EOD;
$actualJsExpression = $actualValue['validate']; $actualJsExpression = $actualValue['validate'];
$this->assertEquals($expectedJsExpression, $actualJsExpression->expression); $this->assertEquals($expectedJsExpression, $actualJsExpression->expression);
$this->assertTrue($expectedValidateOnChange === $actualValue['validateOnChange']); $this->assertTrue($expectedValidateOnChange === $actualValue['validateOnChange']);
$this->assertTrue($expectedValidateOnBlur === $actualValue['validateOnBlur']);
$this->assertTrue($expectedValidateOnType === $actualValue['validateOnType']); $this->assertTrue($expectedValidateOnType === $actualValue['validateOnType']);
$this->assertTrue($expectedValidationDelay === $actualValue['validationDelay']); $this->assertTrue($expectedValidationDelay === $actualValue['validationDelay']);
$this->assertTrue(1 === $actualValue['enableAjaxValidation']); $this->assertTrue(1 === $actualValue['enableAjaxValidation']);
...@@ -364,7 +370,7 @@ class ActiveFieldExtend extends ActiveField ...@@ -364,7 +370,7 @@ class ActiveFieldExtend extends ActiveField
} }
/** /**
* Usefull to test other methods from ActiveField, that call ActiveField::getClientOptions() * Useful to test other methods from ActiveField, that call ActiveField::getClientOptions()
* but it's return value is not relevant for the test being run. * but it's return value is not relevant for the test being run.
*/ */
public function getClientOptions() public function getClientOptions()
......
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