Skip to content

Commit

Permalink
Fixes #14186, Fixes #14510: yiiActiveForm regressions
Browse files Browse the repository at this point in the history
- #14186: Forced validation in `yiiActiveForm` do not trigger `afterValidate` event
- #14510: The state of a form is always "not validated" when using forced validation in `yiiActiveForm`
  • Loading branch information
arogachev authored and samdark committed Jul 29, 2017
1 parent 37bd022 commit 8f2d9ba
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 32 deletions.
2 changes: 2 additions & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ Yii Framework 2 Change Log
- Bug #14074: Fixed default value of `yii\console\controllers\FixtureController::$globalFixtures` to contain valid class name (lynicidn)
- Bug #14094: Fixed bug when single `yii\web\UrlManager::createUrl()` call my result multiple calls of `yii\web\UrlRule::createUrl()` for the same rule (rossoneri)
- Bug #14133: Fixed bug when calculating timings with mixed nested profile begin and end in `yii\log\Logger::calculateTimings()` (bizley)
- Bug #14186: Forced validation in `yiiActiveForm` do not trigger `afterValidate` event (arogachev)
- Bug #14510: The state of a form is always "not validated" when using forced validation in `yiiActiveForm` (arogachev)
- Enh #4793: `yii\filters\AccessControl` now can be used without `user` component (bizley)
- Enh #4999: Added support for wildcards at `yii\filters\AccessRule::$controllers` (klimov-paul)
- Enh #5108: `yii\validators\DateValidator` now resets `$timestampAttribute` value on empty validated attribute value (klimov-paul)
Expand Down
10 changes: 5 additions & 5 deletions framework/assets/yii.activeForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@
needAjaxValidation = false,
messages = {},
deferreds = deferredArray(),
submitting = data.submitting && !forceValidate;
submitting = data.submitting;

if (data.submitting) {
if (submitting) {
var event = $.Event(events.beforeValidate);
$form.trigger(event, [messages, deferreds]);

Expand Down Expand Up @@ -391,7 +391,7 @@
});
} else if (data.submitting) {
// delay callback so that the form can be submitted without problem
setTimeout(function () {
window.setTimeout(function () {
updateInputs($form, messages, submitting);
}, 200);
} else {
Expand Down Expand Up @@ -435,7 +435,7 @@
// Because we bind directly to a form reset event instead of a reset button (that may not exist),
// when this function is executed form input values have not been reset yet.
// Therefore we do the actual reset work through setTimeout.
setTimeout(function () {
window.setTimeout(function () {
$.each(data.attributes, function () {
// Without setTimeout() we would get the input values that are not reset yet.
this.value = getValue($form, this);
Expand Down Expand Up @@ -535,7 +535,7 @@
if (data.settings.timer !== undefined) {
clearTimeout(data.settings.timer);
}
data.settings.timer = setTimeout(function () {
data.settings.timer = window.setTimeout(function () {
if (data.submitting || $form.is(':hidden')) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/js/data/yii.activeForm.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<form id="main">
<input id="nameInput" type="text" name="name" value="value" />
<form id="w0">
<input id="name" type="text" name="name" value="">
</form>
81 changes: 56 additions & 25 deletions tests/js/tests/yii.activeForm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('yii.activeForm', function () {
var yiiPath = 'framework/assets/yii.js';
var jQueryPath = 'vendor/bower-asset/jquery/dist/jquery.js';
var $;
var $mainForm;
var $activeForm;

function registerYii() {
var code = fs.readFileSync(yiiPath);
Expand All @@ -25,11 +25,7 @@ describe('yii.activeForm', function () {
var yii = registerYii();
var code = fs.readFileSync(yiiActiveFormPath);
var script = new vm.Script(code);
var context = new vm.createContext({
window: window,
document: window.document,
yii: yii
});
var context = new vm.createContext({window: window, document: window.document, yii: yii});
script.runInContext(context);
}

Expand All @@ -47,41 +43,76 @@ describe('yii.activeForm', function () {
sinon = require('sinon');
});

beforeEach(function () {
$mainForm = $('#main');
describe('validate method', function () {
var windowSetTimeoutStub;
var afterValidateSpy;

beforeEach(function () {
windowSetTimeoutStub = sinon.stub(window, 'setTimeout', function (callback) {
callback();
});
afterValidateSpy = sinon.spy();
});

afterEach(function () {
windowSetTimeoutStub.restore();
afterValidateSpy.reset();
});

describe('with forceValidate parameter set to true', function () {
it('should trigger manual form validation', function () {
var inputId = 'name';

$activeForm = $('#w0');
$activeForm.yiiActiveForm([
{
id: inputId,
input: '#' + inputId
}
]).on('afterValidate', afterValidateSpy);

$activeForm.yiiActiveForm('validate', true);
// https://github.com/yiisoft/yii2/issues/14510
assert.isTrue($activeForm.data('yiiActiveForm').validated);
// https://github.com/yiisoft/yii2/issues/14186
assert.isTrue(afterValidateSpy.calledOnce);
});
});
});

describe('events', function () {
describe('afterValidateAttribute', function () {
var afterValidateAttributeEventSpy;
var dataForAssert;
var afterValidateAttributeSpy;
var eventData;

before(function () {
afterValidateAttributeEventSpy = sinon.spy(function (event, data) {
dataForAssert = data.value;
afterValidateAttributeSpy = sinon.spy(function (event, data) {
eventData = data;
});
});

after(function () {
afterValidateAttributeEventSpy.reset();
afterValidateAttributeSpy.reset();
});

it('should update attribute value', function () {
var inputId = 'nameInput',
$input = $('#' + inputId);
$mainForm.yiiActiveForm([
// https://github.com/yiisoft/yii2/issues/14318

it('should allow to get updated attribute value', function () {
var inputId = 'name';
var $input = $('#' + inputId);

$activeForm = $('#w0');
$activeForm.yiiActiveForm([
{
id : inputId,
id: inputId,
input: '#' + inputId
}
]).on('afterValidateAttribute', afterValidateAttributeEventSpy);

// Set new value, update attribute
$input.val('newValue');
$mainForm.yiiActiveForm('updateAttribute', inputId);
]).on('afterValidateAttribute', afterValidateAttributeSpy);

assert.equal('newValue', dataForAssert);
$input.val('New value');
$activeForm.yiiActiveForm('updateAttribute', inputId);
assert.equal('New value', eventData.value);
});
});
});
});
});

0 comments on commit 8f2d9ba

Please sign in to comment.