From 662e367cce77cc063ee0ca5abd00fb01c2884ad4 Mon Sep 17 00:00:00 2001 From: Andriy Borysov Date: Tue, 18 Jun 2019 16:21:20 +0300 Subject: [PATCH] Fixes #17332: Trigger 'change' for checkboxes in GridView --- framework/CHANGELOG.md | 1 + framework/assets/yii.gridView.js | 4 ++-- tests/js/tests/yii.gridView.test.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 2dd826d0ff..87c142baed 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -13,6 +13,7 @@ Yii Framework 2 Change Log - Bug #17341: Allowed callable objects to be set to `\yii\filters\AccessRule::$roleParams` (alexkart) - Bug #17070: Striped invalid character from fallback file name in `Content-Disposition` header when using `\yii\web\Response::sendFile` (alexkart) - Bug #16565: Added missing parts of the context message in `\yii\log\Target::collect` (alexkart) +- Bug #17332: Trigger 'change' for checkboxes in GridView (andrii-borysov-me) 2.0.20 June 04, 2019 diff --git a/framework/assets/yii.gridView.js b/framework/assets/yii.gridView.js index 4792acbf9c..25ff9600e1 100644 --- a/framework/assets/yii.gridView.js +++ b/framework/assets/yii.gridView.js @@ -192,11 +192,11 @@ var inputs = options['class'] ? "input." + options['class'] : "input[name='" + options.name + "']"; var inputsEnabled = "#" + id + " " + inputs + ":enabled"; initEventHandler($grid, 'checkAllRows', 'click.yiiGridView', checkAll, function () { - $grid.find(inputs + ":enabled").prop('checked', this.checked); + $grid.find(inputs + ":enabled").prop('checked', this.checked).change(); }); initEventHandler($grid, 'checkRow', 'click.yiiGridView', inputsEnabled, function () { var all = $grid.find(inputs).length == $grid.find(inputs + ":checked").length; - $grid.find("input[name='" + options.checkAll + "']").prop('checked', all); + $grid.find("input[name='" + options.checkAll + "']").prop('checked', all).change(); }); }, diff --git a/tests/js/tests/yii.gridView.test.js b/tests/js/tests/yii.gridView.test.js index 290b0bd335..adee40967f 100644 --- a/tests/js/tests/yii.gridView.test.js +++ b/tests/js/tests/yii.gridView.test.js @@ -588,6 +588,16 @@ describe('yii.gridView', function () { }); describe('with name, multiple and checkAll options, multiple set to true and', function () { + var changedSpy; + + before(function () { + changedSpy = sinon.spy(); + }); + + after(function () { + changedSpy.reset(); + }); + withData({ 'nothing else': [{}], // https://github.com/yiisoft/yii2/pull/11729 @@ -602,44 +612,63 @@ describe('yii.gridView', function () { assert.equal($gridView.yiiGridView('data').selectionColumn, 'selection[]'); + $checkRowCheckboxes + .off('change.yiiGridView') // unbind any subscriptions for clean expectations + .on('change.yiiGridView', changedSpy); + var $checkFirstRowCheckbox = $checkRowCheckboxes.filter('[value="1"]'); // Check all + changedSpy.reset(); click($checkAllCheckbox); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 3); assert.isTrue($checkAllCheckbox.prop('checked')); + assert.equal(changedSpy.callCount, 3); // Uncheck all + changedSpy.reset(); click($checkAllCheckbox); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 0); assert.isFalse($checkAllCheckbox.prop('checked')); + assert.equal(changedSpy.callCount, 3); // Check all manually + changedSpy.reset(); click($checkRowCheckboxes); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 3); assert.isTrue($checkAllCheckbox.prop('checked')); + assert.equal(changedSpy.callCount, 3); // Uncheck all manually + changedSpy.reset(); click($checkRowCheckboxes); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 0); assert.isFalse($checkAllCheckbox.prop('checked')); + assert.equal(changedSpy.callCount, 3); // Check first row + changedSpy.reset(); click($checkFirstRowCheckbox); assert.isTrue($checkFirstRowCheckbox.prop('checked')); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 1); assert.isFalse($checkAllCheckbox.prop('checked')); + assert.equal(changedSpy.callCount, 1); // Then check all + changedSpy.reset(); click($checkAllCheckbox); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 3); assert.isTrue($checkAllCheckbox.prop('checked')); + // "change" should be called 3 times, 1 time per each row, no matter what state it has + assert.equal(changedSpy.callCount, 3); // Uncheck first row + changedSpy.reset(); click($checkFirstRowCheckbox); assert.isFalse($checkFirstRowCheckbox.prop('checked')); assert.lengthOf($checkRowCheckboxes.filter(':checked'), 2); assert.isFalse($checkAllCheckbox.prop('checked')); + assert.equal(changedSpy.callCount, 1); }); }); });