From 584d3b48a2d426a3fba1625eecd7d7c08c6ee200 Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Sun, 11 Jan 2015 21:47:17 -0500 Subject: [PATCH] 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. --- dist/js/select2.amd.full.js | 45 +++++++- dist/js/select2.amd.js | 45 +++++++- dist/js/select2.full.js | 45 +++++++- dist/js/select2.full.min.js | 2 +- dist/js/select2.js | 45 +++++++- dist/js/select2.min.js | 2 +- src/js/select2/defaults.js | 17 ++- src/js/select2/dropdown/selectOnClose.js | 27 +++++ tests/dropdown/selectOnClose-tests.js | 135 +++++++++++++++++++++++ tests/dropdown/selectOnClose.html | 20 ++++ tests/mock.js | 11 ++ 11 files changed, 372 insertions(+), 22 deletions(-) create mode 100644 src/js/select2/dropdown/selectOnClose.js create mode 100644 tests/dropdown/selectOnClose-tests.js create mode 100644 tests/dropdown/selectOnClose.html create mode 100644 tests/mock.js diff --git a/dist/js/select2.amd.full.js b/dist/js/select2.amd.full.js index a99c9570..90845db8 100644 --- a/dist/js/select2.amd.full.js +++ b/dist/js/select2.amd.full.js @@ -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; }, diff --git a/dist/js/select2.amd.js b/dist/js/select2.amd.js index 5e590645..8d39d5c3 100644 --- a/dist/js/select2.amd.js +++ b/dist/js/select2.amd.js @@ -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; }, diff --git a/dist/js/select2.full.js b/dist/js/select2.full.js index 3a63a793..b83eb89c 100644 --- a/dist/js/select2.full.js +++ b/dist/js/select2.full.js @@ -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; }, diff --git a/dist/js/select2.full.min.js b/dist/js/select2.full.min.js index 12be4eb8..32a81fa2 100644 --- a/dist/js/select2.full.min.js +++ b/dist/js/select2.full.min.js @@ -1,5 +1,5 @@ window.$=window.$||{},function(){$&&$.fn&&$.fn.select2&&$.fn.select2.amd&&(c=$.fn.select2.amd.define,b=$.fn.select2.amd.require);var a,b,c;!function(d){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(n=n.slice(0,n.length-1),a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.concat(a),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,b){return function(){return n.apply(d,v.call(arguments,0).concat([a,b]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var b=r[a];delete r[a],t[a]=!0,m.apply(d,b)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,b,c,f){var h,k,l,m,n,s,u=[],v=typeof c;if(f=f||a,"undefined"===v||"function"===v){for(b=!b.length&&c.length?["require","exports","module"]:b,n=0;n0&&b-1 in a}function e(a,b,c){if(bb.isFunction(b))return bb.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return bb.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(ib.test(b))return bb.filter(b,a,c);b=bb.filter(b,a)}return bb.grep(a,function(a){return V.call(b,a)>=0!==c})}function f(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function g(a){var b=pb[a]={};return bb.each(a.match(ob)||[],function(a,c){b[c]=!0}),b}function h(){_.removeEventListener("DOMContentLoaded",h,!1),a.removeEventListener("load",h,!1),bb.ready()}function i(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=bb.expando+Math.random()}function j(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(vb,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:ub.test(c)?bb.parseJSON(c):c}catch(e){}tb.set(a,b,c)}else c=void 0;return c}function k(){return!0}function l(){return!1}function m(){try{return _.activeElement}catch(a){}}function n(a,b){return bb.nodeName(a,"table")&&bb.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function o(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function p(a){var b=Lb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function q(a,b){for(var c=0,d=a.length;d>c;c++)sb.set(a[c],"globalEval",!b||sb.get(b[c],"globalEval"))}function r(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(sb.hasData(a)&&(f=sb.access(a),g=sb.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)bb.event.add(b,e,j[e][c])}tb.hasData(a)&&(h=tb.access(a),i=bb.extend({},h),tb.set(b,i))}}function s(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&bb.nodeName(a,b)?bb.merge([a],c):c}function t(a,b){var c=b.nodeName.toLowerCase();"input"===c&&zb.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function u(b,c){var d=bb(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:bb.css(d[0],"display");return d.detach(),e}function v(a){var b=_,c=Pb[a];return c||(c=u(a,b),"none"!==c&&c||(Ob=(Ob||bb("