Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix maximumSelectionLength being ignored by closeOnSelect #5581

Merged
merged 2 commits into from Jul 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/js/select2/data/maximumSelectionLength.js
Expand Up @@ -7,10 +7,30 @@ define([
decorated.call(this, $e, options);
}

MaximumSelectionLength.prototype.bind =
function (decorated, container, $container) {
var self = this;

decorated.call(this, container, $container);

container.on('select', function () {
self._checkIfMaximumSelected();
});
};

MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
var self = this;

this._checkIfMaximumSelected(function () {
decorated.call(self, params, callback);
});
};

MaximumSelectionLength.prototype._checkIfMaximumSelected =
function (_, successCallback) {
var self = this;

this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
Expand All @@ -23,7 +43,10 @@ define([
});
return;
}
decorated.call(self, params, callback);

if (successCallback) {
successCallback();
}
});
};

Expand Down
190 changes: 70 additions & 120 deletions tests/data/maximumSelectionLength-tests.js
@@ -1,202 +1,152 @@
module('Data adapters - Maximum selection length');

var SelectData = require('select2/data/select');
var MaximumSelectionLength = require('select2/data/maximumSelectionLength');

var $ = require('jquery');
var Options = require('select2/options');
var Utils = require('select2/utils');

function MaximumSelectionStub () {
this.called = false;
this.currentData = [];
}
var MaximumSelectionData = Utils.Decorate(SelectData, MaximumSelectionLength);

MaximumSelectionStub.prototype.current = function (callback) {
callback(this.currentData);
};

MaximumSelectionStub.prototype.val = function (val) {
this.currentData.push(val);
};

MaximumSelectionStub.prototype.query = function (params, callback) {
this.called = true;
};
test('0 never displays the notice', function (assert) {
assert.expect(3);

var MaximumSelectionData = Utils.Decorate(
MaximumSelectionStub,
MaximumSelectionLength
);
var $select = $('#qunit-fixture .multiple');

test('0 never displays the notice', function (assert) {
var zeroOptions = new Options({
maximumSelectionLength: 0
});

var data = new MaximumSelectionData(null, zeroOptions);
var container = new MockContainer();
var data = new MaximumSelectionData($select, zeroOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.bind(container, null);

data.on('results:message', function () {
assert.ok(false, 'The message should not be displayed');
});

data.query({
term: ''
}, function () {
assert.ok(true, 'The results should be queried');
});

assert.ok(data.called);

data = new MaximumSelectionData(null, zeroOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};

data.val('1');
$select.val(['One']);

data.query({
term: ''
}, function () {
assert.ok(true, 'The results should be queried');
});

assert.ok(data.called);

data = new MaximumSelectionData(null, zeroOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};

data.val('1');
data.val('2');
$select.val(['One', 'Two']);

data.query({
term: ''
}, function () {
assert.ok(true, 'The results should be queried');
});

assert.ok(data.called);
});

test('< 0 never displays the notice', function (assert) {
assert.expect(3);

var $select = $('#qunit-fixture .multiple');

var negativeOptions = new Options({
maximumSelectionLength: -1
});

var data = new MaximumSelectionData(null, negativeOptions);
var container = new MockContainer();
var data = new MaximumSelectionData($select, negativeOptions);

data.bind(container, null);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.on('results:message', function () {
assert.ok(false, 'The message should not be displayed');
});

data.query({
term: ''
}, function () {
assert.ok(true, 'The results should be queried');
});

assert.ok(data.called);

data = new MaximumSelectionData(null, negativeOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};

data.val('1');
$select.val(['One']);

data.query({
term: ''
}, function () {
assert.ok(true, 'The results should be queried');
});

assert.ok(data.called);

data = new MaximumSelectionData(null, negativeOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};

data.val('1');
data.val('2');
$select.val(['One', 'Two']);

data.query({
term: ''
}, function () {
assert.ok(true, 'The results should be queried');
});

assert.ok(data.called);
});

test('triggers when >= 1 selection' , function (assert) {
var maxOfOneOptions = new Options({
maximumSelectionLength: 1
});
var data = new MaximumSelectionData(null, maxOfOneOptions);
assert.expect(2);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
var $select = $('#qunit-fixture .multiple');

data.query({
term: ''
var maxOfOneOptions = new Options({
maximumSelectionLength: 1
});

assert.ok(data.called);
var container = new MockContainer();
var data = new MaximumSelectionData($select, maxOfOneOptions);

data = new MaximumSelectionData(null, maxOfOneOptions);
data.bind(container, null);

data.trigger = function () {
assert.ok(true, 'The event should be triggered.');
};
data.on('results:message', function () {
assert.ok(true, 'The message should be displayed');
});

data.val('1');
$select.val(['One']);

data.query({
term: ''
}, function () {
assert.ok(false, 'The results should not be queried');
});

assert.ok(!data.called);

});

test('triggers when >= 2 selections' , function (assert) {
var maxOfTwoOptions = new Options({
maximumSelectionLength: 2
});
var data = new MaximumSelectionData(null, maxOfTwoOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
$select.val(['One', 'Two']);

data.query({
term: ''
}, function () {
assert.ok(false, 'The results should not be queried');
});
});

assert.ok(data.called);

data = new MaximumSelectionData(null, maxOfTwoOptions);

data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
test('triggers after selection' , function (assert) {
assert.expect(1);

data.val('1');
var $select = $('#qunit-fixture .multiple');

data.query({
term: ''
var maxOfOneOptions = new Options({
maximumSelectionLength: 1
});

assert.ok(data.called);

data = new MaximumSelectionData(null, maxOfTwoOptions);

data.trigger = function () {
assert.ok(true, 'The event should be triggered.');
};
var container = new MockContainer();
var data = new MaximumSelectionData($select, maxOfOneOptions);

data.val('1');
data.val('2');
data.bind(container, null);

data.query({
term: ''
data.on('results:message', function () {
assert.ok(true, 'The message should be displayed');
});

assert.ok(!data.called);
$select.val(['One']);

container.trigger('select', {
data: {}
});
});