Skip to content

Commit

Permalink
Fixes yiisoft#7259: Added errorAttributes parameter to ActiveForm `…
Browse files Browse the repository at this point in the history
…afterValidate` event. Made scrolling to first error optional
  • Loading branch information
nkovacs authored and samdark committed Aug 2, 2015
1 parent d3e91ab commit 2577a59
Showing 3 changed files with 33 additions and 15 deletions.
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -121,6 +121,7 @@ Yii Framework 2 Change Log
- Enh #6442: Improved error message on `FileHelper::createDirectory()` to include the path name of the directory (cebe)
- Enh #6895: Added `ignoreCategories` config option for message command to ignore categories specified (samdark)
- Enh #6975: Pressing arrows while focused in inputs of Active Form with `validateOnType` enabled no longer triggers validation (slinstj)
- Enh #7259: Added `errorAttributes` parameter to ActiveForm `afterValidate` event. Made scrolling to first error optional (nkovacs)
- Enh #7409: Allow `yii\filters\auth\CompositeAuth::authMethods` to take authentication objects (fernandezekiel, qiangxue)
- Enh #7443: Allow specification of the `$key` as an array at `yii\helpers\ArrayHelper::getValue()` (Alex-Code)
- Enh #7488: Added `StringHelper::explode` to perform explode with trimming and skipping of empty elements (SilverFire, nineinchnick, creocoder, samdark)
40 changes: 25 additions & 15 deletions framework/assets/yii.activeForm.js
Original file line number Diff line number Diff line change
@@ -40,11 +40,12 @@
/**
* afterValidate event is triggered after validating the whole form.
* The signature of the event handler should be:
* function (event, messages)
* function (event, messages, errorAttributes)
* where
* - event: an Event object.
* - messages: an associative array with keys being attribute IDs and values being error message arrays
* for the corresponding attributes.
* - errorAttributes: an array of attributes that have validation errors. Please refer to attributeDefaults for the structure of this parameter.
*/
afterValidate: 'afterValidate',
/**
@@ -121,7 +122,9 @@
// the type of data that you're expecting back from the server
ajaxDataType: 'json',
// the URL for performing AJAX-based validation. If not set, it will use the the form's action
validationUrl: undefined
validationUrl: undefined,
// whether to scroll to first visible error after validation.
scrollToError: true
};

// NOTE: If you change any of these defaults, make sure you update yii\widgets\ActiveField::getClientOptions() as well
@@ -160,12 +163,12 @@


var submitDefer;

var setSubmitFinalizeDefer = function($form) {
submitDefer = $.Deferred();
$form.data('yiiSubmitFinalizePromise', submitDefer.promise());
};

// finalize yii.js $form.submit
var submitFinalize = function($form) {
if(submitDefer) {
@@ -213,6 +216,18 @@
});
$form.on('submit.yiiActiveForm', methods.submitForm);
}
if (settings.scrollToError) {
$form.on('afterValidate.yiiActiveForm', function(event, messages, errorAttributes) {
var top = $form.find($.map(errorAttributes, function(attribute) {
return attribute.input;
}).join(',')).first().closest(':visible').offset().top;
var wtop = $(window).scrollTop();
if (top < wtop || top > wtop + $(window).height()) {
$(window).scrollTop(top);
}
});
}

});
},

@@ -392,7 +407,7 @@
} else {
// First submit's call (from yii.js/handleAction) - execute validating
setSubmitFinalizeDefer($form);

if (data.settings.timer !== undefined) {
clearTimeout(data.settings.timer);
}
@@ -488,7 +503,7 @@
methods.validate.call($form);
}, validationDelay ? validationDelay : 200);
};

/**
* Returns an array prototype with a shortcut method for adding a new deferred.
* The context of the callback will be the deferred object so it can be resolved like ```this.resolve()```
@@ -512,23 +527,18 @@
var data = $form.data('yiiActiveForm');

if (submitting) {
var errorInputs = [];
var errorAttributes = [];
$.each(data.attributes, function () {
if (!this.cancelled && updateInput($form, this, messages)) {
errorInputs.push(this.input);
errorAttributes.push(this);
}
});

$form.trigger(events.afterValidate, [messages]);
$form.trigger(events.afterValidate, [messages, errorAttributes]);

updateSummary($form, messages);

if (errorInputs.length) {
var top = $form.find(errorInputs.join(',')).first().closest(':visible').offset().top;
var wtop = $(window).scrollTop();
if (top < wtop || top > wtop + $(window).height()) {
$(window).scrollTop(top);
}
if (errorAttributes.length) {
data.submitting = false;
} else {
data.validated = true;
7 changes: 7 additions & 0 deletions framework/widgets/ActiveForm.php
Original file line number Diff line number Diff line change
@@ -151,6 +151,11 @@ class ActiveForm extends Widget
* @var string the type of data that you're expecting back from the server.
*/
public $ajaxDataType = 'json';
/**
* @var boolean whether to scroll to the first error after validation.
* @since 2.0.6
*/
public $scrollToError = true;
/**
* @var array the client validation options for individual attributes. Each element of the array
* represents the validation options for a particular attribute.
@@ -214,6 +219,7 @@ protected function getClientOptions()
'validatingCssClass' => $this->validatingCssClass,
'ajaxParam' => $this->ajaxParam,
'ajaxDataType' => $this->ajaxDataType,
'scrollToError' => $this->scrollToError,
];
if ($this->validationUrl !== null) {
$options['validationUrl'] = Url::to($this->validationUrl);
@@ -229,6 +235,7 @@ protected function getClientOptions()
'validatingCssClass' => 'validating',
'ajaxParam' => 'ajax',
'ajaxDataType' => 'json',
'scrollToError' => true,
]);
}

0 comments on commit 2577a59

Please sign in to comment.