diff --git a/src/js/select2/core.js b/src/js/select2/core.js index 4ba06edb3e..1445f17b76 100644 --- a/src/js/select2/core.js +++ b/src/js/select2/core.js @@ -417,7 +417,8 @@ define([ 'open': 'opening', 'close': 'closing', 'select': 'selecting', - 'unselect': 'unselecting' + 'unselect': 'unselecting', + 'clear': 'clearing' }; if (args === undefined) { diff --git a/src/js/select2/selection/allowClear.js b/src/js/select2/selection/allowClear.js index d3502069f5..a7bbc2ea94 100644 --- a/src/js/select2/selection/allowClear.js +++ b/src/js/select2/selection/allowClear.js @@ -45,8 +45,20 @@ define([ var data = $clear.data('data'); + var previousVal = this.$element.val(); + this.$element.val(this.placeholder.id); + + var unselectData = { + data: data + }; + this.trigger('clear', unselectData); + if (unselectData.prevented) { + this.$element.val(previousVal); + return; + } + for (var d = 0; d < data.length; d++) { - var unselectData = { + unselectData = { data: data[d] }; @@ -56,11 +68,12 @@ define([ // If the event was prevented, don't clear it out. if (unselectData.prevented) { + this.$element.val(previousVal); return; } } - this.$element.val(this.placeholder.id).trigger('change'); + this.$element.trigger('change'); this.trigger('toggle', {}); }; diff --git a/src/js/select2/selection/eventRelay.js b/src/js/select2/selection/eventRelay.js index a91e9c5776..0f59822bab 100644 --- a/src/js/select2/selection/eventRelay.js +++ b/src/js/select2/selection/eventRelay.js @@ -9,10 +9,13 @@ define([ 'open', 'opening', 'close', 'closing', 'select', 'selecting', - 'unselect', 'unselecting' + 'unselect', 'unselecting', + 'clear', 'clearing' ]; - var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting']; + var preventableEvents = [ + 'opening', 'closing', 'selecting', 'unselecting', 'clearing' + ]; decorated.call(this, container, $container); diff --git a/tests/selection/allowClear-tests.js b/tests/selection/allowClear-tests.js index efa132aae3..f33fc0e56b 100644 --- a/tests/selection/allowClear-tests.js +++ b/tests/selection/allowClear-tests.js @@ -43,7 +43,7 @@ test('clear is not displayed for single placeholder', function (assert) { test('clear is not displayed for multiple placeholder', function (assert) { var selection = new AllowClearPlaceholder( - $('#qunit-fixture .single-with-placeholder'), + $('#qunit-fixture .multiple'), allowClearOptions ); @@ -90,7 +90,7 @@ test('clicking clear will set the placeholder value', function (assert) { var $selection = selection.render(); - selection.bind(container, $('
')); $element.val('One'); selection.update([{ @@ -109,7 +109,7 @@ test('clicking clear will set the placeholder value', function (assert) { }); test('clicking clear will trigger the unselect event', function (assert) { - assert.expect(3); + assert.expect(4); var $element = $('#qunit-fixture .single-with-placeholder'); @@ -121,7 +121,7 @@ test('clicking clear will trigger the unselect event', function (assert) { var $selection = selection.render(); - selection.bind(container, $('
')); $element.val('One'); selection.update([{ @@ -143,7 +143,13 @@ test('clicking clear will trigger the unselect event', function (assert) { assert.equal( ev.data.id, 'One', - 'The previous object should be unselected' + 'The data should be the unselected object' + ); + + assert.equal( + $element.val(), + 'placeholder', + 'The previous value should be unselected' ); }); @@ -151,8 +157,6 @@ test('clicking clear will trigger the unselect event', function (assert) { $remove.trigger('mousedown'); }); - - test('preventing the unselect event cancels the clearing', function (assert) { var $element = $('#qunit-fixture .single-with-placeholder'); @@ -164,7 +168,7 @@ test('preventing the unselect event cancels the clearing', function (assert) { var $selection = selection.render(); - selection.bind(container, $('
')); $element.val('One'); selection.update([{ @@ -186,6 +190,94 @@ test('preventing the unselect event cancels the clearing', function (assert) { ); }); +test('clicking clear will trigger the clear event', function (assert) { + assert.expect(5); + + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + selection.on('clear', function (ev) { + assert.ok( + 'data' in ev && ev.data, + 'The event should have been triggered with the data property' + ); + + assert.ok( + $.isArray(ev.data), + 'The data should be an array' + ); + + assert.equal( + ev.data.length, + 1, + 'The data should contain one item for each value' + ); + + assert.equal( + ev.data[0].id, + 'One', + 'The data should contain unselected objects' + ); + + assert.equal( + $element.val(), + 'placeholder', + 'The previous value should be unselected' + ); + }); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); +}); + +test('preventing the clear event cancels the clearing', function (assert) { + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + selection.on('clear', function (ev) { + ev.prevented = true; + }); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); + + assert.equal( + $element.val(), + 'One', + 'The placeholder should not have been set' + ); +}); + test('clear does not work when disabled', function (assert) { var $element = $('#qunit-fixture .single-with-placeholder'); @@ -197,7 +289,7 @@ test('clear does not work when disabled', function (assert) { var $selection = selection.render(); - selection.bind(container, $('
')); selection.update([{ id: 'One',