select2-rails 3.3.2 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/select2.js +548 -280
- data/app/assets/stylesheets/select2.css.scss +60 -24
- data/lib/select2-rails/version.rb +1 -1
- metadata +2 -3
- data/app/assets/images/spinner.gif +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
Copyright 2012 Igor Vaynberg
|
3
3
|
|
4
|
-
Version: 3.
|
4
|
+
Version: 3.4.0 Timestamp: Tue May 14 08:27:33 PDT 2013
|
5
5
|
|
6
6
|
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
|
7
7
|
General Public License version 2 (the "GPL License"). You may choose either license to govern your
|
@@ -19,23 +19,23 @@ CONDITIONS OF ANY KIND, either express or implied. See the Apache License and th
|
|
19
19
|
the specific language governing permissions and limitations under the Apache License and the GPL License.
|
20
20
|
*/
|
21
21
|
(function ($) {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
22
|
+
if(typeof $.fn.each2 == "undefined"){
|
23
|
+
$.fn.extend({
|
24
|
+
/*
|
25
|
+
* 4-10 times faster .each replacement
|
26
|
+
* use it carefully, as it overrides jQuery context of element on each iteration
|
27
|
+
*/
|
28
|
+
each2 : function (c) {
|
29
|
+
var j = $([0]), i = -1, l = this.length;
|
30
|
+
while (
|
31
|
+
++i < l
|
32
|
+
&& (j.context = j[0] = this[i])
|
33
|
+
&& c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
|
34
|
+
);
|
35
|
+
return this;
|
36
|
+
}
|
37
|
+
});
|
38
|
+
}
|
39
39
|
})(jQuery);
|
40
40
|
|
41
41
|
(function ($, undefined) {
|
@@ -47,7 +47,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
47
47
|
}
|
48
48
|
|
49
49
|
var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
|
50
|
-
lastMousePosition, $document
|
50
|
+
lastMousePosition, $document, scrollBarDimensions,
|
51
51
|
|
52
52
|
KEY = {
|
53
53
|
TAB: 9,
|
@@ -95,7 +95,8 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
95
95
|
k = k.which ? k.which : k;
|
96
96
|
return k >= 112 && k <= 123;
|
97
97
|
}
|
98
|
-
}
|
98
|
+
},
|
99
|
+
MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>";
|
99
100
|
|
100
101
|
$document = $(document);
|
101
102
|
|
@@ -109,6 +110,19 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
109
110
|
return -1;
|
110
111
|
}
|
111
112
|
|
113
|
+
function measureScrollbar () {
|
114
|
+
var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
|
115
|
+
$template.appendTo('body');
|
116
|
+
|
117
|
+
var dim = {
|
118
|
+
width: $template.width() - $template[0].clientWidth,
|
119
|
+
height: $template.height() - $template[0].clientHeight
|
120
|
+
};
|
121
|
+
$template.remove();
|
122
|
+
|
123
|
+
return dim;
|
124
|
+
}
|
125
|
+
|
112
126
|
/**
|
113
127
|
* Compares equality of a and b
|
114
128
|
* @param a
|
@@ -143,12 +157,12 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
143
157
|
|
144
158
|
function installKeyUpChangeEvent(element) {
|
145
159
|
var key="keyup-change-value";
|
146
|
-
element.
|
160
|
+
element.on("keydown", function () {
|
147
161
|
if ($.data(element, key) === undefined) {
|
148
162
|
$.data(element, key, element.val());
|
149
163
|
}
|
150
164
|
});
|
151
|
-
element.
|
165
|
+
element.on("keyup", function () {
|
152
166
|
var val= $.data(element, key);
|
153
167
|
if (val !== undefined && element.val() !== val) {
|
154
168
|
$.removeData(element, key);
|
@@ -157,7 +171,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
157
171
|
});
|
158
172
|
}
|
159
173
|
|
160
|
-
$document.
|
174
|
+
$document.on("mousemove", function (e) {
|
161
175
|
lastMousePosition = {x: e.pageX, y: e.pageY};
|
162
176
|
});
|
163
177
|
|
@@ -168,7 +182,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
168
182
|
* the elements under the pointer are scrolled.
|
169
183
|
*/
|
170
184
|
function installFilteredMouseMove(element) {
|
171
|
-
|
185
|
+
element.on("mousemove", function (e) {
|
172
186
|
var lastpos = lastMousePosition;
|
173
187
|
if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
|
174
188
|
$(e.target).trigger("mousemove-filtered", e);
|
@@ -213,7 +227,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
213
227
|
|
214
228
|
function installDebouncedScroll(threshold, element) {
|
215
229
|
var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);});
|
216
|
-
element.
|
230
|
+
element.on("scroll", function (e) {
|
217
231
|
if (indexOf(e.target, element.get()) >= 0) notify(e);
|
218
232
|
});
|
219
233
|
}
|
@@ -248,6 +262,23 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
248
262
|
}, 0);
|
249
263
|
}
|
250
264
|
|
265
|
+
function getCursorInfo(el) {
|
266
|
+
el = $(el)[0];
|
267
|
+
var offset = 0;
|
268
|
+
var length = 0;
|
269
|
+
if ('selectionStart' in el) {
|
270
|
+
offset = el.selectionStart;
|
271
|
+
length = el.selectionEnd - offset;
|
272
|
+
} else if ('selection' in document) {
|
273
|
+
el.focus();
|
274
|
+
var sel = document.selection.createRange();
|
275
|
+
length = document.selection.createRange().text.length;
|
276
|
+
sel.moveStart('character', -el.value.length);
|
277
|
+
offset = sel.text.length - length;
|
278
|
+
}
|
279
|
+
return { offset: offset, length: length };
|
280
|
+
}
|
281
|
+
|
251
282
|
function killEvent(event) {
|
252
283
|
event.preventDefault();
|
253
284
|
event.stopPropagation();
|
@@ -259,22 +290,22 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
259
290
|
|
260
291
|
function measureTextWidth(e) {
|
261
292
|
if (!sizer){
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
293
|
+
var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
|
294
|
+
sizer = $(document.createElement("div")).css({
|
295
|
+
position: "absolute",
|
296
|
+
left: "-10000px",
|
297
|
+
top: "-10000px",
|
298
|
+
display: "none",
|
299
|
+
fontSize: style.fontSize,
|
300
|
+
fontFamily: style.fontFamily,
|
301
|
+
fontStyle: style.fontStyle,
|
302
|
+
fontWeight: style.fontWeight,
|
303
|
+
letterSpacing: style.letterSpacing,
|
304
|
+
textTransform: style.textTransform,
|
305
|
+
whiteSpace: "nowrap"
|
306
|
+
});
|
276
307
|
sizer.attr("class","select2-sizer");
|
277
|
-
|
308
|
+
$("body").append(sizer);
|
278
309
|
}
|
279
310
|
sizer.text(e.val());
|
280
311
|
return sizer.width();
|
@@ -328,11 +359,11 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
328
359
|
* Produces an ajax-based query function
|
329
360
|
*
|
330
361
|
* @param options object containing configuration paramters
|
362
|
+
* @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax
|
331
363
|
* @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax
|
332
364
|
* @param options.url url for the data
|
333
365
|
* @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.
|
334
366
|
* @param options.dataType request data type: ajax, jsonp, other datatatypes supported by jQuery's $.ajax function or the transport function if specified
|
335
|
-
* @param options.traditional a boolean flag that should be true if you wish to use the traditional style of param serialization for the ajax request
|
336
367
|
* @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often
|
337
368
|
* @param options.results a function(remoteData, pageNumber) that converts data returned form the remote request to the format expected by Select2.
|
338
369
|
* The expected format is an object containing the following keys:
|
@@ -355,9 +386,15 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
355
386
|
var requestNumber = requestSequence, // this request's sequence number
|
356
387
|
data = options.data, // ajax data function
|
357
388
|
url = ajaxUrl, // ajax url string or function
|
358
|
-
transport = options.transport || $.
|
359
|
-
|
360
|
-
|
389
|
+
transport = options.transport || $.fn.select2.ajaxDefaults.transport,
|
390
|
+
// deprecated - to be removed in 4.0 - use params instead
|
391
|
+
deprecated = {
|
392
|
+
type: options.type || 'GET', // set type of request (GET or POST)
|
393
|
+
cache: options.cache || false,
|
394
|
+
jsonpCallback: options.jsonpCallback||undefined,
|
395
|
+
dataType: options.dataType||"json"
|
396
|
+
},
|
397
|
+
params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
|
361
398
|
|
362
399
|
data = data ? data.call(self, query.term, query.page, query.context) : null;
|
363
400
|
url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
|
@@ -376,8 +413,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
376
413
|
url: url,
|
377
414
|
dataType: options.dataType,
|
378
415
|
data: data,
|
379
|
-
type: type,
|
380
|
-
cache: false,
|
381
416
|
success: function (data) {
|
382
417
|
if (requestNumber < requestSequence) {
|
383
418
|
return;
|
@@ -412,12 +447,12 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
412
447
|
tmp,
|
413
448
|
text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search
|
414
449
|
|
415
|
-
|
450
|
+
if ($.isArray(data)) {
|
416
451
|
tmp = data;
|
417
452
|
data = { results: tmp };
|
418
453
|
}
|
419
454
|
|
420
|
-
|
455
|
+
if ($.isFunction(data) === false) {
|
421
456
|
tmp = data;
|
422
457
|
data = function() { return tmp; };
|
423
458
|
}
|
@@ -427,7 +462,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
427
462
|
text = dataItem.text;
|
428
463
|
// if text is not a function we assume it to be a key name
|
429
464
|
if (!$.isFunction(text)) {
|
430
|
-
dataText =
|
465
|
+
dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available
|
431
466
|
text = function (item) { return item[dataText]; };
|
432
467
|
}
|
433
468
|
}
|
@@ -590,7 +625,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
590
625
|
|
591
626
|
// abstract
|
592
627
|
init: function (opts) {
|
593
|
-
var results, search, resultsSelector = ".select2-results",
|
628
|
+
var results, search, resultsSelector = ".select2-results", disabled, readonly;
|
594
629
|
|
595
630
|
// prepare options
|
596
631
|
this.opts = opts = this.prepareOpts(opts);
|
@@ -603,7 +638,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
603
638
|
this.destroy();
|
604
639
|
}
|
605
640
|
|
606
|
-
this.enabled=true;
|
607
641
|
this.container = this.createContainer();
|
608
642
|
|
609
643
|
this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
|
@@ -618,14 +652,12 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
618
652
|
this.container.css(evaluate(opts.containerCss));
|
619
653
|
this.container.addClass(evaluate(opts.containerCssClass));
|
620
654
|
|
621
|
-
this.elementTabIndex = this.opts.element.attr("
|
655
|
+
this.elementTabIndex = this.opts.element.attr("tabindex");
|
622
656
|
|
623
657
|
// swap container for the element
|
624
658
|
this.opts.element
|
625
659
|
.data("select2", this)
|
626
|
-
.
|
627
|
-
.bind("focus.select2", function() { $(this).select2("focus"); })
|
628
|
-
.attr("tabIndex", "-1")
|
660
|
+
.attr("tabindex", "-1")
|
629
661
|
.before(this.container);
|
630
662
|
this.container.data("select2", this);
|
631
663
|
|
@@ -636,8 +668,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
636
668
|
this.results = results = this.container.find(resultsSelector);
|
637
669
|
this.search = search = this.container.find("input.select2-input");
|
638
670
|
|
639
|
-
search.attr("tabIndex", this.elementTabIndex);
|
640
|
-
|
641
671
|
this.resultsPage = 0;
|
642
672
|
this.context = null;
|
643
673
|
|
@@ -645,10 +675,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
645
675
|
this.initContainer();
|
646
676
|
|
647
677
|
installFilteredMouseMove(this.results);
|
648
|
-
this.dropdown.
|
678
|
+
this.dropdown.on("mousemove-filtered touchstart touchmove touchend", resultsSelector, this.bind(this.highlightUnderEvent));
|
649
679
|
|
650
680
|
installDebouncedScroll(80, this.results);
|
651
|
-
this.dropdown.
|
681
|
+
this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
|
682
|
+
|
683
|
+
// do not propagate change event from the search field out of the component
|
684
|
+
$(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();});
|
685
|
+
$(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();});
|
652
686
|
|
653
687
|
// if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
|
654
688
|
if ($.fn.mousewheel) {
|
@@ -665,11 +699,11 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
665
699
|
}
|
666
700
|
|
667
701
|
installKeyUpChangeEvent(search);
|
668
|
-
search.
|
669
|
-
search.
|
670
|
-
search.
|
702
|
+
search.on("keyup-change input paste", this.bind(this.updateResults));
|
703
|
+
search.on("focus", function () { search.addClass("select2-focused"); });
|
704
|
+
search.on("blur", function () { search.removeClass("select2-focused");});
|
671
705
|
|
672
|
-
this.dropdown.
|
706
|
+
this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) {
|
673
707
|
if ($(e.target).closest(".select2-result-selectable").length > 0) {
|
674
708
|
this.highlightUnderEvent(e);
|
675
709
|
this.selectHighlighted(e);
|
@@ -679,7 +713,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
679
713
|
// trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
|
680
714
|
// for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
|
681
715
|
// dom it will trigger the popup close, which is not what we want
|
682
|
-
this.dropdown.
|
716
|
+
this.dropdown.on("click mouseup mousedown", function (e) { e.stopPropagation(); });
|
683
717
|
|
684
718
|
if ($.isFunction(this.opts.initSelection)) {
|
685
719
|
// initialize selection based on the current value of the source element
|
@@ -690,7 +724,24 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
690
724
|
this.monitorSource();
|
691
725
|
}
|
692
726
|
|
693
|
-
if (opts.
|
727
|
+
if (opts.maximumInputLength !== null) {
|
728
|
+
this.search.attr("maxlength", opts.maximumInputLength);
|
729
|
+
}
|
730
|
+
|
731
|
+
var disabled = opts.element.prop("disabled");
|
732
|
+
if (disabled === undefined) disabled = false;
|
733
|
+
this.enable(!disabled);
|
734
|
+
|
735
|
+
var readonly = opts.element.prop("readonly");
|
736
|
+
if (readonly === undefined) readonly = false;
|
737
|
+
this.readonly(readonly);
|
738
|
+
|
739
|
+
// Calculate size of scrollbar
|
740
|
+
scrollBarDimensions = scrollBarDimensions || measureScrollbar();
|
741
|
+
|
742
|
+
this.autofocus = opts.element.prop("autofocus")
|
743
|
+
opts.element.prop("autofocus", false);
|
744
|
+
if (this.autofocus) this.focus();
|
694
745
|
},
|
695
746
|
|
696
747
|
// abstract
|
@@ -706,15 +757,37 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
706
757
|
select2.opts.element
|
707
758
|
.removeClass("select2-offscreen")
|
708
759
|
.removeData("select2")
|
709
|
-
.
|
710
|
-
.attr({"
|
760
|
+
.off(".select2")
|
761
|
+
.attr({"tabindex": this.elementTabIndex})
|
762
|
+
.prop("autofocus", this.autofocus||false)
|
711
763
|
.show();
|
712
764
|
}
|
713
765
|
},
|
714
766
|
|
767
|
+
// abstract
|
768
|
+
optionToData: function(element) {
|
769
|
+
if (element.is("option")) {
|
770
|
+
return {
|
771
|
+
id:element.prop("value"),
|
772
|
+
text:element.text(),
|
773
|
+
element: element.get(),
|
774
|
+
css: element.attr("class"),
|
775
|
+
disabled: element.prop("disabled"),
|
776
|
+
locked: equal(element.attr("locked"), "locked")
|
777
|
+
};
|
778
|
+
} else if (element.is("optgroup")) {
|
779
|
+
return {
|
780
|
+
text:element.attr("label"),
|
781
|
+
children:[],
|
782
|
+
element: element.get(),
|
783
|
+
css: element.attr("class")
|
784
|
+
};
|
785
|
+
}
|
786
|
+
},
|
787
|
+
|
715
788
|
// abstract
|
716
789
|
prepareOpts: function (opts) {
|
717
|
-
var element, select, idKey, ajaxUrl;
|
790
|
+
var element, select, idKey, ajaxUrl, self = this;
|
718
791
|
|
719
792
|
element = opts.element;
|
720
793
|
|
@@ -733,7 +806,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
733
806
|
|
734
807
|
opts = $.extend({}, {
|
735
808
|
populateResults: function(container, results, query) {
|
736
|
-
var populate, data, result, children, id=this.opts.id
|
809
|
+
var populate, data, result, children, id=this.opts.id;
|
737
810
|
|
738
811
|
populate=function(results, container, depth) {
|
739
812
|
|
@@ -807,10 +880,10 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
807
880
|
var group;
|
808
881
|
if (element.is("option")) {
|
809
882
|
if (query.matcher(term, element.text(), element)) {
|
810
|
-
collection.push(
|
883
|
+
collection.push(self.optionToData(element));
|
811
884
|
}
|
812
885
|
} else if (element.is("optgroup")) {
|
813
|
-
group=
|
886
|
+
group=self.optionToData(element);
|
814
887
|
element.children().each2(function(i, elm) { process(elm, group.children); });
|
815
888
|
if (group.children.length>0) {
|
816
889
|
collection.push(group);
|
@@ -881,7 +954,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
881
954
|
monitorSource: function () {
|
882
955
|
var el = this.opts.element, sync;
|
883
956
|
|
884
|
-
el.
|
957
|
+
el.on("change.select2", this.bind(function (e) {
|
885
958
|
if (this.opts.element.data("select2-change-triggered") !== true) {
|
886
959
|
this.initSelection();
|
887
960
|
}
|
@@ -893,19 +966,13 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
893
966
|
|
894
967
|
// sync enabled state
|
895
968
|
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
enabled = enabled && !readonly;
|
900
|
-
|
901
|
-
if (this.enabled !== enabled) {
|
902
|
-
if (enabled) {
|
903
|
-
this.enable();
|
904
|
-
} else {
|
905
|
-
this.disable();
|
906
|
-
}
|
907
|
-
}
|
969
|
+
var disabled = el.prop("disabled");
|
970
|
+
if (disabled === undefined) disabled = false;
|
971
|
+
this.enable(!disabled);
|
908
972
|
|
973
|
+
var readonly = el.prop("readonly");
|
974
|
+
if (readonly === undefined) readonly = false;
|
975
|
+
this.readonly(readonly);
|
909
976
|
|
910
977
|
syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
|
911
978
|
this.container.addClass(evaluate(this.opts.containerCssClass));
|
@@ -916,17 +983,31 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
916
983
|
});
|
917
984
|
|
918
985
|
// mozilla and IE
|
919
|
-
el.
|
986
|
+
el.on("propertychange.select2 DOMAttrModified.select2", sync);
|
987
|
+
|
988
|
+
|
989
|
+
// hold onto a reference of the callback to work around a chromium bug
|
990
|
+
if (this.mutationCallback === undefined) {
|
991
|
+
this.mutationCallback = function (mutations) {
|
992
|
+
mutations.forEach(sync);
|
993
|
+
}
|
994
|
+
}
|
995
|
+
|
920
996
|
// safari and chrome
|
921
997
|
if (typeof WebKitMutationObserver !== "undefined") {
|
922
998
|
if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
|
923
|
-
this.propertyObserver = new WebKitMutationObserver(
|
924
|
-
mutations.forEach(sync);
|
925
|
-
});
|
999
|
+
this.propertyObserver = new WebKitMutationObserver(this.mutationCallback);
|
926
1000
|
this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false });
|
927
1001
|
}
|
928
1002
|
},
|
929
1003
|
|
1004
|
+
// abstract
|
1005
|
+
triggerSelect: function(data) {
|
1006
|
+
var evt = $.Event("select2-selecting", { val: this.id(data), object: data });
|
1007
|
+
this.opts.element.trigger(evt);
|
1008
|
+
return !evt.isDefaultPrevented();
|
1009
|
+
},
|
1010
|
+
|
930
1011
|
/**
|
931
1012
|
* Triggers the change event on the source element
|
932
1013
|
*/
|
@@ -950,24 +1031,46 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
950
1031
|
this.opts.element.blur();
|
951
1032
|
},
|
952
1033
|
|
1034
|
+
//abstract
|
1035
|
+
isInterfaceEnabled: function()
|
1036
|
+
{
|
1037
|
+
return this.enabledInterface === true;
|
1038
|
+
},
|
1039
|
+
|
953
1040
|
// abstract
|
954
|
-
|
955
|
-
|
1041
|
+
enableInterface: function() {
|
1042
|
+
var enabled = this._enabled && !this._readonly,
|
1043
|
+
disabled = !enabled;
|
1044
|
+
|
1045
|
+
if (enabled === this.enabledInterface) return false;
|
956
1046
|
|
957
|
-
this.
|
958
|
-
this.
|
959
|
-
this.
|
1047
|
+
this.container.toggleClass("select2-container-disabled", disabled);
|
1048
|
+
this.close();
|
1049
|
+
this.enabledInterface = enabled;
|
1050
|
+
|
1051
|
+
return true;
|
960
1052
|
},
|
961
1053
|
|
962
1054
|
// abstract
|
963
|
-
|
964
|
-
if (
|
1055
|
+
enable: function(enabled) {
|
1056
|
+
if (enabled === undefined) enabled = true;
|
1057
|
+
if (this._enabled === enabled) return false;
|
1058
|
+
this._enabled = enabled;
|
965
1059
|
|
966
|
-
this.
|
1060
|
+
this.opts.element.prop("disabled", !enabled);
|
1061
|
+
this.enableInterface();
|
1062
|
+
return true;
|
1063
|
+
},
|
967
1064
|
|
968
|
-
|
969
|
-
|
970
|
-
|
1065
|
+
// abstract
|
1066
|
+
readonly: function(enabled) {
|
1067
|
+
if (enabled === undefined) enabled = false;
|
1068
|
+
if (this._readonly === enabled) return false;
|
1069
|
+
this._readonly = enabled;
|
1070
|
+
|
1071
|
+
this.opts.element.prop("readonly", enabled);
|
1072
|
+
this.enableInterface();
|
1073
|
+
return true;
|
971
1074
|
},
|
972
1075
|
|
973
1076
|
// abstract
|
@@ -977,22 +1080,37 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
977
1080
|
|
978
1081
|
// abstract
|
979
1082
|
positionDropdown: function() {
|
980
|
-
var
|
1083
|
+
var $dropdown = this.dropdown,
|
1084
|
+
offset = this.container.offset(),
|
981
1085
|
height = this.container.outerHeight(false),
|
982
1086
|
width = this.container.outerWidth(false),
|
983
|
-
dropHeight =
|
984
|
-
|
1087
|
+
dropHeight = $dropdown.outerHeight(false),
|
1088
|
+
viewPortRight = $(window).scrollLeft() + $(window).width(),
|
985
1089
|
viewportBottom = $(window).scrollTop() + $(window).height(),
|
986
1090
|
dropTop = offset.top + height,
|
987
1091
|
dropLeft = offset.left,
|
988
1092
|
enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
|
989
1093
|
enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),
|
990
|
-
|
991
|
-
|
992
|
-
aboveNow =
|
1094
|
+
dropWidth = $dropdown.outerWidth(false),
|
1095
|
+
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
|
1096
|
+
aboveNow = $dropdown.hasClass("select2-drop-above"),
|
993
1097
|
bodyOffset,
|
994
1098
|
above,
|
995
|
-
css
|
1099
|
+
css,
|
1100
|
+
resultsListNode;
|
1101
|
+
|
1102
|
+
if (this.opts.dropdownAutoWidth) {
|
1103
|
+
resultsListNode = $('.select2-results', $dropdown)[0];
|
1104
|
+
$dropdown.addClass('select2-drop-auto-width');
|
1105
|
+
$dropdown.css('width', '');
|
1106
|
+
// Add scrollbar width to dropdown if vertical scrollbar is present
|
1107
|
+
dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
|
1108
|
+
dropWidth > width ? width = dropWidth : dropWidth = width;
|
1109
|
+
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
|
1110
|
+
}
|
1111
|
+
else {
|
1112
|
+
this.container.removeClass('select2-drop-auto-width');
|
1113
|
+
}
|
996
1114
|
|
997
1115
|
//console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
|
998
1116
|
//console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove);
|
@@ -1022,11 +1140,11 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1022
1140
|
if (above) {
|
1023
1141
|
dropTop = offset.top - dropHeight;
|
1024
1142
|
this.container.addClass("select2-drop-above");
|
1025
|
-
|
1143
|
+
$dropdown.addClass("select2-drop-above");
|
1026
1144
|
}
|
1027
1145
|
else {
|
1028
1146
|
this.container.removeClass("select2-drop-above");
|
1029
|
-
|
1147
|
+
$dropdown.removeClass("select2-drop-above");
|
1030
1148
|
}
|
1031
1149
|
|
1032
1150
|
css = $.extend({
|
@@ -1035,7 +1153,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1035
1153
|
width: width
|
1036
1154
|
}, evaluate(this.opts.dropdownCss));
|
1037
1155
|
|
1038
|
-
|
1156
|
+
$dropdown.css(css);
|
1039
1157
|
},
|
1040
1158
|
|
1041
1159
|
// abstract
|
@@ -1044,7 +1162,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1044
1162
|
|
1045
1163
|
if (this.opened()) return false;
|
1046
1164
|
|
1047
|
-
|
1165
|
+
if (this._enabled === false || this._readonly === true) return false;
|
1166
|
+
|
1167
|
+
event = $.Event("select2-opening");
|
1048
1168
|
this.opts.element.trigger(event);
|
1049
1169
|
return !event.isDefaultPrevented();
|
1050
1170
|
},
|
@@ -1067,7 +1187,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1067
1187
|
|
1068
1188
|
if (!this.shouldOpen()) return false;
|
1069
1189
|
|
1070
|
-
|
1190
|
+
this.opening();
|
1071
1191
|
|
1072
1192
|
return true;
|
1073
1193
|
},
|
@@ -1083,17 +1203,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1083
1203
|
orient = "orientationchange."+cid,
|
1084
1204
|
mask;
|
1085
1205
|
|
1086
|
-
this.clearDropdownAlignmentPreference();
|
1087
|
-
|
1088
1206
|
this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
|
1089
1207
|
|
1208
|
+
this.clearDropdownAlignmentPreference();
|
1090
1209
|
|
1091
1210
|
if(this.dropdown[0] !== this.body().children().last()[0]) {
|
1092
1211
|
this.dropdown.detach().appendTo(this.body());
|
1093
1212
|
}
|
1094
1213
|
|
1095
|
-
this.updateResults(true);
|
1096
|
-
|
1097
1214
|
// create the dropdown mask if doesnt already exist
|
1098
1215
|
mask = $("#select2-drop-mask");
|
1099
1216
|
if (mask.length == 0) {
|
@@ -1101,7 +1218,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1101
1218
|
mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
|
1102
1219
|
mask.hide();
|
1103
1220
|
mask.appendTo(this.body());
|
1104
|
-
mask.
|
1221
|
+
mask.on("mousedown touchstart", function (e) {
|
1105
1222
|
var dropdown = $("#select2-drop"), self;
|
1106
1223
|
if (dropdown.length > 0) {
|
1107
1224
|
self=dropdown.data("select2");
|
@@ -1109,6 +1226,8 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1109
1226
|
self.selectHighlighted({noFocus: true});
|
1110
1227
|
}
|
1111
1228
|
self.close();
|
1229
|
+
e.preventDefault();
|
1230
|
+
e.stopPropagation();
|
1112
1231
|
}
|
1113
1232
|
});
|
1114
1233
|
}
|
@@ -1135,14 +1254,12 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1135
1254
|
// the position of the dropdown to be updated as well so it does not come unglued from the container
|
1136
1255
|
var that = this;
|
1137
1256
|
this.container.parents().add(window).each(function () {
|
1138
|
-
$(this).
|
1257
|
+
$(this).on(resize+" "+scroll+" "+orient, function (e) {
|
1139
1258
|
$("#select2-drop-mask").css(_makeMaskCss());
|
1140
1259
|
that.positionDropdown();
|
1141
1260
|
});
|
1142
1261
|
});
|
1143
1262
|
|
1144
|
-
this.focusSearch();
|
1145
|
-
|
1146
1263
|
function _makeMaskCss() {
|
1147
1264
|
return {
|
1148
1265
|
width : Math.max(document.documentElement.scrollWidth, $(window).width()),
|
@@ -1161,7 +1278,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1161
1278
|
orient = "orientationchange."+cid;
|
1162
1279
|
|
1163
1280
|
// unbind event listeners
|
1164
|
-
this.container.parents().add(window).each(function () { $(this).
|
1281
|
+
this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); });
|
1165
1282
|
|
1166
1283
|
this.clearDropdownAlignmentPreference();
|
1167
1284
|
|
@@ -1170,9 +1287,11 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1170
1287
|
this.dropdown.hide();
|
1171
1288
|
this.container.removeClass("select2-dropdown-open");
|
1172
1289
|
this.results.empty();
|
1290
|
+
|
1291
|
+
|
1173
1292
|
this.clearSearch();
|
1174
1293
|
this.search.removeClass("select2-active");
|
1175
|
-
this.opts.element.trigger($.Event("close"));
|
1294
|
+
this.opts.element.trigger($.Event("select2-close"));
|
1176
1295
|
},
|
1177
1296
|
|
1178
1297
|
// abstract
|
@@ -1203,7 +1322,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1203
1322
|
return;
|
1204
1323
|
}
|
1205
1324
|
|
1206
|
-
children = this.findHighlightableChoices();
|
1325
|
+
children = this.findHighlightableChoices().find('.select2-result-label');
|
1207
1326
|
|
1208
1327
|
child = $(children[index]);
|
1209
1328
|
|
@@ -1231,7 +1350,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1231
1350
|
|
1232
1351
|
// abstract
|
1233
1352
|
findHighlightableChoices: function() {
|
1234
|
-
var h=this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)");
|
1235
1353
|
return this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)");
|
1236
1354
|
},
|
1237
1355
|
|
@@ -1272,7 +1390,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1272
1390
|
|
1273
1391
|
data = choice.data("select2-data");
|
1274
1392
|
if (data) {
|
1275
|
-
this.opts.element.trigger({ type: "highlight", val: this.id(data), choice: data });
|
1393
|
+
this.opts.element.trigger({ type: "select2-highlight", val: this.id(data), choice: data });
|
1276
1394
|
}
|
1277
1395
|
},
|
1278
1396
|
|
@@ -1285,7 +1403,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1285
1403
|
highlightUnderEvent: function (event) {
|
1286
1404
|
var el = $(event.target).closest(".select2-result-selectable");
|
1287
1405
|
if (el.length > 0 && !el.is(".select2-highlighted")) {
|
1288
|
-
|
1406
|
+
var choices = this.findHighlightableChoices();
|
1289
1407
|
this.highlight(choices.index(el));
|
1290
1408
|
} else if (el.length == 0) {
|
1291
1409
|
// if we are over an unselectable item remove al highlights
|
@@ -1383,8 +1501,8 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1383
1501
|
if (maxSelSize >=1) {
|
1384
1502
|
data = this.data();
|
1385
1503
|
if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
|
1386
|
-
|
1387
|
-
|
1504
|
+
render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(maxSelSize) + "</li>");
|
1505
|
+
return;
|
1388
1506
|
}
|
1389
1507
|
}
|
1390
1508
|
|
@@ -1394,6 +1512,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1394
1512
|
} else {
|
1395
1513
|
render("");
|
1396
1514
|
}
|
1515
|
+
if (initial) this.showSearch(true);
|
1397
1516
|
return;
|
1398
1517
|
}
|
1399
1518
|
|
@@ -1467,7 +1586,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1467
1586
|
|
1468
1587
|
postRender();
|
1469
1588
|
|
1470
|
-
this.opts.element.trigger({ type: "loaded", data:data });
|
1589
|
+
this.opts.element.trigger({ type: "select2-loaded", data:data });
|
1471
1590
|
})});
|
1472
1591
|
},
|
1473
1592
|
|
@@ -1537,18 +1656,18 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1537
1656
|
attrs = style.split(';');
|
1538
1657
|
for (i = 0, l = attrs.length; i < l; i = i + 1) {
|
1539
1658
|
matches = attrs[i].replace(/\s/g, '')
|
1540
|
-
.match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/);
|
1659
|
+
.match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
|
1541
1660
|
if (matches !== null && matches.length >= 1)
|
1542
1661
|
return matches[1];
|
1543
1662
|
}
|
1544
1663
|
}
|
1545
1664
|
|
1546
|
-
if (
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
if (style.indexOf("%") > 0) return style;
|
1665
|
+
// next check if css('width') can resolve a width that is percent based, this is sometimes possible
|
1666
|
+
// when attached to input type=hidden or elements hidden via css
|
1667
|
+
style = this.opts.element.css('width');
|
1668
|
+
if (style && style.length > 0) return style;
|
1551
1669
|
|
1670
|
+
if (this.opts.width === "resolve") {
|
1552
1671
|
// finally, fallback on the calculated width of the element
|
1553
1672
|
return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
|
1554
1673
|
}
|
@@ -1572,18 +1691,18 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1572
1691
|
|
1573
1692
|
// single
|
1574
1693
|
|
1575
|
-
|
1694
|
+
createContainer: function () {
|
1576
1695
|
var container = $(document.createElement("div")).attr({
|
1577
1696
|
"class": "select2-container"
|
1578
1697
|
}).html([
|
1579
1698
|
"<a href='javascript:void(0)' onclick='return false;' class='select2-choice' tabindex='-1'>",
|
1580
|
-
" <span
|
1699
|
+
" <span> </span><abbr class='select2-search-choice-close'></abbr>",
|
1581
1700
|
" <div><b></b></div>" ,
|
1582
1701
|
"</a>",
|
1583
1702
|
"<input class='select2-focusser select2-offscreen' type='text'/>",
|
1584
|
-
"<div class='select2-drop
|
1703
|
+
"<div class='select2-drop select2-display-none'>" ,
|
1585
1704
|
" <div class='select2-search'>" ,
|
1586
|
-
" <input type='text' autocomplete='off' class='select2-input'/>" ,
|
1705
|
+
" <input type='text' autocomplete='off' autocorrect='off' autocapitilize='off' spellcheck='false' class='select2-input'/>" ,
|
1587
1706
|
" </div>" ,
|
1588
1707
|
" <ul class='select2-results'>" ,
|
1589
1708
|
" </ul>" ,
|
@@ -1592,29 +1711,35 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1592
1711
|
},
|
1593
1712
|
|
1594
1713
|
// single
|
1595
|
-
|
1596
|
-
if (
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
this.focusser.attr("disabled", "disabled");
|
1601
|
-
},
|
1602
|
-
|
1603
|
-
// single
|
1604
|
-
enable: function() {
|
1605
|
-
if (this.enabled) return;
|
1606
|
-
|
1607
|
-
this.parent.enable.apply(this, arguments);
|
1608
|
-
|
1609
|
-
this.focusser.removeAttr("disabled");
|
1714
|
+
enableInterface: function() {
|
1715
|
+
if (this.parent.enableInterface.apply(this, arguments)) {
|
1716
|
+
this.focusser.prop("disabled", !this.isInterfaceEnabled());
|
1717
|
+
}
|
1610
1718
|
},
|
1611
1719
|
|
1612
1720
|
// single
|
1613
1721
|
opening: function () {
|
1722
|
+
var el, range;
|
1614
1723
|
this.parent.opening.apply(this, arguments);
|
1615
|
-
this.
|
1724
|
+
if (this.showSearchInput !== false) {
|
1725
|
+
// IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range
|
1726
|
+
// all other browsers handle this just fine
|
1616
1727
|
|
1617
|
-
|
1728
|
+
this.search.val(this.focusser.val());
|
1729
|
+
}
|
1730
|
+
this.search.focus();
|
1731
|
+
// in IE we have to move the cursor to the end after focussing, otherwise it will be at the beginning and
|
1732
|
+
// new text will appear *before* focusser.val()
|
1733
|
+
el = this.search.get(0);
|
1734
|
+
if (el.createTextRange) {
|
1735
|
+
range = el.createTextRange();
|
1736
|
+
range.collapse(false);
|
1737
|
+
range.select();
|
1738
|
+
}
|
1739
|
+
|
1740
|
+
this.focusser.prop("disabled", true).val("");
|
1741
|
+
this.updateResults(true);
|
1742
|
+
this.opts.element.trigger($.Event("select2-open"));
|
1618
1743
|
},
|
1619
1744
|
|
1620
1745
|
// single
|
@@ -1622,7 +1747,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1622
1747
|
if (!this.opened()) return;
|
1623
1748
|
this.parent.close.apply(this, arguments);
|
1624
1749
|
this.focusser.removeAttr("disabled");
|
1625
|
-
|
1750
|
+
this.focusser.focus();
|
1626
1751
|
},
|
1627
1752
|
|
1628
1753
|
// single
|
@@ -1652,10 +1777,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1652
1777
|
|
1653
1778
|
var selection,
|
1654
1779
|
container = this.container,
|
1655
|
-
dropdown = this.dropdown
|
1656
|
-
clickingInside = false;
|
1780
|
+
dropdown = this.dropdown;
|
1657
1781
|
|
1658
|
-
this.showSearch(
|
1782
|
+
this.showSearch(false);
|
1659
1783
|
|
1660
1784
|
this.selection = selection = container.find(".select2-choice");
|
1661
1785
|
|
@@ -1663,11 +1787,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1663
1787
|
|
1664
1788
|
// rewrite labels from original element to focusser
|
1665
1789
|
this.focusser.attr("id", "s2id_autogen"+nextUid());
|
1790
|
+
|
1666
1791
|
$("label[for='" + this.opts.element.attr("id") + "']")
|
1667
1792
|
.attr('for', this.focusser.attr('id'));
|
1668
1793
|
|
1669
|
-
this.
|
1670
|
-
|
1794
|
+
this.focusser.attr("tabindex", this.elementTabIndex);
|
1795
|
+
|
1796
|
+
this.search.on("keydown", this.bind(function (e) {
|
1797
|
+
if (!this.isInterfaceEnabled()) return;
|
1671
1798
|
|
1672
1799
|
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
|
1673
1800
|
// prevent the page from scrolling
|
@@ -1681,11 +1808,13 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1681
1808
|
this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
|
1682
1809
|
killEvent(e);
|
1683
1810
|
return;
|
1684
|
-
case KEY.TAB:
|
1685
1811
|
case KEY.ENTER:
|
1686
1812
|
this.selectHighlighted();
|
1687
1813
|
killEvent(e);
|
1688
1814
|
return;
|
1815
|
+
case KEY.TAB:
|
1816
|
+
this.selectHighlighted({noFocus: true});
|
1817
|
+
return;
|
1689
1818
|
case KEY.ESC:
|
1690
1819
|
this.cancel(e);
|
1691
1820
|
killEvent(e);
|
@@ -1693,7 +1822,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1693
1822
|
}
|
1694
1823
|
}));
|
1695
1824
|
|
1696
|
-
this.search.
|
1825
|
+
this.search.on("blur", this.bind(function(e) {
|
1697
1826
|
// a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.
|
1698
1827
|
// without this the search field loses focus which is annoying
|
1699
1828
|
if (document.activeElement === this.body().get(0)) {
|
@@ -1703,8 +1832,8 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1703
1832
|
}
|
1704
1833
|
}));
|
1705
1834
|
|
1706
|
-
this.focusser.
|
1707
|
-
if (!this.
|
1835
|
+
this.focusser.on("keydown", this.bind(function (e) {
|
1836
|
+
if (!this.isInterfaceEnabled()) return;
|
1708
1837
|
|
1709
1838
|
if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
|
1710
1839
|
return;
|
@@ -1733,56 +1862,61 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1733
1862
|
|
1734
1863
|
|
1735
1864
|
installKeyUpChangeEvent(this.focusser);
|
1736
|
-
this.focusser.
|
1865
|
+
this.focusser.on("keyup-change input", this.bind(function(e) {
|
1866
|
+
e.stopPropagation();
|
1737
1867
|
if (this.opened()) return;
|
1738
1868
|
this.open();
|
1739
|
-
if (this.showSearchInput !== false) {
|
1740
|
-
this.search.val(this.focusser.val());
|
1741
|
-
}
|
1742
|
-
this.focusser.val("");
|
1743
|
-
killEvent(e);
|
1744
1869
|
}));
|
1745
1870
|
|
1746
|
-
selection.
|
1747
|
-
if (!this.
|
1871
|
+
selection.on("mousedown", "abbr", this.bind(function (e) {
|
1872
|
+
if (!this.isInterfaceEnabled()) return;
|
1748
1873
|
this.clear();
|
1749
1874
|
killEventImmediately(e);
|
1750
1875
|
this.close();
|
1751
1876
|
this.selection.focus();
|
1752
1877
|
}));
|
1753
1878
|
|
1754
|
-
selection.
|
1755
|
-
|
1879
|
+
selection.on("mousedown", this.bind(function (e) {
|
1880
|
+
|
1881
|
+
if (!this.container.hasClass("select2-container-active")) {
|
1882
|
+
this.opts.element.trigger($.Event("select2-focus"));
|
1883
|
+
}
|
1756
1884
|
|
1757
1885
|
if (this.opened()) {
|
1758
1886
|
this.close();
|
1759
|
-
} else if (this.
|
1887
|
+
} else if (this.isInterfaceEnabled()) {
|
1760
1888
|
this.open();
|
1761
1889
|
}
|
1762
1890
|
|
1763
1891
|
killEvent(e);
|
1764
|
-
|
1765
|
-
clickingInside = false;
|
1766
1892
|
}));
|
1767
1893
|
|
1768
|
-
dropdown.
|
1894
|
+
dropdown.on("mousedown", this.bind(function() { this.search.focus(); }));
|
1769
1895
|
|
1770
|
-
selection.
|
1896
|
+
selection.on("focus", this.bind(function(e) {
|
1771
1897
|
killEvent(e);
|
1772
1898
|
}));
|
1773
1899
|
|
1774
|
-
this.focusser.
|
1900
|
+
this.focusser.on("focus", this.bind(function(){
|
1901
|
+
if (!this.container.hasClass("select2-container-active")) {
|
1902
|
+
this.opts.element.trigger($.Event("select2-focus"));
|
1903
|
+
}
|
1775
1904
|
this.container.addClass("select2-container-active");
|
1776
|
-
})).
|
1905
|
+
})).on("blur", this.bind(function() {
|
1777
1906
|
if (!this.opened()) {
|
1778
1907
|
this.container.removeClass("select2-container-active");
|
1908
|
+
this.opts.element.trigger($.Event("select2-blur"));
|
1779
1909
|
}
|
1780
1910
|
}));
|
1781
|
-
this.search.
|
1911
|
+
this.search.on("focus", this.bind(function(){
|
1912
|
+
if (!this.container.hasClass("select2-container-active")) {
|
1913
|
+
this.opts.element.trigger($.Event("select2-focus"));
|
1914
|
+
}
|
1782
1915
|
this.container.addClass("select2-container-active");
|
1783
|
-
}))
|
1916
|
+
}));
|
1784
1917
|
|
1785
1918
|
this.initContainerWidth();
|
1919
|
+
this.opts.element.addClass("select2-offscreen");
|
1786
1920
|
this.setPlaceholder();
|
1787
1921
|
|
1788
1922
|
},
|
@@ -1797,7 +1931,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1797
1931
|
this.setPlaceholder();
|
1798
1932
|
|
1799
1933
|
if (triggerChange !== false){
|
1800
|
-
this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data });
|
1934
|
+
this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
|
1801
1935
|
this.triggerChange({removed:data});
|
1802
1936
|
}
|
1803
1937
|
}
|
@@ -1810,6 +1944,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1810
1944
|
initSelection: function () {
|
1811
1945
|
var selected;
|
1812
1946
|
if (this.opts.element.val() === "" && this.opts.element.text() === "") {
|
1947
|
+
this.updateSelection([]);
|
1813
1948
|
this.close();
|
1814
1949
|
this.setPlaceholder();
|
1815
1950
|
} else {
|
@@ -1826,15 +1961,15 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1826
1961
|
|
1827
1962
|
// single
|
1828
1963
|
prepareOpts: function () {
|
1829
|
-
var opts = this.parent.prepareOpts.apply(this, arguments)
|
1964
|
+
var opts = this.parent.prepareOpts.apply(this, arguments),
|
1965
|
+
self=this;
|
1830
1966
|
|
1831
1967
|
if (opts.element.get(0).tagName.toLowerCase() === "select") {
|
1832
1968
|
// install the selection initializer
|
1833
1969
|
opts.initSelection = function (element, callback) {
|
1834
1970
|
var selected = element.find(":selected");
|
1835
1971
|
// a single select box always has a value, no need to null check 'selected'
|
1836
|
-
|
1837
|
-
callback({id: selected.attr("value"), text: selected.text(), element:selected});
|
1972
|
+
callback(self.optionToData(selected));
|
1838
1973
|
};
|
1839
1974
|
} else if ("data" in opts) {
|
1840
1975
|
// install default initSelection when applied to hidden input and data is local
|
@@ -1885,7 +2020,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1885
2020
|
|
1886
2021
|
this.selection.addClass("select2-default");
|
1887
2022
|
|
1888
|
-
this.
|
2023
|
+
this.container.removeClass("select2-allowclear");
|
1889
2024
|
}
|
1890
2025
|
},
|
1891
2026
|
|
@@ -1907,12 +2042,13 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1907
2042
|
this.highlight(selected);
|
1908
2043
|
}
|
1909
2044
|
|
1910
|
-
//
|
2045
|
+
// show the search box if this is the first we got the results and there are enough of them for search
|
1911
2046
|
|
1912
|
-
if (initial === true) {
|
2047
|
+
if (initial === true && this.showSearchInput === false) {
|
1913
2048
|
var min=this.opts.minimumResultsForSearch;
|
1914
|
-
|
1915
|
-
|
2049
|
+
if (min>=0) {
|
2050
|
+
this.showSearch(countResults(data.results)>=min);
|
2051
|
+
}
|
1916
2052
|
}
|
1917
2053
|
|
1918
2054
|
},
|
@@ -1921,26 +2057,31 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1921
2057
|
showSearch: function(showSearchInput) {
|
1922
2058
|
this.showSearchInput = showSearchInput;
|
1923
2059
|
|
1924
|
-
this.dropdown.find(".select2-search")
|
2060
|
+
this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput);
|
2061
|
+
this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput);
|
1925
2062
|
//add "select2-with-searchbox" to the container if search box is shown
|
1926
|
-
$(this.dropdown, this.container)
|
2063
|
+
$(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput);
|
1927
2064
|
},
|
1928
2065
|
|
1929
2066
|
// single
|
1930
2067
|
onSelect: function (data, options) {
|
1931
|
-
|
2068
|
+
|
2069
|
+
if (!this.triggerSelect(data)) { return; }
|
2070
|
+
|
2071
|
+
var old = this.opts.element.val(),
|
2072
|
+
oldData = this.data();
|
1932
2073
|
|
1933
2074
|
this.opts.element.val(this.id(data));
|
1934
2075
|
this.updateSelection(data);
|
1935
2076
|
|
1936
|
-
this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
|
2077
|
+
this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data });
|
1937
2078
|
|
1938
2079
|
this.close();
|
1939
2080
|
|
1940
2081
|
if (!options || !options.noFocus)
|
1941
2082
|
this.selection.focus();
|
1942
2083
|
|
1943
|
-
if (!equal(old, this.id(data))) { this.triggerChange(); }
|
2084
|
+
if (!equal(old, this.id(data))) { this.triggerChange({added:data,removed:oldData}); }
|
1944
2085
|
},
|
1945
2086
|
|
1946
2087
|
// single
|
@@ -1959,13 +2100,17 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1959
2100
|
this.selection.removeClass("select2-default");
|
1960
2101
|
|
1961
2102
|
if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
|
1962
|
-
this.
|
2103
|
+
this.container.addClass("select2-allowclear");
|
1963
2104
|
}
|
1964
2105
|
},
|
1965
2106
|
|
1966
2107
|
// single
|
1967
2108
|
val: function () {
|
1968
|
-
var val,
|
2109
|
+
var val,
|
2110
|
+
triggerChange = false,
|
2111
|
+
data = null,
|
2112
|
+
self = this,
|
2113
|
+
oldData = this.data();
|
1969
2114
|
|
1970
2115
|
if (arguments.length === 0) {
|
1971
2116
|
return this.opts.element.val();
|
@@ -1981,13 +2126,13 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1981
2126
|
this.select
|
1982
2127
|
.val(val)
|
1983
2128
|
.find(":selected").each2(function (i, elm) {
|
1984
|
-
data =
|
2129
|
+
data = self.optionToData(elm);
|
1985
2130
|
return false;
|
1986
2131
|
});
|
1987
2132
|
this.updateSelection(data);
|
1988
2133
|
this.setPlaceholder();
|
1989
2134
|
if (triggerChange) {
|
1990
|
-
this.triggerChange();
|
2135
|
+
this.triggerChange({added: data, removed:oldData});
|
1991
2136
|
}
|
1992
2137
|
} else {
|
1993
2138
|
if (this.opts.initSelection === undefined) {
|
@@ -1996,9 +2141,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
1996
2141
|
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
|
1997
2142
|
if (!val && val !== 0) {
|
1998
2143
|
this.clear(triggerChange);
|
1999
|
-
if (triggerChange) {
|
2000
|
-
this.triggerChange();
|
2001
|
-
}
|
2002
2144
|
return;
|
2003
2145
|
}
|
2004
2146
|
this.opts.element.val(val);
|
@@ -2007,7 +2149,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2007
2149
|
self.updateSelection(data);
|
2008
2150
|
self.setPlaceholder();
|
2009
2151
|
if (triggerChange) {
|
2010
|
-
self.triggerChange();
|
2152
|
+
self.triggerChange({added: data, removed:oldData});
|
2011
2153
|
}
|
2012
2154
|
});
|
2013
2155
|
}
|
@@ -2020,7 +2162,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2020
2162
|
},
|
2021
2163
|
|
2022
2164
|
// single
|
2023
|
-
data: function(value) {
|
2165
|
+
data: function(value, triggerChange) {
|
2024
2166
|
var data;
|
2025
2167
|
|
2026
2168
|
if (arguments.length === 0) {
|
@@ -2029,10 +2171,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2029
2171
|
return data;
|
2030
2172
|
} else {
|
2031
2173
|
if (!value || value === "") {
|
2032
|
-
this.clear();
|
2174
|
+
this.clear(triggerChange);
|
2033
2175
|
} else {
|
2176
|
+
data = this.data();
|
2034
2177
|
this.opts.element.val(!value ? "" : this.id(value));
|
2035
2178
|
this.updateSelection(value);
|
2179
|
+
if (triggerChange) {
|
2180
|
+
this.triggerChange({added: value, removed:data});
|
2181
|
+
}
|
2036
2182
|
}
|
2037
2183
|
}
|
2038
2184
|
}
|
@@ -2048,19 +2194,20 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2048
2194
|
" <ul class='select2-choices'>",
|
2049
2195
|
//"<li class='select2-search-choice'><span>California</span><a href="javascript:void(0)" class="select2-search-choice-close"></a></li>" ,
|
2050
2196
|
" <li class='select2-search-field'>" ,
|
2051
|
-
" <input type='text' autocomplete='off' class='select2-input'>" ,
|
2197
|
+
" <input type='text' autocomplete='off' autocorrect='off' autocapitilize='off' spellcheck='false' class='select2-input'>" ,
|
2052
2198
|
" </li>" ,
|
2053
2199
|
"</ul>" ,
|
2054
|
-
"<div class='select2-drop select2-drop-multi
|
2200
|
+
"<div class='select2-drop select2-drop-multi select2-display-none'>" ,
|
2055
2201
|
" <ul class='select2-results'>" ,
|
2056
2202
|
" </ul>" ,
|
2057
2203
|
"</div>"].join(""));
|
2058
|
-
|
2204
|
+
return container;
|
2059
2205
|
},
|
2060
2206
|
|
2061
2207
|
// multi
|
2062
2208
|
prepareOpts: function () {
|
2063
|
-
var opts = this.parent.prepareOpts.apply(this, arguments)
|
2209
|
+
var opts = this.parent.prepareOpts.apply(this, arguments),
|
2210
|
+
self=this;
|
2064
2211
|
|
2065
2212
|
// TODO validate placeholder is a string if specified
|
2066
2213
|
|
@@ -2071,7 +2218,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2071
2218
|
var data = [];
|
2072
2219
|
|
2073
2220
|
element.find(":selected").each2(function (i, elm) {
|
2074
|
-
data.push(
|
2221
|
+
data.push(self.optionToData(elm));
|
2075
2222
|
});
|
2076
2223
|
callback(data);
|
2077
2224
|
};
|
@@ -2092,7 +2239,21 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2092
2239
|
return is_match;
|
2093
2240
|
},
|
2094
2241
|
callback: !$.isFunction(callback) ? $.noop : function() {
|
2095
|
-
|
2242
|
+
// reorder matches based on the order they appear in the ids array because right now
|
2243
|
+
// they are in the order in which they appear in data array
|
2244
|
+
var ordered = [];
|
2245
|
+
for (var i = 0; i < ids.length; i++) {
|
2246
|
+
var id = ids[i];
|
2247
|
+
for (var j = 0; j < matches.length; j++) {
|
2248
|
+
var match = matches[j];
|
2249
|
+
if (equal(id, opts.id(match))) {
|
2250
|
+
ordered.push(match);
|
2251
|
+
matches.splice(j, 1);
|
2252
|
+
break;
|
2253
|
+
}
|
2254
|
+
}
|
2255
|
+
}
|
2256
|
+
callback(ordered);
|
2096
2257
|
}
|
2097
2258
|
});
|
2098
2259
|
};
|
@@ -2101,6 +2262,24 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2101
2262
|
return opts;
|
2102
2263
|
},
|
2103
2264
|
|
2265
|
+
selectChoice: function (choice) {
|
2266
|
+
|
2267
|
+
var selected = this.container.find(".select2-search-choice-focus");
|
2268
|
+
if (selected.length && choice && choice[0] == selected[0]) {
|
2269
|
+
|
2270
|
+
} else {
|
2271
|
+
if (selected.length) {
|
2272
|
+
this.opts.element.trigger("choice-deselected", selected);
|
2273
|
+
}
|
2274
|
+
selected.removeClass("select2-search-choice-focus");
|
2275
|
+
if (choice && choice.length) {
|
2276
|
+
this.close();
|
2277
|
+
choice.addClass("select2-search-choice-focus");
|
2278
|
+
this.opts.element.trigger("choice-selected", choice);
|
2279
|
+
}
|
2280
|
+
}
|
2281
|
+
},
|
2282
|
+
|
2104
2283
|
// multi
|
2105
2284
|
initContainer: function () {
|
2106
2285
|
|
@@ -2109,39 +2288,77 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2109
2288
|
this.searchContainer = this.container.find(".select2-search-field");
|
2110
2289
|
this.selection = selection = this.container.find(selector);
|
2111
2290
|
|
2291
|
+
var _this = this;
|
2292
|
+
this.selection.on("mousedown", ".select2-search-choice", function (e) {
|
2293
|
+
//killEvent(e);
|
2294
|
+
_this.search[0].focus();
|
2295
|
+
_this.selectChoice($(this));
|
2296
|
+
})
|
2297
|
+
//.sortable({
|
2298
|
+
// items: " > li",
|
2299
|
+
// tolerance: "pointer",
|
2300
|
+
// revert: 100
|
2301
|
+
//});
|
2302
|
+
|
2112
2303
|
// rewrite labels from original element to focusser
|
2113
2304
|
this.search.attr("id", "s2id_autogen"+nextUid());
|
2114
2305
|
$("label[for='" + this.opts.element.attr("id") + "']")
|
2115
2306
|
.attr('for', this.search.attr('id'));
|
2116
2307
|
|
2117
|
-
this.search.
|
2118
|
-
if (!this.
|
2308
|
+
this.search.on("input paste", this.bind(function() {
|
2309
|
+
if (!this.isInterfaceEnabled()) return;
|
2119
2310
|
if (!this.opened()) {
|
2120
2311
|
this.open();
|
2121
2312
|
}
|
2122
2313
|
}));
|
2123
2314
|
|
2124
|
-
this.search.
|
2125
|
-
if (!this.enabled) return;
|
2315
|
+
this.search.attr("tabindex", this.elementTabIndex);
|
2126
2316
|
|
2127
|
-
|
2128
|
-
|
2317
|
+
this.keydowns = 0;
|
2318
|
+
this.search.on("keydown", this.bind(function (e) {
|
2319
|
+
if (!this.isInterfaceEnabled()) return;
|
2320
|
+
|
2321
|
+
++this.keydowns;
|
2322
|
+
var selected = selection.find(".select2-search-choice-focus");
|
2323
|
+
var prev = selected.prev(".select2-search-choice:not(.select2-locked)");
|
2324
|
+
var next = selected.next(".select2-search-choice:not(.select2-locked)");
|
2325
|
+
var pos = getCursorInfo(this.search);
|
2129
2326
|
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2327
|
+
if (selected.length &&
|
2328
|
+
(e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {
|
2329
|
+
var selectedChoice = selected;
|
2330
|
+
if (e.which == KEY.LEFT && prev.length) {
|
2331
|
+
selectedChoice = prev;
|
2332
|
+
}
|
2333
|
+
else if (e.which == KEY.RIGHT) {
|
2334
|
+
selectedChoice = next.length ? next : null;
|
2335
|
+
}
|
2336
|
+
else if (e.which === KEY.BACKSPACE) {
|
2133
2337
|
this.unselect(selected.first());
|
2134
2338
|
this.search.width(10);
|
2135
|
-
|
2136
|
-
|
2339
|
+
selectedChoice = prev.length ? prev : next;
|
2340
|
+
} else if (e.which == KEY.DELETE) {
|
2341
|
+
this.unselect(selected.first());
|
2342
|
+
this.search.width(10);
|
2343
|
+
selectedChoice = next.length ? next : null;
|
2344
|
+
} else if (e.which == KEY.ENTER) {
|
2345
|
+
selectedChoice = null;
|
2137
2346
|
}
|
2138
2347
|
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2348
|
+
this.selectChoice(selectedChoice);
|
2349
|
+
killEvent(e);
|
2350
|
+
if (!selectedChoice || !selectedChoice.length) {
|
2351
|
+
this.open();
|
2142
2352
|
}
|
2353
|
+
return;
|
2354
|
+
} else if (((e.which === KEY.BACKSPACE && this.keydowns == 1)
|
2355
|
+
|| e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {
|
2356
|
+
|
2357
|
+
this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());
|
2358
|
+
killEvent(e);
|
2359
|
+
return;
|
2143
2360
|
} else {
|
2144
|
-
|
2361
|
+
this.selectChoice(null);
|
2145
2362
|
}
|
2146
2363
|
|
2147
2364
|
if (this.opened()) {
|
@@ -2152,10 +2369,12 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2152
2369
|
killEvent(e);
|
2153
2370
|
return;
|
2154
2371
|
case KEY.ENTER:
|
2155
|
-
case KEY.TAB:
|
2156
2372
|
this.selectHighlighted();
|
2157
2373
|
killEvent(e);
|
2158
2374
|
return;
|
2375
|
+
case KEY.TAB:
|
2376
|
+
this.selectHighlighted({noFocus:true});
|
2377
|
+
return;
|
2159
2378
|
case KEY.ESC:
|
2160
2379
|
this.cancel(e);
|
2161
2380
|
killEvent(e);
|
@@ -2190,56 +2409,59 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2190
2409
|
|
2191
2410
|
}));
|
2192
2411
|
|
2193
|
-
this.search.
|
2412
|
+
this.search.on("keyup", this.bind(function (e) {
|
2413
|
+
this.keydowns = 0;
|
2414
|
+
this.resizeSearch();
|
2415
|
+
})
|
2416
|
+
);
|
2194
2417
|
|
2195
|
-
this.search.
|
2418
|
+
this.search.on("blur", this.bind(function(e) {
|
2196
2419
|
this.container.removeClass("select2-container-active");
|
2197
2420
|
this.search.removeClass("select2-focused");
|
2421
|
+
this.selectChoice(null);
|
2198
2422
|
if (!this.opened()) this.clearSearch();
|
2199
2423
|
e.stopImmediatePropagation();
|
2424
|
+
this.opts.element.trigger($.Event("select2-blur"));
|
2200
2425
|
}));
|
2201
2426
|
|
2202
|
-
this.container.
|
2203
|
-
if (!this.
|
2427
|
+
this.container.on("mousedown", selector, this.bind(function (e) {
|
2428
|
+
if (!this.isInterfaceEnabled()) return;
|
2204
2429
|
if ($(e.target).closest(".select2-search-choice").length > 0) {
|
2205
2430
|
// clicked inside a select2 search choice, do not open
|
2206
2431
|
return;
|
2207
2432
|
}
|
2433
|
+
this.selectChoice(null);
|
2208
2434
|
this.clearPlaceholder();
|
2435
|
+
if (!this.container.hasClass("select2-container-active")) {
|
2436
|
+
this.opts.element.trigger($.Event("select2-focus"));
|
2437
|
+
}
|
2209
2438
|
this.open();
|
2210
2439
|
this.focusSearch();
|
2211
2440
|
e.preventDefault();
|
2212
2441
|
}));
|
2213
2442
|
|
2214
|
-
this.container.
|
2215
|
-
if (!this.
|
2443
|
+
this.container.on("focus", selector, this.bind(function () {
|
2444
|
+
if (!this.isInterfaceEnabled()) return;
|
2445
|
+
if (!this.container.hasClass("select2-container-active")) {
|
2446
|
+
this.opts.element.trigger($.Event("select2-focus"));
|
2447
|
+
}
|
2216
2448
|
this.container.addClass("select2-container-active");
|
2217
2449
|
this.dropdown.addClass("select2-drop-active");
|
2218
2450
|
this.clearPlaceholder();
|
2219
2451
|
}));
|
2220
2452
|
|
2221
2453
|
this.initContainerWidth();
|
2454
|
+
this.opts.element.addClass("select2-offscreen");
|
2222
2455
|
|
2223
2456
|
// set the placeholder if necessary
|
2224
2457
|
this.clearSearch();
|
2225
2458
|
},
|
2226
2459
|
|
2227
2460
|
// multi
|
2228
|
-
|
2229
|
-
if (this.
|
2230
|
-
|
2231
|
-
|
2232
|
-
|
2233
|
-
this.search.removeAttr("disabled");
|
2234
|
-
},
|
2235
|
-
|
2236
|
-
// multi
|
2237
|
-
disable: function() {
|
2238
|
-
if (!this.enabled) return;
|
2239
|
-
|
2240
|
-
this.parent.disable.apply(this, arguments);
|
2241
|
-
|
2242
|
-
this.search.attr("disabled", true);
|
2461
|
+
enableInterface: function() {
|
2462
|
+
if (this.parent.enableInterface.apply(this, arguments)) {
|
2463
|
+
this.search.prop("disabled", !this.isInterfaceEnabled());
|
2464
|
+
}
|
2243
2465
|
},
|
2244
2466
|
|
2245
2467
|
// multi
|
@@ -2266,13 +2488,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2266
2488
|
|
2267
2489
|
// multi
|
2268
2490
|
clearSearch: function () {
|
2269
|
-
var placeholder = this.getPlaceholder()
|
2491
|
+
var placeholder = this.getPlaceholder(),
|
2492
|
+
maxWidth = this.getMaxSearchWidth();
|
2270
2493
|
|
2271
2494
|
if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
|
2272
2495
|
this.search.val(placeholder).addClass("select2-default");
|
2273
2496
|
// stretch the search box to full width of the container so as much of the placeholder is visible as possible
|
2274
2497
|
// we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944
|
2275
|
-
this.search.width(this.
|
2498
|
+
this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width"));
|
2276
2499
|
} else {
|
2277
2500
|
this.search.val("").width(10);
|
2278
2501
|
}
|
@@ -2294,7 +2517,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2294
2517
|
|
2295
2518
|
this.focusSearch();
|
2296
2519
|
|
2297
|
-
this.
|
2520
|
+
this.updateResults(true);
|
2521
|
+
this.search.focus();
|
2522
|
+
this.opts.element.trigger($.Event("select2-open"));
|
2298
2523
|
},
|
2299
2524
|
|
2300
2525
|
// multi
|
@@ -2350,6 +2575,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2350
2575
|
|
2351
2576
|
// multi
|
2352
2577
|
onSelect: function (data, options) {
|
2578
|
+
|
2579
|
+
if (!this.triggerSelect(data)) { return; }
|
2580
|
+
|
2353
2581
|
this.addSelectedChoice(data);
|
2354
2582
|
|
2355
2583
|
this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
|
@@ -2408,14 +2636,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2408
2636
|
|
2409
2637
|
formatted=this.opts.formatSelection(data, choice.find("div"));
|
2410
2638
|
if (formatted != undefined) {
|
2411
|
-
choice.find("div").replaceWith("<div>"+this.opts.escapeMarkup(formatted)+"</div>");
|
2639
|
+
choice.find("div").replaceWith("<div title='"+this.opts.escapeMarkup(formatted)+"'>"+this.opts.escapeMarkup(formatted)+"</div>");
|
2412
2640
|
}
|
2413
2641
|
|
2414
2642
|
if(enableChoice){
|
2415
2643
|
choice.find(".select2-search-choice-close")
|
2416
|
-
.
|
2417
|
-
.
|
2418
|
-
if (!this.
|
2644
|
+
.on("mousedown", killEvent)
|
2645
|
+
.on("click dblclick", this.bind(function (e) {
|
2646
|
+
if (!this.isInterfaceEnabled()) return;
|
2419
2647
|
|
2420
2648
|
$(e.target).closest(".select2-search-choice").fadeOut('fast', this.bind(function(){
|
2421
2649
|
this.unselect($(e.target));
|
@@ -2424,8 +2652,8 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2424
2652
|
this.focusSearch();
|
2425
2653
|
})).dequeue();
|
2426
2654
|
killEvent(e);
|
2427
|
-
})).
|
2428
|
-
if (!this.
|
2655
|
+
})).on("focus", this.bind(function () {
|
2656
|
+
if (!this.isInterfaceEnabled()) return;
|
2429
2657
|
this.container.addClass("select2-container-active");
|
2430
2658
|
this.dropdown.addClass("select2-drop-active");
|
2431
2659
|
}));
|
@@ -2472,7 +2700,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2472
2700
|
},
|
2473
2701
|
|
2474
2702
|
// multi
|
2475
|
-
postprocessResults: function () {
|
2703
|
+
postprocessResults: function (data, initial, noHighlightUpdate) {
|
2476
2704
|
var val = this.getVal(),
|
2477
2705
|
choices = this.results.find(".select2-result"),
|
2478
2706
|
compound = this.results.find(".select2-result-with-children"),
|
@@ -2495,10 +2723,15 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2495
2723
|
}
|
2496
2724
|
});
|
2497
2725
|
|
2498
|
-
if (this.highlight() == -1){
|
2726
|
+
if (this.highlight() == -1 && noHighlightUpdate !== false){
|
2499
2727
|
self.highlight(0);
|
2500
2728
|
}
|
2501
2729
|
|
2730
|
+
//If all results are chosen render formatNoMAtches
|
2731
|
+
if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){
|
2732
|
+
this.results.append("<li class='select2-no-results'>" + self.opts.formatNoMatches(self.search.val()) + "</li>");
|
2733
|
+
}
|
2734
|
+
|
2502
2735
|
},
|
2503
2736
|
|
2504
2737
|
// multi
|
@@ -2509,7 +2742,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2509
2742
|
// multi
|
2510
2743
|
resizeSearch: function () {
|
2511
2744
|
var minimumWidth, left, maxWidth, containerLeft, searchWidth,
|
2512
|
-
|
2745
|
+
sideBorderPadding = getSideBorderPadding(this.search);
|
2513
2746
|
|
2514
2747
|
minimumWidth = measureTextWidth(this.search) + 10;
|
2515
2748
|
|
@@ -2563,18 +2796,36 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2563
2796
|
},
|
2564
2797
|
|
2565
2798
|
// multi
|
2566
|
-
|
2567
|
-
var
|
2799
|
+
buildChangeDetails: function (old, current) {
|
2800
|
+
var current = current.slice(0),
|
2801
|
+
old = old.slice(0);
|
2802
|
+
|
2803
|
+
// remove intersection from each array
|
2804
|
+
for (var i = 0; i < current.length; i++) {
|
2805
|
+
for (var j = 0; j < old.length; j++) {
|
2806
|
+
if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
|
2807
|
+
current.splice(i, 1);
|
2808
|
+
i--;
|
2809
|
+
old.splice(j, 1);
|
2810
|
+
j--;
|
2811
|
+
}
|
2812
|
+
}
|
2813
|
+
}
|
2814
|
+
|
2815
|
+
return {added: current, removed: old};
|
2816
|
+
},
|
2817
|
+
|
2818
|
+
|
2819
|
+
// multi
|
2820
|
+
val: function (val, triggerChange) {
|
2821
|
+
var oldData, self=this, changeDetails;
|
2568
2822
|
|
2569
2823
|
if (arguments.length === 0) {
|
2570
2824
|
return this.getVal();
|
2571
2825
|
}
|
2572
2826
|
|
2573
|
-
|
2574
|
-
|
2575
|
-
if (arguments.length > 1) {
|
2576
|
-
triggerChange = arguments[1];
|
2577
|
-
}
|
2827
|
+
oldData=this.data();
|
2828
|
+
if (!oldData.length) oldData=[];
|
2578
2829
|
|
2579
2830
|
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
|
2580
2831
|
if (!val && val !== 0) {
|
@@ -2582,7 +2833,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2582
2833
|
this.updateSelection([]);
|
2583
2834
|
this.clearSearch();
|
2584
2835
|
if (triggerChange) {
|
2585
|
-
this.triggerChange();
|
2836
|
+
this.triggerChange({added: this.data(), removed: oldData});
|
2586
2837
|
}
|
2587
2838
|
return;
|
2588
2839
|
}
|
@@ -2593,7 +2844,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2593
2844
|
if (this.select) {
|
2594
2845
|
this.opts.initSelection(this.select, this.bind(this.updateSelection));
|
2595
2846
|
if (triggerChange) {
|
2596
|
-
this.triggerChange();
|
2847
|
+
this.triggerChange(this.buildChangeDetails(oldData, this.data()));
|
2597
2848
|
}
|
2598
2849
|
} else {
|
2599
2850
|
if (this.opts.initSelection === undefined) {
|
@@ -2606,7 +2857,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2606
2857
|
self.updateSelection(data);
|
2607
2858
|
self.clearSearch();
|
2608
2859
|
if (triggerChange) {
|
2609
|
-
self.triggerChange();
|
2860
|
+
self.triggerChange(this.buildChangeDetails(oldData, this.data()));
|
2610
2861
|
}
|
2611
2862
|
});
|
2612
2863
|
}
|
@@ -2647,19 +2898,23 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2647
2898
|
},
|
2648
2899
|
|
2649
2900
|
// multi
|
2650
|
-
data: function(values) {
|
2651
|
-
var self=this, ids;
|
2901
|
+
data: function(values, triggerChange) {
|
2902
|
+
var self=this, ids, old;
|
2652
2903
|
if (arguments.length === 0) {
|
2653
2904
|
return this.selection
|
2654
2905
|
.find(".select2-search-choice")
|
2655
2906
|
.map(function() { return $(this).data("select2-data"); })
|
2656
2907
|
.get();
|
2657
2908
|
} else {
|
2909
|
+
old = this.data();
|
2658
2910
|
if (!values) { values = []; }
|
2659
2911
|
ids = $.map(values, function(e) { return self.opts.id(e); });
|
2660
2912
|
this.setVal(ids);
|
2661
2913
|
this.updateSelection(values);
|
2662
2914
|
this.clearSearch();
|
2915
|
+
if (triggerChange) {
|
2916
|
+
this.triggerChange(this.buildChangeDetails(old, this.data()));
|
2917
|
+
}
|
2663
2918
|
}
|
2664
2919
|
}
|
2665
2920
|
});
|
@@ -2669,7 +2924,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2669
2924
|
var args = Array.prototype.slice.call(arguments, 0),
|
2670
2925
|
opts,
|
2671
2926
|
select2,
|
2672
|
-
value, multiple,
|
2927
|
+
value, multiple,
|
2928
|
+
allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "readonly", "positionDropdown", "data"],
|
2929
|
+
valueMethods = ["val", "opened", "isFocused", "container", "data"];
|
2673
2930
|
|
2674
2931
|
this.each(function () {
|
2675
2932
|
if (args.length === 0 || typeof(args[0]) === "object") {
|
@@ -2677,7 +2934,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2677
2934
|
opts.element = $(this);
|
2678
2935
|
|
2679
2936
|
if (opts.element.get(0).tagName.toLowerCase() === "select") {
|
2680
|
-
multiple = opts.element.
|
2937
|
+
multiple = opts.element.prop("multiple");
|
2681
2938
|
} else {
|
2682
2939
|
multiple = opts.multiple || false;
|
2683
2940
|
if ("tags" in opts) {opts.multiple = multiple = true;}
|
@@ -2699,7 +2956,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2699
2956
|
} else {
|
2700
2957
|
value = select2[args[0]].apply(select2, args.slice(1));
|
2701
2958
|
}
|
2702
|
-
if (
|
2959
|
+
if (indexOf(args[0], valueMethods) >= 0) {
|
2960
|
+
return false;
|
2961
|
+
}
|
2703
2962
|
} else {
|
2704
2963
|
throw "Invalid arguments to select2 plugin: " + args;
|
2705
2964
|
}
|
@@ -2753,12 +3012,12 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2753
3012
|
'<': '<',
|
2754
3013
|
'>': '>',
|
2755
3014
|
'"': '"',
|
2756
|
-
"'": '
|
3015
|
+
"'": ''',
|
2757
3016
|
"/": '/'
|
2758
3017
|
};
|
2759
3018
|
|
2760
3019
|
return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
|
2761
|
-
return replace_map[match
|
3020
|
+
return replace_map[match];
|
2762
3021
|
});
|
2763
3022
|
},
|
2764
3023
|
blurOnChange: false,
|
@@ -2767,6 +3026,15 @@ the specific language governing permissions and limitations under the Apache Lic
|
|
2767
3026
|
adaptDropdownCssClass: function(c) { return null; }
|
2768
3027
|
};
|
2769
3028
|
|
3029
|
+
$.fn.select2.ajaxDefaults = {
|
3030
|
+
transport: $.ajax,
|
3031
|
+
params: {
|
3032
|
+
type: "GET",
|
3033
|
+
cache: false,
|
3034
|
+
dataType: "json"
|
3035
|
+
}
|
3036
|
+
};
|
3037
|
+
|
2770
3038
|
// exports
|
2771
3039
|
window.Select2 = {
|
2772
3040
|
query: {
|