Added selectOnClose
`selectOnClose` is a new option which works very much like the old `selectOnBlur` option. When the `close` event is triggered, the highlighted result is automatically selected. This is useful for single selects, which is where it is designed to be used, but it can also be used on multiple selects. This also adds tests to verify that this works in the future. During the creation of the test, we noticed that we were missing a mock container that could be used for triggering events. One was created and a general mock JS file was created to hold any future mocks for tests.
This commit is contained in:
parent
af1f35176b
commit
584d3b48a2
45
dist/js/select2.amd.full.js
vendored
45
dist/js/select2.amd.full.js
vendored
@ -3308,6 +3308,34 @@ define('select2/dropdown/minimumResultsForSearch',[
|
||||
return MinimumResultsForSearch;
|
||||
});
|
||||
|
||||
define('select2/dropdown/selectOnClose',[
|
||||
|
||||
], function () {
|
||||
function SelectOnClose () { }
|
||||
|
||||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||||
var self = this;
|
||||
|
||||
decorated.call(this, container, $container);
|
||||
|
||||
container.on('close', function () {
|
||||
self._handleSelectOnClose();
|
||||
});
|
||||
};
|
||||
|
||||
SelectOnClose.prototype._handleSelectOnClose = function () {
|
||||
var $highlightedResults = this.getHighlightedResults();
|
||||
|
||||
if ($highlightedResults.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$highlightedResults.trigger('mouseup');
|
||||
};
|
||||
|
||||
return SelectOnClose;
|
||||
});
|
||||
|
||||
define('select2/i18n/en',[],function () {
|
||||
// English
|
||||
return {
|
||||
@ -3382,6 +3410,7 @@ define('select2/defaults',[
|
||||
'./dropdown/infiniteScroll',
|
||||
'./dropdown/attachBody',
|
||||
'./dropdown/minimumResultsForSearch',
|
||||
'./dropdown/selectOnClose',
|
||||
|
||||
'./i18n/en'
|
||||
], function ($, ResultsList,
|
||||
@ -3395,7 +3424,7 @@ define('select2/defaults',[
|
||||
MinimumInputLength, MaximumInputLength,
|
||||
|
||||
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
|
||||
AttachBody, MinimumResultsForSearch,
|
||||
AttachBody, MinimumResultsForSearch, SelectOnClose,
|
||||
|
||||
EnglishTranslation) {
|
||||
function Defaults () {
|
||||
@ -3474,6 +3503,13 @@ define('select2/defaults',[
|
||||
);
|
||||
}
|
||||
|
||||
if (options.selectOnClose) {
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
SelectOnClose
|
||||
);
|
||||
}
|
||||
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
AttachBody
|
||||
@ -3607,12 +3643,13 @@ define('select2/defaults',[
|
||||
this.defaults = {
|
||||
language: EnglishTranslation,
|
||||
matcher: matcher,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
minimumInputLength: 0,
|
||||
maximumInputLength: 0,
|
||||
minimumResultsForSearch: 0,
|
||||
selectOnClose: false,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
templateResult: function (result) {
|
||||
return result.text;
|
||||
},
|
||||
|
45
dist/js/select2.amd.js
vendored
45
dist/js/select2.amd.js
vendored
@ -3308,6 +3308,34 @@ define('select2/dropdown/minimumResultsForSearch',[
|
||||
return MinimumResultsForSearch;
|
||||
});
|
||||
|
||||
define('select2/dropdown/selectOnClose',[
|
||||
|
||||
], function () {
|
||||
function SelectOnClose () { }
|
||||
|
||||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||||
var self = this;
|
||||
|
||||
decorated.call(this, container, $container);
|
||||
|
||||
container.on('close', function () {
|
||||
self._handleSelectOnClose();
|
||||
});
|
||||
};
|
||||
|
||||
SelectOnClose.prototype._handleSelectOnClose = function () {
|
||||
var $highlightedResults = this.getHighlightedResults();
|
||||
|
||||
if ($highlightedResults.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$highlightedResults.trigger('mouseup');
|
||||
};
|
||||
|
||||
return SelectOnClose;
|
||||
});
|
||||
|
||||
define('select2/i18n/en',[],function () {
|
||||
// English
|
||||
return {
|
||||
@ -3382,6 +3410,7 @@ define('select2/defaults',[
|
||||
'./dropdown/infiniteScroll',
|
||||
'./dropdown/attachBody',
|
||||
'./dropdown/minimumResultsForSearch',
|
||||
'./dropdown/selectOnClose',
|
||||
|
||||
'./i18n/en'
|
||||
], function ($, ResultsList,
|
||||
@ -3395,7 +3424,7 @@ define('select2/defaults',[
|
||||
MinimumInputLength, MaximumInputLength,
|
||||
|
||||
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
|
||||
AttachBody, MinimumResultsForSearch,
|
||||
AttachBody, MinimumResultsForSearch, SelectOnClose,
|
||||
|
||||
EnglishTranslation) {
|
||||
function Defaults () {
|
||||
@ -3474,6 +3503,13 @@ define('select2/defaults',[
|
||||
);
|
||||
}
|
||||
|
||||
if (options.selectOnClose) {
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
SelectOnClose
|
||||
);
|
||||
}
|
||||
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
AttachBody
|
||||
@ -3607,12 +3643,13 @@ define('select2/defaults',[
|
||||
this.defaults = {
|
||||
language: EnglishTranslation,
|
||||
matcher: matcher,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
minimumInputLength: 0,
|
||||
maximumInputLength: 0,
|
||||
minimumResultsForSearch: 0,
|
||||
selectOnClose: false,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
templateResult: function (result) {
|
||||
return result.text;
|
||||
},
|
||||
|
45
dist/js/select2.full.js
vendored
45
dist/js/select2.full.js
vendored
@ -12843,6 +12843,34 @@ define('select2/dropdown/minimumResultsForSearch',[
|
||||
return MinimumResultsForSearch;
|
||||
});
|
||||
|
||||
define('select2/dropdown/selectOnClose',[
|
||||
|
||||
], function () {
|
||||
function SelectOnClose () { }
|
||||
|
||||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||||
var self = this;
|
||||
|
||||
decorated.call(this, container, $container);
|
||||
|
||||
container.on('close', function () {
|
||||
self._handleSelectOnClose();
|
||||
});
|
||||
};
|
||||
|
||||
SelectOnClose.prototype._handleSelectOnClose = function () {
|
||||
var $highlightedResults = this.getHighlightedResults();
|
||||
|
||||
if ($highlightedResults.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$highlightedResults.trigger('mouseup');
|
||||
};
|
||||
|
||||
return SelectOnClose;
|
||||
});
|
||||
|
||||
define('select2/i18n/en',[],function () {
|
||||
// English
|
||||
return {
|
||||
@ -12917,6 +12945,7 @@ define('select2/defaults',[
|
||||
'./dropdown/infiniteScroll',
|
||||
'./dropdown/attachBody',
|
||||
'./dropdown/minimumResultsForSearch',
|
||||
'./dropdown/selectOnClose',
|
||||
|
||||
'./i18n/en'
|
||||
], function ($, ResultsList,
|
||||
@ -12930,7 +12959,7 @@ define('select2/defaults',[
|
||||
MinimumInputLength, MaximumInputLength,
|
||||
|
||||
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
|
||||
AttachBody, MinimumResultsForSearch,
|
||||
AttachBody, MinimumResultsForSearch, SelectOnClose,
|
||||
|
||||
EnglishTranslation) {
|
||||
function Defaults () {
|
||||
@ -13009,6 +13038,13 @@ define('select2/defaults',[
|
||||
);
|
||||
}
|
||||
|
||||
if (options.selectOnClose) {
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
SelectOnClose
|
||||
);
|
||||
}
|
||||
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
AttachBody
|
||||
@ -13142,12 +13178,13 @@ define('select2/defaults',[
|
||||
this.defaults = {
|
||||
language: EnglishTranslation,
|
||||
matcher: matcher,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
minimumInputLength: 0,
|
||||
maximumInputLength: 0,
|
||||
minimumResultsForSearch: 0,
|
||||
selectOnClose: false,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
templateResult: function (result) {
|
||||
return result.text;
|
||||
},
|
||||
|
2
dist/js/select2.full.min.js
vendored
2
dist/js/select2.full.min.js
vendored
File diff suppressed because one or more lines are too long
45
dist/js/select2.js
vendored
45
dist/js/select2.js
vendored
@ -3736,6 +3736,34 @@ define('select2/dropdown/minimumResultsForSearch',[
|
||||
return MinimumResultsForSearch;
|
||||
});
|
||||
|
||||
define('select2/dropdown/selectOnClose',[
|
||||
|
||||
], function () {
|
||||
function SelectOnClose () { }
|
||||
|
||||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||||
var self = this;
|
||||
|
||||
decorated.call(this, container, $container);
|
||||
|
||||
container.on('close', function () {
|
||||
self._handleSelectOnClose();
|
||||
});
|
||||
};
|
||||
|
||||
SelectOnClose.prototype._handleSelectOnClose = function () {
|
||||
var $highlightedResults = this.getHighlightedResults();
|
||||
|
||||
if ($highlightedResults.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$highlightedResults.trigger('mouseup');
|
||||
};
|
||||
|
||||
return SelectOnClose;
|
||||
});
|
||||
|
||||
define('select2/i18n/en',[],function () {
|
||||
// English
|
||||
return {
|
||||
@ -3810,6 +3838,7 @@ define('select2/defaults',[
|
||||
'./dropdown/infiniteScroll',
|
||||
'./dropdown/attachBody',
|
||||
'./dropdown/minimumResultsForSearch',
|
||||
'./dropdown/selectOnClose',
|
||||
|
||||
'./i18n/en'
|
||||
], function ($, ResultsList,
|
||||
@ -3823,7 +3852,7 @@ define('select2/defaults',[
|
||||
MinimumInputLength, MaximumInputLength,
|
||||
|
||||
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
|
||||
AttachBody, MinimumResultsForSearch,
|
||||
AttachBody, MinimumResultsForSearch, SelectOnClose,
|
||||
|
||||
EnglishTranslation) {
|
||||
function Defaults () {
|
||||
@ -3902,6 +3931,13 @@ define('select2/defaults',[
|
||||
);
|
||||
}
|
||||
|
||||
if (options.selectOnClose) {
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
SelectOnClose
|
||||
);
|
||||
}
|
||||
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
AttachBody
|
||||
@ -4035,12 +4071,13 @@ define('select2/defaults',[
|
||||
this.defaults = {
|
||||
language: EnglishTranslation,
|
||||
matcher: matcher,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
minimumInputLength: 0,
|
||||
maximumInputLength: 0,
|
||||
minimumResultsForSearch: 0,
|
||||
selectOnClose: false,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
templateResult: function (result) {
|
||||
return result.text;
|
||||
},
|
||||
|
2
dist/js/select2.min.js
vendored
2
dist/js/select2.min.js
vendored
File diff suppressed because one or more lines are too long
17
src/js/select2/defaults.js
vendored
17
src/js/select2/defaults.js
vendored
@ -27,6 +27,7 @@ define([
|
||||
'./dropdown/infiniteScroll',
|
||||
'./dropdown/attachBody',
|
||||
'./dropdown/minimumResultsForSearch',
|
||||
'./dropdown/selectOnClose',
|
||||
|
||||
'./i18n/en'
|
||||
], function ($, ResultsList,
|
||||
@ -40,7 +41,7 @@ define([
|
||||
MinimumInputLength, MaximumInputLength,
|
||||
|
||||
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
|
||||
AttachBody, MinimumResultsForSearch,
|
||||
AttachBody, MinimumResultsForSearch, SelectOnClose,
|
||||
|
||||
EnglishTranslation) {
|
||||
function Defaults () {
|
||||
@ -119,6 +120,13 @@ define([
|
||||
);
|
||||
}
|
||||
|
||||
if (options.selectOnClose) {
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
SelectOnClose
|
||||
);
|
||||
}
|
||||
|
||||
options.dropdownAdapter = Utils.Decorate(
|
||||
options.dropdownAdapter,
|
||||
AttachBody
|
||||
@ -252,12 +260,13 @@ define([
|
||||
this.defaults = {
|
||||
language: EnglishTranslation,
|
||||
matcher: matcher,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
minimumInputLength: 0,
|
||||
maximumInputLength: 0,
|
||||
minimumResultsForSearch: 0,
|
||||
selectOnClose: false,
|
||||
sorter: function (data) {
|
||||
return data;
|
||||
},
|
||||
templateResult: function (result) {
|
||||
return result.text;
|
||||
},
|
||||
|
27
src/js/select2/dropdown/selectOnClose.js
vendored
Normal file
27
src/js/select2/dropdown/selectOnClose.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
define([
|
||||
|
||||
], function () {
|
||||
function SelectOnClose () { }
|
||||
|
||||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||||
var self = this;
|
||||
|
||||
decorated.call(this, container, $container);
|
||||
|
||||
container.on('close', function () {
|
||||
self._handleSelectOnClose();
|
||||
});
|
||||
};
|
||||
|
||||
SelectOnClose.prototype._handleSelectOnClose = function () {
|
||||
var $highlightedResults = this.getHighlightedResults();
|
||||
|
||||
if ($highlightedResults.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$highlightedResults.trigger('mouseup');
|
||||
};
|
||||
|
||||
return SelectOnClose;
|
||||
});
|
135
tests/dropdown/selectOnClose-tests.js
Normal file
135
tests/dropdown/selectOnClose-tests.js
Normal file
@ -0,0 +1,135 @@
|
||||
module('Dropdown - selectOnClose');
|
||||
|
||||
var Utils = require('select2/utils');
|
||||
var Options = require('select2/options');
|
||||
|
||||
var SelectData = require('select2/data/select');
|
||||
|
||||
var Results = require('select2/results');
|
||||
var SelectOnClose = require('select2/dropdown/selectOnClose');
|
||||
|
||||
var ModifiedResults = Utils.Decorate(Results, SelectOnClose);
|
||||
|
||||
var options = new Options({
|
||||
selectOnClose: true
|
||||
});
|
||||
|
||||
test('will not trigger if no results were given', function (assert) {
|
||||
expect(0);
|
||||
|
||||
var $element = $('<select></select>');
|
||||
var select = new ModifiedResults($element, options, new SelectData($element));
|
||||
|
||||
var $dropdown = select.render();
|
||||
|
||||
var container = new MockContainer();
|
||||
select.bind(container, $('<div></div>'));
|
||||
|
||||
select.on('select', function () {
|
||||
assert.ok(false, 'The select event should not have been triggered');
|
||||
});
|
||||
|
||||
container.trigger('close');
|
||||
});
|
||||
|
||||
test('will not trigger if the results list is empty', function (assert) {
|
||||
expect(1);
|
||||
|
||||
var $element = $('<select></select>');
|
||||
var select = new ModifiedResults($element, options, new SelectData($element));
|
||||
|
||||
var $dropdown = select.render();
|
||||
|
||||
var container = new MockContainer();
|
||||
select.bind(container, $('<div></div>'));
|
||||
|
||||
select.on('select', function () {
|
||||
assert.ok(false, 'The select event should not have been triggered');
|
||||
});
|
||||
|
||||
select.append({
|
||||
results: []
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
$dropdown.find('li').length,
|
||||
0,
|
||||
'There should not be any results in the dropdown'
|
||||
);
|
||||
|
||||
container.trigger('close');
|
||||
});
|
||||
|
||||
test('will not trigger if no results here highlighted', function (assert) {
|
||||
expect(2);
|
||||
|
||||
var $element = $('<select></select>');
|
||||
var select = new ModifiedResults($element, options, new SelectData($element));
|
||||
|
||||
var $dropdown = select.render();
|
||||
|
||||
var container = new MockContainer();
|
||||
select.bind(container, $('<div></div>'));
|
||||
|
||||
select.on('select', function () {
|
||||
assert.ok(false, 'The select event should not have been triggered');
|
||||
});
|
||||
|
||||
select.append({
|
||||
results: [
|
||||
{
|
||||
id: '1',
|
||||
text: 'Test'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
$dropdown.find('li').length,
|
||||
1,
|
||||
'There should be one result in the dropdown'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
$.trim($dropdown.find('li').text()),
|
||||
'Test',
|
||||
'The result should be the same as the one we appended'
|
||||
);
|
||||
|
||||
container.trigger('close');
|
||||
});
|
||||
|
||||
test('will trigger if there is a highlighted result', function (assert) {
|
||||
expect(2);
|
||||
|
||||
var $element = $('<select></select>');
|
||||
var select = new ModifiedResults($element, options, new SelectData($element));
|
||||
|
||||
var $dropdown = select.render();
|
||||
|
||||
var container = new MockContainer();
|
||||
select.bind(container, $('<div></div>'));
|
||||
|
||||
select.on('select', function () {
|
||||
assert.ok(true, 'The select event should have been triggered');
|
||||
});
|
||||
|
||||
select.append({
|
||||
results: [
|
||||
{
|
||||
id: '1',
|
||||
text: 'Test'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
$dropdown.find('li').length,
|
||||
1,
|
||||
'There should be one result in the dropdown'
|
||||
);
|
||||
|
||||
$dropdown.find('li').addClass('select2-results__option--highlighted');
|
||||
|
||||
container.trigger('close');
|
||||
});
|
20
tests/dropdown/selectOnClose.html
Normal file
20
tests/dropdown/selectOnClose.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../vendor/qunit-1.14.0.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../dist/css/select2.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script src="../vendor/qunit-1.14.0.js" type="text/javascript"></script>
|
||||
<script src="../../vendor/almond-0.2.9.js" type="text/javascript"></script>
|
||||
<script src="../../vendor/jquery-2.1.0.js" type="text/javascript"></script>
|
||||
<script src="../../dist/js/select2.amd.js" type="text/javascript"></script>
|
||||
|
||||
<script src="../mock.js" type="text/javascript"></script>
|
||||
|
||||
<script src="selectOnClose-tests.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
11
tests/mock.js
Normal file
11
tests/mock.js
Normal file
@ -0,0 +1,11 @@
|
||||
var Utils = require('select2/utils');
|
||||
|
||||
function MockContainer () {
|
||||
MockContainer.__super__.constructor.call(this);
|
||||
}
|
||||
|
||||
Utils.Extend(MockContainer, Utils.Observable);
|
||||
|
||||
MockContainer.prototype.isOpen = function () {
|
||||
return this.isOpen;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user