1
0
mirror of synced 2024-12-01 09:06:03 +03:00
select2/tests/selection/allowClear-tests.js

401 lines
8.3 KiB
JavaScript
Raw Normal View History

module('Selection containers - Placeholders - Allow clear');
var Placeholder = require('select2/selection/placeholder');
var AllowClear = require('select2/selection/allowClear');
var SingleSelection = require('select2/selection/single');
allowClear no longer shifts selections to a new line (#5603) * allowClear no longer shifts selections to a new line This fixes an issue that we have had with the "x" icon used by the `allowClear` option where selections that just barely interacted with the position of the "x" icon would be pushed to a new line that was separate from the normal second line of selections. This case was pretty rare, because you only had a ~9px area where the interaction could occur. The issue was cuased by the "x" icon being sized for the height of the text in the selection choices, which should be the same as how the selection choices themselves are sized. Unfortunately this did not take into account the fact that the selection choices are given a 1px border which increases their size by 2px, which is what lead to the odd behaviour. This behaviour could not be replicated without the 1px border because the height would then line up correctly. The issue can be fixed by adding a 2px margin to the bottom of the "x" icon, which would force overlapping selections on to the correct second line of selections. This was the method that many users have been using to correct this issue, but was not the method we chose to use. A 1px padding has been added to the "x" icon instead, which should expand the touch area of the "x" by a little while also increasing the height of the "x" by enough to prevent the overlapping. Fixes #4470 * Remove hard-coded height in tests Because tests are executed on different browsers, and because each browser sets their own line height, we cannot depend on the height of the default Select2 being consistent across browsers. As a result, we must write our tests to calcualte the expected height based on known data. In the case of this test, we can calculate ahead of time what two rows of selections is supposed to look like, instead of the edge case that we can otherwise encounter.
2019-08-05 05:03:52 +03:00
var MultipleSelection = require('select2/selection/multiple');
var $ = require('jquery');
var Options = require('select2/options');
var Utils = require('select2/utils');
var AllowClearPlaceholder = Utils.Decorate(
Utils.Decorate(SingleSelection, Placeholder),
AllowClear
);
var allowClearOptions = new Options({
placeholder: {
id: 'placeholder',
text: 'This is the placeholder'
},
allowClear: true
});
test('clear is not displayed for single placeholder', function (assert) {
var selection = new AllowClearPlaceholder(
$('#qunit-fixture .single-with-placeholder'),
allowClearOptions
);
var $selection = selection.render();
selection.update([{
id: 'placeholder'
}]);
assert.equal(
$selection.find('.select2-selection__clear').length,
0,
'The clear icon should not be displayed'
);
});
test('clear is not displayed for multiple placeholder', function (assert) {
var selection = new AllowClearPlaceholder(
$('#qunit-fixture .multiple'),
allowClearOptions
);
var $selection = selection.render();
selection.update([]);
assert.equal(
$selection.find('.select2-selection__clear').length,
0,
'The clear icon should not be displayed'
);
});
test('clear is displayed for placeholder', function (assert) {
var selection = new AllowClearPlaceholder(
$('#qunit-fixture .single-with-placeholder'),
allowClearOptions
);
var $selection = selection.render();
selection.update([{
id: 'one',
test: 'one'
}]);
assert.equal(
$selection.find('.select2-selection__clear').length,
1,
'The clear icon should be displayed'
);
});
test('clear icon should have title displayed', function (assert) {
var selection = new AllowClearPlaceholder(
$('#qunit-fixture .single-with-placeholder'),
allowClearOptions
);
var $selection = selection.render();
selection.update([{
id: 'one',
test: 'one'
}]);
assert.equal(
$selection.find('.select2-selection__clear').attr('title'),
'Remove all items',
'The clear icon should have title displayed'
);
});
test('clicking clear will set the placeholder value', 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, $('<div></div>'));
$element.val('One');
selection.update([{
id: 'One',
text: 'One'
}]);
var $remove = $selection.find('.select2-selection__clear');
$remove.trigger('mousedown');
assert.equal(
$element.val(),
'placeholder',
'The value should have been reset to the placeholder'
);
});
test('clicking clear will trigger the unselect event', function (assert) {
assert.expect(4);
var $element = $('#qunit-fixture .single-with-placeholder');
var selection = new AllowClearPlaceholder(
$element,
allowClearOptions
);
var container = new MockContainer();
var $selection = selection.render();
selection.bind(container, $('<div></div>'));
$element.val('One');
selection.update([{
id: 'One',
text: 'One'
}]);
selection.on('unselect', function (ev) {
assert.ok(
'data' in ev && ev.data,
'The event should have been triggered with the data property'
);
assert.ok(
$.isPlainObject(ev.data),
'The data should be an object'
);
assert.equal(
ev.data.id,
'One',
'The data should be the unselected object'
);
assert.equal(
$element.val(),
'placeholder',
'The previous value should be unselected'
);
});
var $remove = $selection.find('.select2-selection__clear');
$remove.trigger('mousedown');
});
test('preventing the unselect 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, $('<div></div>'));
$element.val('One');
selection.update([{
id: 'One',
text: 'One'
}]);
selection.on('unselect', 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('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, $('<div></div>'));
$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, $('<div></div>'));
$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');
var selection = new AllowClearPlaceholder(
$element,
allowClearOptions
);
var container = new MockContainer();
var $selection = selection.render();
selection.bind(container, $('<div></div>'));
selection.update([{
id: 'One',
text: 'One'
}]);
$element.val('One');
selection.options.set('disabled', true);
var $remove = $selection.find('.select2-selection__clear');
$remove.trigger('mousedown');
assert.equal(
$element.val(),
'One',
'The placeholder should not have been set'
);
});
allowClear no longer shifts selections to a new line (#5603) * allowClear no longer shifts selections to a new line This fixes an issue that we have had with the "x" icon used by the `allowClear` option where selections that just barely interacted with the position of the "x" icon would be pushed to a new line that was separate from the normal second line of selections. This case was pretty rare, because you only had a ~9px area where the interaction could occur. The issue was cuased by the "x" icon being sized for the height of the text in the selection choices, which should be the same as how the selection choices themselves are sized. Unfortunately this did not take into account the fact that the selection choices are given a 1px border which increases their size by 2px, which is what lead to the odd behaviour. This behaviour could not be replicated without the 1px border because the height would then line up correctly. The issue can be fixed by adding a 2px margin to the bottom of the "x" icon, which would force overlapping selections on to the correct second line of selections. This was the method that many users have been using to correct this issue, but was not the method we chose to use. A 1px padding has been added to the "x" icon instead, which should expand the touch area of the "x" by a little while also increasing the height of the "x" by enough to prevent the overlapping. Fixes #4470 * Remove hard-coded height in tests Because tests are executed on different browsers, and because each browser sets their own line height, we cannot depend on the height of the default Select2 being consistent across browsers. As a result, we must write our tests to calcualte the expected height based on known data. In the case of this test, we can calculate ahead of time what two rows of selections is supposed to look like, instead of the edge case that we can otherwise encounter.
2019-08-05 05:03:52 +03:00
test('clear button doesnt visually break selected options', function (assert) {
var $element = $('<select></select>');
var Selection = Utils.Decorate(
Utils.Decorate(MultipleSelection, Placeholder),
AllowClear
);
var selection = new Selection(
$element,
allowClearOptions
);
var container = new MockContainer();
var $container = $(
'<span class="select2-container select2-container--default"></span>'
);
$('#qunit-fixture').append($container);
var $selection = selection.render();
$container.append($selection);
$container.css('width', '100px');
selection.bind(container, $container);
selection.update([{
id: '1',
text: '1'
}]);
var singleHeight = $container.height();
selection.update([
{
id: '10',
text: '10'
},
{
id: '20',
text: '20'
}
]);
var doubleHeight = $container.height();
selection.update([
{
id: '1',
text: '1'
},
{
id: '2',
text: '2'
}
]);
assert.notEqual(
singleHeight,
doubleHeight,
'The height of the two different rows should be different'
);
assert.equal(
$container.height(),
doubleHeight,
'There should be two full lines of selections'
);
});