diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index e12dda91810a..fb76d8dd83b8 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -26,7 +26,7 @@ }, { "path": "./dist/js/bootstrap.bundle.js", - "maxSize": "47.50 kB" + "maxSize": "47.5 kB" }, { "path": "./dist/js/bootstrap.bundle.min.js", @@ -34,7 +34,7 @@ }, { "path": "./dist/js/bootstrap.js", - "maxSize": "25 kB" + "maxSize": "25.5 kB" }, { "path": "./dist/js/bootstrap.min.js", diff --git a/js/src/button.js b/js/src/button.js index d793785829fc..c95013a98cd3 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -46,6 +46,7 @@ const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` class Button { constructor(element) { this._element = element + this.shouldAvoidTriggerChange = false } // Getters @@ -83,7 +84,9 @@ class Button { input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE) } - $(input).trigger('change') + if (!this.shouldAvoidTriggerChange) { + $(input).trigger('change') + } } input.focus() @@ -109,7 +112,7 @@ class Button { // Static - static _jQueryInterface(config) { + static _jQueryInterface(config, avoidTriggerChange) { return this.each(function () { const $element = $(this) let data = $element.data(DATA_KEY) @@ -119,6 +122,8 @@ class Button { $element.data(DATA_KEY, data) } + data.shouldAvoidTriggerChange = avoidTriggerChange + if (config === 'toggle') { data[config]() } @@ -151,8 +156,8 @@ $(document) return } - if (initialButton.tagName !== 'LABEL' || inputBtn && inputBtn.type !== 'checkbox') { - Button._jQueryInterface.call($(button), 'toggle') + if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') { + Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT') } } }) diff --git a/js/tests/unit/button.js b/js/tests/unit/button.js index 2adffedd9fe6..1bd62b6b8b60 100644 --- a/js/tests/unit/button.js +++ b/js/tests/unit/button.js @@ -180,6 +180,32 @@ $(function () { $group.find('label').trigger('click') }) + QUnit.test('should trigger label change event only once', function (assert) { + assert.expect(1) + var done = assert.async() + var countChangeEvent = 0 + + var groupHTML = '
' + + '' + + '
' + var $group = $(groupHTML).appendTo('#qunit-fixture') + + var $btn = $group.children().eq(0) + + $group.find('label').on('change', function () { + countChangeEvent++ + }) + + setTimeout(function () { + assert.ok(countChangeEvent === 1, 'onchange event fired only once') + done() + }, 5) + + $btn[0].click() + }) + QUnit.test('should check for closest matching toggle', function (assert) { assert.expect(18) var groupHTML = '
' +