select2-rails 3.2.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +3 -3
- data/lib/select2-rails/version.rb +1 -1
- data/select2-rails.gemspec +1 -0
- data/vendor/assets/images/select2-spinner.gif +0 -0
- data/vendor/assets/images/select2.png +0 -0
- data/vendor/assets/images/select2x2.png +0 -0
- data/vendor/assets/javascripts/select2.js +460 -271
- data/vendor/assets/stylesheets/select2.css.scss +324 -259
- metadata +95 -80
data/README.md
CHANGED
@@ -26,13 +26,13 @@ Add to your `app/assets/stylesheets/application.css`:
|
|
26
26
|
*= require select2
|
27
27
|
|
28
28
|
## Version
|
29
|
-
From `v2.1.0` on, `select2-rails`'s version will match the version of `Select2` it uses. Currently, `select2-rails` uses `Select2 v3.
|
29
|
+
From `v2.1.0` on, `select2-rails`'s version will match the version of `Select2` it uses. Currently, `select2-rails` uses `Select2 v3.2`.
|
30
30
|
|
31
31
|
The last number of the version is the patch version specific to the gem. For example, for a version of the form `2.x.y`, `2.x` is the release of `Select2` we should be compatible with, and y is the patch version specific to the gem (ie. to resolve any gem-specific issues that crop up).
|
32
32
|
|
33
33
|
## Contributions
|
34
34
|
|
35
|
-
If you
|
35
|
+
If you want to contribute, please:
|
36
36
|
|
37
37
|
* Fork the project.
|
38
38
|
* Make your feature addition or bug fix.
|
@@ -40,4 +40,4 @@ If you wont to contribute, please:
|
|
40
40
|
|
41
41
|
## Copyright
|
42
42
|
|
43
|
-
Copyright (c) 2012 Rogerio Medeiros. See [LICENSE](https://github.com/argerim/select2-rails/blob/master/LICENSE) for details.
|
43
|
+
Copyright (c) 2012 Rogerio Medeiros. See [LICENSE](https://github.com/argerim/select2-rails/blob/master/LICENSE) for details.
|
data/select2-rails.gemspec
CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
|
18
18
|
s.add_dependency "thor", "~> 0.14"
|
19
|
+
s.add_runtime_dependency "sass-rails", "~> 3.2"
|
19
20
|
s.add_development_dependency "bundler", "~> 1.0"
|
20
21
|
s.add_development_dependency "rails", "~> 3.0"
|
21
22
|
s.add_development_dependency "httpclient", "~> 2.2"
|
Binary file
|
File without changes
|
File without changes
|
@@ -1,17 +1,23 @@
|
|
1
1
|
/*
|
2
|
-
|
2
|
+
Copyright 2012 Igor Vaynberg
|
3
3
|
|
4
|
-
|
4
|
+
Version: 3.3.0 Timestamp: Tue Feb 5 18:33:54 PST 2013
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
|
7
|
+
General Public License version 2 (the "GPL License"). You may choose either license to govern your
|
8
|
+
use of this software only upon the condition that you accept all of the terms of either the Apache
|
9
|
+
License or the GPL License.
|
8
10
|
|
9
|
-
|
11
|
+
You may obtain a copy of the Apache License and the GPL License at:
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
14
|
+
http://www.gnu.org/licenses/gpl-2.0.html
|
15
|
+
|
16
|
+
Unless required by applicable law or agreed to in writing, software distributed under the
|
17
|
+
Apache License or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
18
|
+
CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
|
19
|
+
the specific language governing permissions and limitations under the Apache License and the GPL License.
|
20
|
+
*/
|
15
21
|
(function ($) {
|
16
22
|
if(typeof $.fn.each2 == "undefined"){
|
17
23
|
$.fn.extend({
|
@@ -40,7 +46,8 @@
|
|
40
46
|
return;
|
41
47
|
}
|
42
48
|
|
43
|
-
var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer
|
49
|
+
var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
|
50
|
+
lastMousePosition, $document;
|
44
51
|
|
45
52
|
KEY = {
|
46
53
|
TAB: 9,
|
@@ -90,42 +97,23 @@
|
|
90
97
|
}
|
91
98
|
};
|
92
99
|
|
100
|
+
$document = $(document);
|
101
|
+
|
93
102
|
nextUid=(function() { var counter=1; return function() { return counter++; }; }());
|
94
103
|
|
95
104
|
function indexOf(value, array) {
|
96
|
-
var i = 0, l = array.length
|
97
|
-
|
98
|
-
if (typeof value === "undefined") {
|
99
|
-
return -1;
|
100
|
-
}
|
101
|
-
|
102
|
-
if (value.constructor === String) {
|
103
|
-
for (; i < l; i = i + 1) if (value.localeCompare(array[i]) === 0) return i;
|
104
|
-
} else {
|
105
|
-
for (; i < l; i = i + 1) {
|
106
|
-
v = array[i];
|
107
|
-
if (v.constructor === String) {
|
108
|
-
if (v.localeCompare(value) === 0) return i;
|
109
|
-
} else {
|
110
|
-
if (v === value) return i;
|
111
|
-
}
|
112
|
-
}
|
113
|
-
}
|
105
|
+
var i = 0, l = array.length;
|
106
|
+
for (; i < l; i = i + 1) if (value === array[i]) return i;
|
114
107
|
return -1;
|
115
108
|
}
|
116
109
|
|
117
110
|
/**
|
118
|
-
* Compares equality of a and b
|
111
|
+
* Compares equality of a and b
|
119
112
|
* @param a
|
120
113
|
* @param b
|
121
114
|
*/
|
122
115
|
function equal(a, b) {
|
123
|
-
|
124
|
-
if (a === undefined || b === undefined) return false;
|
125
|
-
if (a === null || b === null) return false;
|
126
|
-
if (a.constructor === String) return a.localeCompare(b) === 0;
|
127
|
-
if (b.constructor === String) return b.localeCompare(a) === 0;
|
128
|
-
return false;
|
116
|
+
return a===b;
|
129
117
|
}
|
130
118
|
|
131
119
|
/**
|
@@ -143,7 +131,7 @@
|
|
143
131
|
}
|
144
132
|
|
145
133
|
function getSideBorderPadding(element) {
|
146
|
-
return element.outerWidth() - element.width();
|
134
|
+
return element.outerWidth(false) - element.width();
|
147
135
|
}
|
148
136
|
|
149
137
|
function installKeyUpChangeEvent(element) {
|
@@ -162,8 +150,8 @@
|
|
162
150
|
});
|
163
151
|
}
|
164
152
|
|
165
|
-
$
|
166
|
-
|
153
|
+
$document.bind("mousemove", function (e) {
|
154
|
+
lastMousePosition = {x: e.pageX, y: e.pageY};
|
167
155
|
});
|
168
156
|
|
169
157
|
/**
|
@@ -174,7 +162,7 @@
|
|
174
162
|
*/
|
175
163
|
function installFilteredMouseMove(element) {
|
176
164
|
element.bind("mousemove", function (e) {
|
177
|
-
var lastpos =
|
165
|
+
var lastpos = lastMousePosition;
|
178
166
|
if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
|
179
167
|
$(e.target).trigger("mousemove-filtered", e);
|
180
168
|
}
|
@@ -227,11 +215,15 @@
|
|
227
215
|
event.preventDefault();
|
228
216
|
event.stopPropagation();
|
229
217
|
}
|
218
|
+
function killEventImmediately(event) {
|
219
|
+
event.preventDefault();
|
220
|
+
event.stopImmediatePropagation();
|
221
|
+
}
|
230
222
|
|
231
223
|
function measureTextWidth(e) {
|
232
224
|
if (!sizer){
|
233
225
|
var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
|
234
|
-
sizer = $("
|
226
|
+
sizer = $(document.createElement("div")).css({
|
235
227
|
position: "absolute",
|
236
228
|
left: "-10000px",
|
237
229
|
top: "-10000px",
|
@@ -244,26 +236,27 @@
|
|
244
236
|
textTransform: style.textTransform,
|
245
237
|
whiteSpace: "nowrap"
|
246
238
|
});
|
239
|
+
sizer.attr("class","select2-sizer");
|
247
240
|
$("body").append(sizer);
|
248
241
|
}
|
249
242
|
sizer.text(e.val());
|
250
243
|
return sizer.width();
|
251
244
|
}
|
252
245
|
|
253
|
-
function markMatch(text, term, markup) {
|
246
|
+
function markMatch(text, term, markup, escapeMarkup) {
|
254
247
|
var match=text.toUpperCase().indexOf(term.toUpperCase()),
|
255
248
|
tl=term.length;
|
256
249
|
|
257
250
|
if (match<0) {
|
258
|
-
markup.push(text);
|
251
|
+
markup.push(escapeMarkup(text));
|
259
252
|
return;
|
260
253
|
}
|
261
254
|
|
262
|
-
markup.push(text.substring(0, match));
|
255
|
+
markup.push(escapeMarkup(text.substring(0, match)));
|
263
256
|
markup.push("<span class='select2-match'>");
|
264
|
-
markup.push(text.substring(match, match + tl));
|
257
|
+
markup.push(escapeMarkup(text.substring(match, match + tl)));
|
265
258
|
markup.push("</span>");
|
266
|
-
markup.push(text.substring(match + tl, text.length));
|
259
|
+
markup.push(escapeMarkup(text.substring(match + tl, text.length)));
|
267
260
|
}
|
268
261
|
|
269
262
|
/**
|
@@ -294,16 +287,18 @@
|
|
294
287
|
requestSequence += 1; // increment the sequence
|
295
288
|
var requestNumber = requestSequence, // this request's sequence number
|
296
289
|
data = options.data, // ajax data function
|
290
|
+
url = options.url, // ajax url string or function
|
297
291
|
transport = options.transport || $.ajax,
|
298
292
|
traditional = options.traditional || false,
|
299
293
|
type = options.type || 'GET'; // set type of request (GET or POST)
|
300
294
|
|
301
|
-
data = data.call(this, query.term, query.page, query.context);
|
295
|
+
data = data ? data.call(this, query.term, query.page, query.context) : null;
|
296
|
+
url = (typeof url === 'function') ? url.call(this, query.term, query.page, query.context) : url;
|
302
297
|
|
303
298
|
if( null !== handler) { handler.abort(); }
|
304
299
|
|
305
300
|
handler = transport.call(null, {
|
306
|
-
url:
|
301
|
+
url: url,
|
307
302
|
dataType: options.dataType,
|
308
303
|
data: data,
|
309
304
|
type: type,
|
@@ -367,11 +362,11 @@
|
|
367
362
|
}
|
368
363
|
group.children=[];
|
369
364
|
$(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); });
|
370
|
-
if (group.children.length) {
|
365
|
+
if (group.children.length || query.matcher(t, text(group), datum)) {
|
371
366
|
collection.push(group);
|
372
367
|
}
|
373
368
|
} else {
|
374
|
-
if (query.matcher(t, text(datum))) {
|
369
|
+
if (query.matcher(t, text(datum), datum)) {
|
375
370
|
collection.push(datum);
|
376
371
|
}
|
377
372
|
}
|
@@ -384,17 +379,10 @@
|
|
384
379
|
|
385
380
|
// TODO javadoc
|
386
381
|
function tags(data) {
|
387
|
-
|
388
|
-
// the function for arrays. otherwise only functions that return objects are supported.
|
389
|
-
if ($.isFunction(data)) {
|
390
|
-
return data;
|
391
|
-
}
|
392
|
-
|
393
|
-
// if not a function we assume it to be an array
|
394
|
-
|
382
|
+
var isFunc = $.isFunction(data);
|
395
383
|
return function (query) {
|
396
384
|
var t = query.term, filtered = {results: []};
|
397
|
-
$(data).each(function () {
|
385
|
+
$(isFunc ? data() : data).each(function () {
|
398
386
|
var isObject = this.text !== undefined,
|
399
387
|
text = isObject ? this.text : this;
|
400
388
|
if (t === "" || query.matcher(t, text)) {
|
@@ -485,38 +473,9 @@
|
|
485
473
|
}
|
486
474
|
}
|
487
475
|
|
488
|
-
if (original
|
476
|
+
if (original!==input) return input;
|
489
477
|
}
|
490
478
|
|
491
|
-
/**
|
492
|
-
* blurs any Select2 container that has focus when an element outside them was clicked or received focus
|
493
|
-
*
|
494
|
-
* also takes care of clicks on label tags that point to the source element
|
495
|
-
*/
|
496
|
-
$(document).ready(function () {
|
497
|
-
$(document).delegate("body", "mousedown touchend", function (e) {
|
498
|
-
var target = $(e.target).closest("div.select2-container").get(0), attr;
|
499
|
-
if (target) {
|
500
|
-
$(document).find("div.select2-container-active").each(function () {
|
501
|
-
if (this !== target) $(this).data("select2").blur();
|
502
|
-
});
|
503
|
-
} else {
|
504
|
-
target = $(e.target).closest("div.select2-drop").get(0);
|
505
|
-
$(document).find("div.select2-drop-active").each(function () {
|
506
|
-
if (this !== target) $(this).data("select2").blur();
|
507
|
-
});
|
508
|
-
}
|
509
|
-
|
510
|
-
target=$(e.target);
|
511
|
-
attr = target.attr("for");
|
512
|
-
if ("LABEL" === e.target.tagName && attr && attr.length > 0) {
|
513
|
-
target = $("#"+attr);
|
514
|
-
target = target.data("select2");
|
515
|
-
if (target !== undefined) { target.focus(); e.preventDefault();}
|
516
|
-
}
|
517
|
-
});
|
518
|
-
});
|
519
|
-
|
520
479
|
/**
|
521
480
|
* Creates a new class
|
522
481
|
*
|
@@ -544,7 +503,7 @@
|
|
544
503
|
|
545
504
|
// abstract
|
546
505
|
init: function (opts) {
|
547
|
-
var results, search, resultsSelector = ".select2-results";
|
506
|
+
var results, search, resultsSelector = ".select2-results", mask;
|
548
507
|
|
549
508
|
// prepare options
|
550
509
|
this.opts = opts = this.prepareOpts(opts);
|
@@ -567,6 +526,25 @@
|
|
567
526
|
// cache the body so future lookups are cheap
|
568
527
|
this.body = thunk(function() { return opts.element.closest("body"); });
|
569
528
|
|
529
|
+
// create the dropdown mask if doesnt already exist
|
530
|
+
mask = $("#select2-drop-mask");
|
531
|
+
if (mask.length == 0) {
|
532
|
+
mask = $(document.createElement("div"));
|
533
|
+
mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
|
534
|
+
mask.hide();
|
535
|
+
mask.appendTo(this.body());
|
536
|
+
mask.bind("mousedown touchstart", function (e) {
|
537
|
+
var dropdown = $("#select2-drop"), self;
|
538
|
+
if (dropdown.length > 0) {
|
539
|
+
self=dropdown.data("select2");
|
540
|
+
if (self.opts.selectOnBlur) {
|
541
|
+
self.selectHighlighted({noFocus: true});
|
542
|
+
}
|
543
|
+
self.close();
|
544
|
+
}
|
545
|
+
});
|
546
|
+
}
|
547
|
+
|
570
548
|
if (opts.element.attr("class") !== undefined) {
|
571
549
|
this.container.addClass(opts.element.attr("class").replace(/validate\[[\S ]+] ?/, ''));
|
572
550
|
}
|
@@ -574,10 +552,14 @@
|
|
574
552
|
this.container.css(evaluate(opts.containerCss));
|
575
553
|
this.container.addClass(evaluate(opts.containerCssClass));
|
576
554
|
|
555
|
+
this.elementTabIndex = this.opts.element.attr("tabIndex");
|
556
|
+
|
577
557
|
// swap container for the element
|
578
558
|
this.opts.element
|
579
559
|
.data("select2", this)
|
580
|
-
.
|
560
|
+
.addClass("select2-offscreen")
|
561
|
+
.bind("focus.select2", function() { $(this).select2("focus")})
|
562
|
+
.attr("tabIndex", "-1")
|
581
563
|
.before(this.container);
|
582
564
|
this.container.data("select2", this);
|
583
565
|
|
@@ -588,7 +570,7 @@
|
|
588
570
|
this.results = results = this.container.find(resultsSelector);
|
589
571
|
this.search = search = this.container.find("input.select2-input");
|
590
572
|
|
591
|
-
search.attr("tabIndex", this.
|
573
|
+
search.attr("tabIndex", this.elementTabIndex);
|
592
574
|
|
593
575
|
this.resultsPage = 0;
|
594
576
|
this.context = null;
|
@@ -623,7 +605,7 @@
|
|
623
605
|
search.bind("blur", function () { search.removeClass("select2-focused");});
|
624
606
|
|
625
607
|
this.dropdown.delegate(resultsSelector, "mouseup", this.bind(function (e) {
|
626
|
-
if ($(e.target).closest(".select2-result-selectable
|
608
|
+
if ($(e.target).closest(".select2-result-selectable").length > 0) {
|
627
609
|
this.highlightUnderEvent(e);
|
628
610
|
this.selectHighlighted(e);
|
629
611
|
} else {
|
@@ -652,12 +634,17 @@
|
|
652
634
|
// abstract
|
653
635
|
destroy: function () {
|
654
636
|
var select2 = this.opts.element.data("select2");
|
637
|
+
|
638
|
+
if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
|
639
|
+
|
655
640
|
if (select2 !== undefined) {
|
641
|
+
|
656
642
|
select2.container.remove();
|
657
643
|
select2.dropdown.remove();
|
658
644
|
select2.opts.element
|
659
645
|
.removeData("select2")
|
660
646
|
.unbind(".select2")
|
647
|
+
.attr("tabIndex", this.elementTabIndex)
|
661
648
|
.show();
|
662
649
|
}
|
663
650
|
},
|
@@ -687,26 +674,33 @@
|
|
687
674
|
|
688
675
|
populate=function(results, container, depth) {
|
689
676
|
|
690
|
-
var i, l, result, selectable, compound, node, label, innerContainer, formatted;
|
677
|
+
var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
|
678
|
+
|
679
|
+
results = opts.sortResults(results, container, query);
|
680
|
+
|
691
681
|
for (i = 0, l = results.length; i < l; i = i + 1) {
|
692
682
|
|
693
683
|
result=results[i];
|
694
|
-
|
684
|
+
|
685
|
+
disabled = (result.disabled === true);
|
686
|
+
selectable = (!disabled) && (id(result) !== undefined);
|
687
|
+
|
695
688
|
compound=result.children && result.children.length > 0;
|
696
689
|
|
697
690
|
node=$("<li></li>");
|
698
691
|
node.addClass("select2-results-dept-"+depth);
|
699
692
|
node.addClass("select2-result");
|
700
693
|
node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
|
694
|
+
if (disabled) { node.addClass("select2-disabled"); }
|
701
695
|
if (compound) { node.addClass("select2-result-with-children"); }
|
702
696
|
node.addClass(self.opts.formatResultCssClass(result));
|
703
697
|
|
704
|
-
label=$("
|
698
|
+
label=$(document.createElement("div"));
|
705
699
|
label.addClass("select2-result-label");
|
706
700
|
|
707
|
-
formatted=opts.formatResult(result, label, query);
|
701
|
+
formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup);
|
708
702
|
if (formatted!==undefined) {
|
709
|
-
label.html(
|
703
|
+
label.html(formatted);
|
710
704
|
}
|
711
705
|
|
712
706
|
node.append(label);
|
@@ -733,6 +727,13 @@
|
|
733
727
|
opts.id = function (e) { return e[idKey]; };
|
734
728
|
}
|
735
729
|
|
730
|
+
if ($.isArray(opts.element.data("select2Tags"))) {
|
731
|
+
if ("tags" in opts) {
|
732
|
+
throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
|
733
|
+
}
|
734
|
+
opts.tags=opts.element.attr("data-select2-tags");
|
735
|
+
}
|
736
|
+
|
736
737
|
if (select) {
|
737
738
|
opts.query = this.bind(function (query) {
|
738
739
|
var data = { results: [], more: false },
|
@@ -743,7 +744,7 @@
|
|
743
744
|
var group;
|
744
745
|
if (element.is("option")) {
|
745
746
|
if (query.matcher(term, element.text(), element)) {
|
746
|
-
collection.push({id:element.attr("value"), text:element.text(), element: element.get(), css: element.attr("class")});
|
747
|
+
collection.push({id:element.attr("value"), text:element.text(), element: element.get(), css: element.attr("class"), disabled: equal(element.attr("disabled"), "disabled") });
|
747
748
|
}
|
748
749
|
} else if (element.is("optgroup")) {
|
749
750
|
group={text:element.attr("label"), children:[], element: element.get(), css: element.attr("class")};
|
@@ -773,6 +774,7 @@
|
|
773
774
|
opts.formatResultCssClass = function(data) { return data.css; }
|
774
775
|
} else {
|
775
776
|
if (!("query" in opts)) {
|
777
|
+
|
776
778
|
if ("ajax" in opts) {
|
777
779
|
ajaxUrl = opts.element.data("ajax-url");
|
778
780
|
if (ajaxUrl && ajaxUrl.length > 0) {
|
@@ -783,7 +785,9 @@
|
|
783
785
|
opts.query = local(opts.data);
|
784
786
|
} else if ("tags" in opts) {
|
785
787
|
opts.query = tags(opts.tags);
|
786
|
-
opts.createSearchChoice
|
788
|
+
if (opts.createSearchChoice === undefined) {
|
789
|
+
opts.createSearchChoice = function (term) { return {id: term, text: term}; };
|
790
|
+
}
|
787
791
|
opts.initSelection = function (element, callback) {
|
788
792
|
var data = [];
|
789
793
|
$(splitVal(element.val(), opts.separator)).each(function () {
|
@@ -810,11 +814,39 @@
|
|
810
814
|
*/
|
811
815
|
// abstract
|
812
816
|
monitorSource: function () {
|
813
|
-
this.opts.element
|
817
|
+
var el = this.opts.element, sync;
|
818
|
+
|
819
|
+
el.bind("change.select2", this.bind(function (e) {
|
814
820
|
if (this.opts.element.data("select2-change-triggered") !== true) {
|
815
821
|
this.initSelection();
|
816
822
|
}
|
817
823
|
}));
|
824
|
+
|
825
|
+
sync = this.bind(function () {
|
826
|
+
var enabled = this.opts.element.attr("disabled") !== "disabled";
|
827
|
+
var readonly = this.opts.element.attr("readonly") === "readonly";
|
828
|
+
|
829
|
+
enabled = enabled && !readonly;
|
830
|
+
|
831
|
+
if (this.enabled !== enabled) {
|
832
|
+
if (enabled) {
|
833
|
+
this.enable();
|
834
|
+
} else {
|
835
|
+
this.disable();
|
836
|
+
}
|
837
|
+
}
|
838
|
+
});
|
839
|
+
|
840
|
+
// mozilla and IE
|
841
|
+
el.bind("propertychange.select2 DOMAttrModified.select2", sync);
|
842
|
+
// safari and chrome
|
843
|
+
if (typeof WebKitMutationObserver !== "undefined") {
|
844
|
+
if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
|
845
|
+
this.propertyObserver = new WebKitMutationObserver(function (mutations) {
|
846
|
+
mutations.forEach(sync);
|
847
|
+
});
|
848
|
+
this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false });
|
849
|
+
}
|
818
850
|
},
|
819
851
|
|
820
852
|
/**
|
@@ -840,13 +872,13 @@
|
|
840
872
|
this.opts.element.blur();
|
841
873
|
},
|
842
874
|
|
843
|
-
|
844
875
|
// abstract
|
845
876
|
enable: function() {
|
846
877
|
if (this.enabled) return;
|
847
878
|
|
848
879
|
this.enabled=true;
|
849
880
|
this.container.removeClass("select2-container-disabled");
|
881
|
+
this.opts.element.removeAttr("disabled");
|
850
882
|
},
|
851
883
|
|
852
884
|
// abstract
|
@@ -857,6 +889,7 @@
|
|
857
889
|
|
858
890
|
this.enabled=false;
|
859
891
|
this.container.addClass("select2-container-disabled");
|
892
|
+
this.opts.element.attr("disabled", "disabled");
|
860
893
|
},
|
861
894
|
|
862
895
|
// abstract
|
@@ -867,14 +900,17 @@
|
|
867
900
|
// abstract
|
868
901
|
positionDropdown: function() {
|
869
902
|
var offset = this.container.offset(),
|
870
|
-
height = this.container.outerHeight(),
|
871
|
-
width = this.container.outerWidth(),
|
872
|
-
dropHeight = this.dropdown.outerHeight(),
|
903
|
+
height = this.container.outerHeight(false),
|
904
|
+
width = this.container.outerWidth(false),
|
905
|
+
dropHeight = this.dropdown.outerHeight(false),
|
906
|
+
viewPortRight = $(window).scrollLeft() + document.documentElement.clientWidth,
|
873
907
|
viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight,
|
874
908
|
dropTop = offset.top + height,
|
875
909
|
dropLeft = offset.left,
|
876
910
|
enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
|
877
911
|
enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),
|
912
|
+
dropWidth = this.dropdown.outerWidth(false),
|
913
|
+
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
|
878
914
|
aboveNow = this.dropdown.hasClass("select2-drop-above"),
|
879
915
|
bodyOffset,
|
880
916
|
above,
|
@@ -901,6 +937,10 @@
|
|
901
937
|
if (!enoughRoomBelow && enoughRoomAbove) above = true;
|
902
938
|
}
|
903
939
|
|
940
|
+
if (!enoughRoomOnRight) {
|
941
|
+
dropLeft = offset.left + width - dropWidth;
|
942
|
+
}
|
943
|
+
|
904
944
|
if (above) {
|
905
945
|
dropTop = offset.top - dropHeight;
|
906
946
|
this.container.addClass("select2-drop-above");
|
@@ -959,26 +999,11 @@
|
|
959
999
|
*/
|
960
1000
|
// abstract
|
961
1001
|
opening: function() {
|
962
|
-
var cid = this.containerId,
|
963
|
-
scroll = "scroll." + cid,
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
var s2 = $(selector);
|
968
|
-
if (s2.length == 0) {
|
969
|
-
$(this).unbind(scroll);
|
970
|
-
}
|
971
|
-
s2.select2("close");
|
972
|
-
});
|
973
|
-
});
|
974
|
-
|
975
|
-
$(window).bind(resize, function() {
|
976
|
-
var s2 = $(selector);
|
977
|
-
if (s2.length == 0) {
|
978
|
-
$(window).unbind(resize);
|
979
|
-
}
|
980
|
-
s2.select2("close");
|
981
|
-
});
|
1002
|
+
var cid = this.containerId,
|
1003
|
+
scroll = "scroll." + cid,
|
1004
|
+
resize = "resize."+cid,
|
1005
|
+
orient = "orientationchange."+cid,
|
1006
|
+
mask;
|
982
1007
|
|
983
1008
|
this.clearDropdownAlignmentPreference();
|
984
1009
|
|
@@ -986,19 +1011,46 @@
|
|
986
1011
|
|
987
1012
|
this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
|
988
1013
|
|
989
|
-
this.updateResults(true);
|
990
1014
|
|
991
1015
|
if(this.dropdown[0] !== this.body().children().last()[0]) {
|
992
1016
|
this.dropdown.detach().appendTo(this.body());
|
993
1017
|
}
|
994
1018
|
|
995
|
-
this.
|
1019
|
+
this.updateResults(true);
|
1020
|
+
|
1021
|
+
mask = $("#select2-drop-mask");
|
996
1022
|
|
1023
|
+
// ensure the mask is always right before the dropdown
|
1024
|
+
if (this.dropdown.prev()[0] !== mask[0]) {
|
1025
|
+
this.dropdown.before(mask);
|
1026
|
+
}
|
1027
|
+
|
1028
|
+
// move the global id to the correct dropdown
|
1029
|
+
$("#select2-drop").removeAttr("id");
|
1030
|
+
this.dropdown.attr("id", "select2-drop");
|
1031
|
+
|
1032
|
+
// show the elements
|
1033
|
+
mask.css({
|
1034
|
+
width: document.documentElement.scrollWidth,
|
1035
|
+
height: document.documentElement.scrollHeight});
|
1036
|
+
mask.show();
|
1037
|
+
this.dropdown.show();
|
997
1038
|
this.positionDropdown();
|
998
|
-
this.dropdown.addClass("select2-drop-active");
|
999
1039
|
|
1040
|
+
this.dropdown.addClass("select2-drop-active");
|
1000
1041
|
this.ensureHighlightVisible();
|
1001
1042
|
|
1043
|
+
// attach listeners to events that can change the position of the container and thus require
|
1044
|
+
// the position of the dropdown to be updated as well so it does not come unglued from the container
|
1045
|
+
this.container.parents().add(window).each(function () {
|
1046
|
+
$(this).bind(resize+" "+scroll+" "+orient, function (e) {
|
1047
|
+
$("#select2-drop-mask").css({
|
1048
|
+
width:document.documentElement.scrollWidth,
|
1049
|
+
height:document.documentElement.scrollHeight});
|
1050
|
+
$("#select2-drop").data("select2").positionDropdown();
|
1051
|
+
});
|
1052
|
+
});
|
1053
|
+
|
1002
1054
|
this.focusSearch();
|
1003
1055
|
},
|
1004
1056
|
|
@@ -1006,15 +1058,18 @@
|
|
1006
1058
|
close: function () {
|
1007
1059
|
if (!this.opened()) return;
|
1008
1060
|
|
1009
|
-
var
|
1061
|
+
var cid = this.containerId,
|
1062
|
+
scroll = "scroll." + cid,
|
1063
|
+
resize = "resize."+cid,
|
1064
|
+
orient = "orientationchange."+cid;
|
1010
1065
|
|
1011
|
-
|
1012
|
-
|
1013
|
-
});
|
1014
|
-
$(window).unbind("resize." + this.containerId);
|
1066
|
+
// unbind event listeners
|
1067
|
+
this.container.parents().add(window).each(function () { $(this).unbind(scroll).unbind(resize).unbind(orient); });
|
1015
1068
|
|
1016
1069
|
this.clearDropdownAlignmentPreference();
|
1017
1070
|
|
1071
|
+
$("#select2-drop-mask").hide();
|
1072
|
+
this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id
|
1018
1073
|
this.dropdown.hide();
|
1019
1074
|
this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
|
1020
1075
|
this.results.empty();
|
@@ -1046,41 +1101,47 @@
|
|
1046
1101
|
return;
|
1047
1102
|
}
|
1048
1103
|
|
1049
|
-
children =
|
1104
|
+
children = this.findHighlightableChoices();
|
1050
1105
|
|
1051
1106
|
child = $(children[index]);
|
1052
1107
|
|
1053
|
-
hb = child.offset().top + child.outerHeight();
|
1108
|
+
hb = child.offset().top + child.outerHeight(true);
|
1054
1109
|
|
1055
1110
|
// if this is the last child lets also make sure select2-more-results is visible
|
1056
1111
|
if (index === children.length - 1) {
|
1057
1112
|
more = results.find("li.select2-more-results");
|
1058
1113
|
if (more.length > 0) {
|
1059
|
-
hb = more.offset().top + more.outerHeight();
|
1114
|
+
hb = more.offset().top + more.outerHeight(true);
|
1060
1115
|
}
|
1061
1116
|
}
|
1062
1117
|
|
1063
|
-
rb = results.offset().top + results.outerHeight();
|
1118
|
+
rb = results.offset().top + results.outerHeight(true);
|
1064
1119
|
if (hb > rb) {
|
1065
1120
|
results.scrollTop(results.scrollTop() + (hb - rb));
|
1066
1121
|
}
|
1067
1122
|
y = child.offset().top - results.offset().top;
|
1068
1123
|
|
1069
1124
|
// make sure the top of the element is visible
|
1070
|
-
if (y < 0) {
|
1125
|
+
if (y < 0 && child.css('display') != 'none' ) {
|
1071
1126
|
results.scrollTop(results.scrollTop() + y); // y is negative
|
1072
1127
|
}
|
1073
1128
|
},
|
1074
1129
|
|
1130
|
+
// abstract
|
1131
|
+
findHighlightableChoices: function() {
|
1132
|
+
var h=this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)");
|
1133
|
+
return this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)");
|
1134
|
+
},
|
1135
|
+
|
1075
1136
|
// abstract
|
1076
1137
|
moveHighlight: function (delta) {
|
1077
|
-
var choices = this.
|
1138
|
+
var choices = this.findHighlightableChoices(),
|
1078
1139
|
index = this.highlight();
|
1079
1140
|
|
1080
1141
|
while (index > -1 && index < choices.length) {
|
1081
1142
|
index += delta;
|
1082
1143
|
var choice = $(choices[index]);
|
1083
|
-
if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled")) {
|
1144
|
+
if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) {
|
1084
1145
|
this.highlight(index);
|
1085
1146
|
break;
|
1086
1147
|
}
|
@@ -1089,7 +1150,7 @@
|
|
1089
1150
|
|
1090
1151
|
// abstract
|
1091
1152
|
highlight: function (index) {
|
1092
|
-
var choices = this.
|
1153
|
+
var choices = this.findHighlightableChoices();
|
1093
1154
|
|
1094
1155
|
if (arguments.length === 0) {
|
1095
1156
|
return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
|
@@ -1098,23 +1159,22 @@
|
|
1098
1159
|
if (index >= choices.length) index = choices.length - 1;
|
1099
1160
|
if (index < 0) index = 0;
|
1100
1161
|
|
1101
|
-
|
1162
|
+
this.results.find(".select2-highlighted").removeClass("select2-highlighted");
|
1102
1163
|
|
1103
1164
|
$(choices[index]).addClass("select2-highlighted");
|
1104
1165
|
this.ensureHighlightVisible();
|
1105
|
-
|
1106
1166
|
},
|
1107
1167
|
|
1108
1168
|
// abstract
|
1109
1169
|
countSelectableResults: function() {
|
1110
|
-
return this.
|
1170
|
+
return this.findHighlightableChoices().length;
|
1111
1171
|
},
|
1112
1172
|
|
1113
1173
|
// abstract
|
1114
1174
|
highlightUnderEvent: function (event) {
|
1115
1175
|
var el = $(event.target).closest(".select2-result-selectable");
|
1116
1176
|
if (el.length > 0 && !el.is(".select2-highlighted")) {
|
1117
|
-
var choices = this.
|
1177
|
+
var choices = this.findHighlightableChoices();
|
1118
1178
|
this.highlight(choices.index(el));
|
1119
1179
|
} else if (el.length == 0) {
|
1120
1180
|
// if we are over an unselectable item remove al highlights
|
@@ -1136,7 +1196,7 @@
|
|
1136
1196
|
if (more.length === 0) return;
|
1137
1197
|
below = more.offset().top - results.offset().top - results.height();
|
1138
1198
|
|
1139
|
-
if (below <=
|
1199
|
+
if (below <= this.opts.loadMorePadding) {
|
1140
1200
|
more.addClass("select2-active");
|
1141
1201
|
this.opts.query({
|
1142
1202
|
term: term,
|
@@ -1191,26 +1251,40 @@
|
|
1191
1251
|
}
|
1192
1252
|
|
1193
1253
|
function render(html) {
|
1194
|
-
results.html(
|
1254
|
+
results.html(html);
|
1195
1255
|
postRender();
|
1196
1256
|
}
|
1197
1257
|
|
1198
|
-
|
1258
|
+
var maxSelSize = $.isFunction(opts.maximumSelectionSize) ? opts.maximumSelectionSize() : opts.maximumSelectionSize;
|
1259
|
+
if (maxSelSize >=1) {
|
1199
1260
|
data = this.data();
|
1200
|
-
if ($.isArray(data) && data.length >=
|
1201
|
-
render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(
|
1261
|
+
if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
|
1262
|
+
render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(maxSelSize) + "</li>");
|
1202
1263
|
return;
|
1203
1264
|
}
|
1204
1265
|
}
|
1205
1266
|
|
1206
|
-
if (search.val().length < opts.minimumInputLength
|
1207
|
-
|
1267
|
+
if (search.val().length < opts.minimumInputLength) {
|
1268
|
+
if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
|
1269
|
+
render("<li class='select2-no-results'>" + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "</li>");
|
1270
|
+
} else {
|
1271
|
+
render("");
|
1272
|
+
}
|
1208
1273
|
return;
|
1209
1274
|
}
|
1210
|
-
else {
|
1275
|
+
else if (opts.formatSearching() && initial===true) {
|
1211
1276
|
render("<li class='select2-searching'>" + opts.formatSearching() + "</li>");
|
1212
1277
|
}
|
1213
1278
|
|
1279
|
+
if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
|
1280
|
+
if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
|
1281
|
+
render("<li class='select2-no-results'>" + opts.formatInputTooLong(search.val(), opts.maximumInputLength) + "</li>");
|
1282
|
+
} else {
|
1283
|
+
render("");
|
1284
|
+
}
|
1285
|
+
return;
|
1286
|
+
}
|
1287
|
+
|
1214
1288
|
// give the tokenizer a chance to pre-process the input
|
1215
1289
|
input = this.tokenize();
|
1216
1290
|
if (input != undefined && input != null) {
|
@@ -1271,6 +1345,10 @@
|
|
1271
1345
|
|
1272
1346
|
// abstract
|
1273
1347
|
blur: function () {
|
1348
|
+
// if selectOnBlur == true, select the currently highlighted option
|
1349
|
+
if (this.opts.selectOnBlur)
|
1350
|
+
this.selectHighlighted({noFocus: true});
|
1351
|
+
|
1274
1352
|
this.close();
|
1275
1353
|
this.container.removeClass("select2-container-active");
|
1276
1354
|
this.dropdown.removeClass("select2-drop-active");
|
@@ -1278,6 +1356,7 @@
|
|
1278
1356
|
if (this.search[0] === document.activeElement) { this.search.blur(); }
|
1279
1357
|
this.clearSearch();
|
1280
1358
|
this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
|
1359
|
+
this.opts.element.triggerHandler("blur");
|
1281
1360
|
},
|
1282
1361
|
|
1283
1362
|
// abstract
|
@@ -1297,19 +1376,27 @@
|
|
1297
1376
|
},
|
1298
1377
|
|
1299
1378
|
// abstract
|
1300
|
-
selectHighlighted: function () {
|
1379
|
+
selectHighlighted: function (options) {
|
1301
1380
|
var index=this.highlight(),
|
1302
|
-
highlighted=this.results.find(".select2-highlighted")
|
1303
|
-
data = highlighted.closest('.select2-result
|
1381
|
+
highlighted=this.results.find(".select2-highlighted"),
|
1382
|
+
data = highlighted.closest('.select2-result').data("select2-data");
|
1383
|
+
|
1304
1384
|
if (data) {
|
1305
|
-
highlighted.addClass("select2-disabled");
|
1306
1385
|
this.highlight(index);
|
1307
|
-
this.onSelect(data);
|
1386
|
+
this.onSelect(data, options);
|
1308
1387
|
}
|
1309
1388
|
},
|
1310
1389
|
|
1311
1390
|
// abstract
|
1312
1391
|
getPlaceholder: function () {
|
1392
|
+
|
1393
|
+
// if a placeholder is specified on a select without the first empty option ignore it
|
1394
|
+
if (this.select) {
|
1395
|
+
if (this.select.find("option").first().text() !== "") {
|
1396
|
+
return undefined;
|
1397
|
+
}
|
1398
|
+
}
|
1399
|
+
|
1313
1400
|
return this.opts.element.attr("placeholder") ||
|
1314
1401
|
this.opts.element.attr("data-placeholder") || // jquery 1.4 compat
|
1315
1402
|
this.opts.element.data("placeholder") ||
|
@@ -1330,7 +1417,7 @@
|
|
1330
1417
|
if (this.opts.width === "off") {
|
1331
1418
|
return null;
|
1332
1419
|
} else if (this.opts.width === "element"){
|
1333
|
-
return this.opts.element.outerWidth() === 0 ? 'auto' : this.opts.element.outerWidth() + 'px';
|
1420
|
+
return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
|
1334
1421
|
} else if (this.opts.width === "copy" || this.opts.width === "resolve") {
|
1335
1422
|
// check if there is inline style on the element that contains width
|
1336
1423
|
style = this.opts.element.attr('style');
|
@@ -1351,7 +1438,7 @@
|
|
1351
1438
|
if (style.indexOf("%") > 0) return style;
|
1352
1439
|
|
1353
1440
|
// finally, fallback on the calculated width of the element
|
1354
|
-
return (this.opts.element.outerWidth() === 0 ? 'auto' : this.opts.element.outerWidth() + 'px');
|
1441
|
+
return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
|
1355
1442
|
}
|
1356
1443
|
|
1357
1444
|
return null;
|
@@ -1374,10 +1461,10 @@
|
|
1374
1461
|
// single
|
1375
1462
|
|
1376
1463
|
createContainer: function () {
|
1377
|
-
var container = $("
|
1464
|
+
var container = $(document.createElement("div")).attr({
|
1378
1465
|
"class": "select2-container"
|
1379
1466
|
}).html([
|
1380
|
-
" <a href='
|
1467
|
+
" <a href='javascript:void(0)' onclick='return false;' class='select2-choice'>",
|
1381
1468
|
" <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
|
1382
1469
|
" <div><b></b></div>" ,
|
1383
1470
|
"</a>",
|
@@ -1391,6 +1478,31 @@
|
|
1391
1478
|
return container;
|
1392
1479
|
},
|
1393
1480
|
|
1481
|
+
// single
|
1482
|
+
disable: function() {
|
1483
|
+
if (!this.enabled) return;
|
1484
|
+
|
1485
|
+
this.parent.disable.apply(this, arguments);
|
1486
|
+
|
1487
|
+
this.selection.attr("tabIndex", "-1");
|
1488
|
+
this.search.attr("tabIndex", "-1");
|
1489
|
+
},
|
1490
|
+
|
1491
|
+
// single
|
1492
|
+
enable: function() {
|
1493
|
+
if (this.enabled) return;
|
1494
|
+
|
1495
|
+
this.parent.enable.apply(this, arguments);
|
1496
|
+
|
1497
|
+
if (this.elementTabIndex) {
|
1498
|
+
this.selection.attr("tabIndex", this.elementTabIndex)
|
1499
|
+
} else {
|
1500
|
+
this.selection.removeAttr("tabIndex");
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
this.search.removeAttr("tabIndex");
|
1504
|
+
},
|
1505
|
+
|
1394
1506
|
// single
|
1395
1507
|
opening: function () {
|
1396
1508
|
this.search.show();
|
@@ -1409,6 +1521,7 @@
|
|
1409
1521
|
focus: function () {
|
1410
1522
|
this.close();
|
1411
1523
|
this.selection.focus();
|
1524
|
+
this.opts.element.triggerHandler("focus");
|
1412
1525
|
},
|
1413
1526
|
|
1414
1527
|
// single
|
@@ -1482,7 +1595,24 @@
|
|
1482
1595
|
}));
|
1483
1596
|
this.search.bind("blur", this.bind(function() {
|
1484
1597
|
if (!this.opened()) this.container.removeClass("select2-container-active");
|
1485
|
-
window.setTimeout(this.bind(function() {
|
1598
|
+
window.setTimeout(this.bind(function() {
|
1599
|
+
// restore original tab index
|
1600
|
+
var ti=this.elementTabIndex || 0;
|
1601
|
+
if (ti) {
|
1602
|
+
this.selection.attr("tabIndex", ti);
|
1603
|
+
} else {
|
1604
|
+
this.selection.removeAttr("tabIndex");
|
1605
|
+
}
|
1606
|
+
}), 10);
|
1607
|
+
}));
|
1608
|
+
|
1609
|
+
selection.delegate("abbr", "mousedown", this.bind(function (e) {
|
1610
|
+
if (!this.enabled) return;
|
1611
|
+
this.clear();
|
1612
|
+
killEventImmediately(e);
|
1613
|
+
this.close();
|
1614
|
+
this.triggerChange();
|
1615
|
+
this.selection.focus();
|
1486
1616
|
}));
|
1487
1617
|
|
1488
1618
|
selection.bind("mousedown", this.bind(function (e) {
|
@@ -1501,6 +1631,8 @@
|
|
1501
1631
|
dropdown.bind("mousedown", this.bind(function() { this.search.focus(); }));
|
1502
1632
|
|
1503
1633
|
selection.bind("focus", this.bind(function() {
|
1634
|
+
if (!this.enabled) return;
|
1635
|
+
|
1504
1636
|
this.container.addClass("select2-container-active");
|
1505
1637
|
// hide the search so the tab key does not focus on it
|
1506
1638
|
this.search.attr("tabIndex", "-1");
|
@@ -1510,70 +1642,34 @@
|
|
1510
1642
|
if (!this.opened()) {
|
1511
1643
|
this.container.removeClass("select2-container-active");
|
1512
1644
|
}
|
1513
|
-
window.setTimeout(this.bind(function() { this.search.attr("tabIndex", this.
|
1645
|
+
window.setTimeout(this.bind(function() { this.search.attr("tabIndex", this.elementTabIndex || 0); }), 10);
|
1514
1646
|
}));
|
1515
1647
|
|
1516
1648
|
selection.bind("keydown", this.bind(function(e) {
|
1517
1649
|
if (!this.enabled) return;
|
1518
1650
|
|
1519
|
-
if (e.which
|
1520
|
-
|
1651
|
+
if (e.which == KEY.DOWN || e.which == KEY.UP
|
1652
|
+
|| (e.which == KEY.ENTER && this.opts.openOnEnter)) {
|
1653
|
+
this.open();
|
1521
1654
|
killEvent(e);
|
1522
1655
|
return;
|
1523
1656
|
}
|
1524
1657
|
|
1525
|
-
if (e.which
|
1526
|
-
|| e.which === KEY.ESC) {
|
1527
|
-
return;
|
1528
|
-
}
|
1529
|
-
|
1530
|
-
if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
|
1531
|
-
return;
|
1532
|
-
}
|
1533
|
-
|
1534
|
-
if (e.which == KEY.DELETE) {
|
1658
|
+
if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
|
1535
1659
|
if (this.opts.allowClear) {
|
1536
1660
|
this.clear();
|
1537
1661
|
}
|
1538
|
-
return;
|
1539
|
-
}
|
1540
|
-
|
1541
|
-
this.open();
|
1542
|
-
|
1543
|
-
if (e.which === KEY.ENTER) {
|
1544
|
-
// do not propagate the event otherwise we open, and propagate enter which closes
|
1545
|
-
killEvent(e);
|
1546
|
-
return;
|
1547
|
-
}
|
1548
|
-
|
1549
|
-
// do not set the search input value for non-alpha-numeric keys
|
1550
|
-
// otherwise pressing down results in a '(' being set in the search field
|
1551
|
-
if (e.which < 48 ) { // '0' == 48
|
1552
1662
|
killEvent(e);
|
1553
1663
|
return;
|
1554
1664
|
}
|
1555
|
-
|
1556
|
-
var keyWritten = String.fromCharCode(e.which).toLowerCase();
|
1557
|
-
|
1558
|
-
if (e.shiftKey) {
|
1559
|
-
keyWritten = keyWritten.toUpperCase();
|
1560
|
-
}
|
1561
|
-
|
1562
|
-
// focus the field before calling val so the cursor ends up after the value instead of before
|
1563
|
-
this.search.focus();
|
1564
|
-
this.search.val(keyWritten);
|
1565
|
-
|
1566
|
-
// prevent event propagation so it doesnt replay on the now focussed search field and result in double key entry
|
1567
|
-
killEvent(e);
|
1568
1665
|
}));
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
this.
|
1575
|
-
this.
|
1576
|
-
this.selection.focus();
|
1666
|
+
selection.bind("keypress", this.bind(function(e) {
|
1667
|
+
if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE || e.which == KEY.TAB || e.which == KEY.ENTER || e.which == 0) {
|
1668
|
+
return
|
1669
|
+
}
|
1670
|
+
var key = String.fromCharCode(e.which);
|
1671
|
+
this.search.val(key);
|
1672
|
+
this.open();
|
1577
1673
|
}));
|
1578
1674
|
|
1579
1675
|
this.setPlaceholder();
|
@@ -1597,7 +1693,7 @@
|
|
1597
1693
|
// single
|
1598
1694
|
initSelection: function () {
|
1599
1695
|
var selected;
|
1600
|
-
if (this.opts.element.val() === "") {
|
1696
|
+
if (this.opts.element.val() === "" && this.opts.element.text() === "") {
|
1601
1697
|
this.close();
|
1602
1698
|
this.setPlaceholder();
|
1603
1699
|
} else {
|
@@ -1622,7 +1718,21 @@
|
|
1622
1718
|
var selected = element.find(":selected");
|
1623
1719
|
// a single select box always has a value, no need to null check 'selected'
|
1624
1720
|
if ($.isFunction(callback))
|
1625
|
-
callback({id: selected.attr("value"), text: selected.text()});
|
1721
|
+
callback({id: selected.attr("value"), text: selected.text(), element:selected});
|
1722
|
+
};
|
1723
|
+
} else if ("data" in opts) {
|
1724
|
+
// install default initSelection when applied to hidden input and data is local
|
1725
|
+
opts.initSelection = opts.initSelection || function (element, callback) {
|
1726
|
+
var id = element.val();
|
1727
|
+
//search in data by id
|
1728
|
+
opts.query({
|
1729
|
+
matcher: function(term, text, el){
|
1730
|
+
return equal(id, opts.id(el));
|
1731
|
+
},
|
1732
|
+
callback: !$.isFunction(callback) ? $.noop : function(filtered) {
|
1733
|
+
callback(filtered.results.length ? filtered.results[0] : null);
|
1734
|
+
}
|
1735
|
+
});
|
1626
1736
|
};
|
1627
1737
|
}
|
1628
1738
|
|
@@ -1652,7 +1762,7 @@
|
|
1652
1762
|
|
1653
1763
|
// find the selected element in the result list
|
1654
1764
|
|
1655
|
-
this.
|
1765
|
+
this.findHighlightableChoices().each2(function (i, elm) {
|
1656
1766
|
if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
|
1657
1767
|
selected = i;
|
1658
1768
|
return false;
|
@@ -1676,13 +1786,15 @@
|
|
1676
1786
|
},
|
1677
1787
|
|
1678
1788
|
// single
|
1679
|
-
onSelect: function (data) {
|
1789
|
+
onSelect: function (data, options) {
|
1680
1790
|
var old = this.opts.element.val();
|
1681
1791
|
|
1682
1792
|
this.opts.element.val(this.id(data));
|
1683
1793
|
this.updateSelection(data);
|
1684
1794
|
this.close();
|
1685
|
-
|
1795
|
+
|
1796
|
+
if (!options || !options.noFocus)
|
1797
|
+
this.selection.focus();
|
1686
1798
|
|
1687
1799
|
if (!equal(old, this.id(data))) { this.triggerChange(); }
|
1688
1800
|
},
|
@@ -1709,7 +1821,7 @@
|
|
1709
1821
|
|
1710
1822
|
// single
|
1711
1823
|
val: function () {
|
1712
|
-
var val, data = null, self = this;
|
1824
|
+
var val, triggerChange = false, data = null, self = this;
|
1713
1825
|
|
1714
1826
|
if (arguments.length === 0) {
|
1715
1827
|
return this.opts.element.val();
|
@@ -1717,6 +1829,10 @@
|
|
1717
1829
|
|
1718
1830
|
val = arguments[0];
|
1719
1831
|
|
1832
|
+
if (arguments.length > 1) {
|
1833
|
+
triggerChange = arguments[1];
|
1834
|
+
}
|
1835
|
+
|
1720
1836
|
if (this.select) {
|
1721
1837
|
this.select
|
1722
1838
|
.val(val)
|
@@ -1726,13 +1842,19 @@
|
|
1726
1842
|
});
|
1727
1843
|
this.updateSelection(data);
|
1728
1844
|
this.setPlaceholder();
|
1845
|
+
if (triggerChange) {
|
1846
|
+
this.triggerChange();
|
1847
|
+
}
|
1729
1848
|
} else {
|
1730
1849
|
if (this.opts.initSelection === undefined) {
|
1731
1850
|
throw new Error("cannot call val() if initSelection() is not defined");
|
1732
1851
|
}
|
1733
|
-
// val is an id. !val is true for [undefined,null,'']
|
1734
|
-
if (!val) {
|
1852
|
+
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
|
1853
|
+
if (!val && val !== 0) {
|
1735
1854
|
this.clear();
|
1855
|
+
if (triggerChange) {
|
1856
|
+
this.triggerChange();
|
1857
|
+
}
|
1736
1858
|
return;
|
1737
1859
|
}
|
1738
1860
|
this.opts.element.val(val);
|
@@ -1740,6 +1862,7 @@
|
|
1740
1862
|
self.opts.element.val(!data ? "" : self.id(data));
|
1741
1863
|
self.updateSelection(data);
|
1742
1864
|
self.setPlaceholder();
|
1865
|
+
self.triggerChange();
|
1743
1866
|
});
|
1744
1867
|
}
|
1745
1868
|
},
|
@@ -1772,7 +1895,7 @@
|
|
1772
1895
|
|
1773
1896
|
// multi
|
1774
1897
|
createContainer: function () {
|
1775
|
-
var container = $("
|
1898
|
+
var container = $(document.createElement("div")).attr({
|
1776
1899
|
"class": "select2-container select2-container-multi"
|
1777
1900
|
}).html([
|
1778
1901
|
" <ul class='select2-choices'>",
|
@@ -1800,12 +1923,28 @@
|
|
1800
1923
|
|
1801
1924
|
var data = [];
|
1802
1925
|
element.find(":selected").each2(function (i, elm) {
|
1803
|
-
data.push({id: elm.attr("value"), text: elm.text()});
|
1926
|
+
data.push({id: elm.attr("value"), text: elm.text(), element: elm});
|
1804
1927
|
});
|
1805
1928
|
|
1806
1929
|
if ($.isFunction(callback))
|
1807
1930
|
callback(data);
|
1808
1931
|
};
|
1932
|
+
} else if ("data" in opts) {
|
1933
|
+
// install default initSelection when applied to hidden input and data is local
|
1934
|
+
opts.initSelection = opts.initSelection || function (element, callback) {
|
1935
|
+
var ids = splitVal(element.val(), opts.separator);
|
1936
|
+
//search in data by array of ids
|
1937
|
+
opts.query({
|
1938
|
+
matcher: function(term, text, el){
|
1939
|
+
return $.grep(ids, function(id) {
|
1940
|
+
return equal(id, opts.id(el));
|
1941
|
+
}).length;
|
1942
|
+
},
|
1943
|
+
callback: !$.isFunction(callback) ? $.noop : function(filtered) {
|
1944
|
+
callback(filtered.results);
|
1945
|
+
}
|
1946
|
+
});
|
1947
|
+
};
|
1809
1948
|
}
|
1810
1949
|
|
1811
1950
|
return opts;
|
@@ -1834,7 +1973,7 @@
|
|
1834
1973
|
return;
|
1835
1974
|
}
|
1836
1975
|
|
1837
|
-
choices = selection.find(".select2-search-choice");
|
1976
|
+
choices = selection.find(".select2-search-choice:not(.select2-locked)");
|
1838
1977
|
if (choices.length > 0) {
|
1839
1978
|
choices.last().addClass("select2-search-choice-focus");
|
1840
1979
|
}
|
@@ -1883,7 +2022,7 @@
|
|
1883
2022
|
this.search.bind("blur", this.bind(function(e) {
|
1884
2023
|
this.container.removeClass("select2-container-active");
|
1885
2024
|
this.search.removeClass("select2-focused");
|
1886
|
-
this.clearSearch();
|
2025
|
+
if (!this.opened()) this.clearSearch();
|
1887
2026
|
e.stopImmediatePropagation();
|
1888
2027
|
}));
|
1889
2028
|
|
@@ -1931,7 +2070,7 @@
|
|
1931
2070
|
// multi
|
1932
2071
|
initSelection: function () {
|
1933
2072
|
var data;
|
1934
|
-
if (this.opts.element.val() === "") {
|
2073
|
+
if (this.opts.element.val() === "" && this.opts.element.text() === "") {
|
1935
2074
|
this.updateSelection([]);
|
1936
2075
|
this.close();
|
1937
2076
|
// set the placeholder if necessary
|
@@ -1994,6 +2133,7 @@
|
|
1994
2133
|
focus: function () {
|
1995
2134
|
this.close();
|
1996
2135
|
this.search.focus();
|
2136
|
+
this.opts.element.triggerHandler("focus");
|
1997
2137
|
},
|
1998
2138
|
|
1999
2139
|
// multi
|
@@ -2034,9 +2174,9 @@
|
|
2034
2174
|
},
|
2035
2175
|
|
2036
2176
|
// multi
|
2037
|
-
onSelect: function (data) {
|
2177
|
+
onSelect: function (data, options) {
|
2038
2178
|
this.addSelectedChoice(data);
|
2039
|
-
if (this.select
|
2179
|
+
if (this.select || !this.opts.closeOnSelect) this.postprocessResults();
|
2040
2180
|
|
2041
2181
|
if (this.opts.closeOnSelect) {
|
2042
2182
|
this.close();
|
@@ -2056,7 +2196,8 @@
|
|
2056
2196
|
// added we do not need to check if this is a new element before firing change
|
2057
2197
|
this.triggerChange({ added: data });
|
2058
2198
|
|
2059
|
-
|
2199
|
+
if (!options || !options.noFocus)
|
2200
|
+
this.focusSearch();
|
2060
2201
|
},
|
2061
2202
|
|
2062
2203
|
// multi
|
@@ -2065,36 +2206,46 @@
|
|
2065
2206
|
this.focusSearch();
|
2066
2207
|
},
|
2067
2208
|
|
2068
|
-
// multi
|
2069
2209
|
addSelectedChoice: function (data) {
|
2070
|
-
var
|
2210
|
+
var enableChoice = !data.locked,
|
2211
|
+
enabledItem = $(
|
2071
2212
|
"<li class='select2-search-choice'>" +
|
2072
2213
|
" <div></div>" +
|
2073
2214
|
" <a href='#' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a>" +
|
2074
2215
|
"</li>"),
|
2216
|
+
disabledItem = $(
|
2217
|
+
"<li class='select2-search-choice select2-locked'>" +
|
2218
|
+
"<div></div>" +
|
2219
|
+
"</li>");
|
2220
|
+
var choice = enableChoice ? enabledItem : disabledItem,
|
2075
2221
|
id = this.id(data),
|
2076
2222
|
val = this.getVal(),
|
2077
2223
|
formatted;
|
2078
2224
|
|
2079
|
-
formatted=this.opts.formatSelection(data, choice);
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
.bind("click dblclick", this.bind(function (e) {
|
2084
|
-
if (!this.enabled) return;
|
2225
|
+
formatted=this.opts.formatSelection(data, choice.find("div"));
|
2226
|
+
if (formatted != undefined) {
|
2227
|
+
choice.find("div").replaceWith("<div>"+this.opts.escapeMarkup(formatted)+"</div>");
|
2228
|
+
}
|
2085
2229
|
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2230
|
+
if(enableChoice){
|
2231
|
+
choice.find(".select2-search-choice-close")
|
2232
|
+
.bind("mousedown", killEvent)
|
2233
|
+
.bind("click dblclick", this.bind(function (e) {
|
2234
|
+
if (!this.enabled) return;
|
2235
|
+
|
2236
|
+
$(e.target).closest(".select2-search-choice").fadeOut('fast', this.bind(function(){
|
2237
|
+
this.unselect($(e.target));
|
2238
|
+
this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
|
2239
|
+
this.close();
|
2240
|
+
this.focusSearch();
|
2241
|
+
})).dequeue();
|
2242
|
+
killEvent(e);
|
2243
|
+
})).bind("focus", this.bind(function () {
|
2244
|
+
if (!this.enabled) return;
|
2245
|
+
this.container.addClass("select2-container-active");
|
2246
|
+
this.dropdown.addClass("select2-drop-active");
|
2247
|
+
}));
|
2248
|
+
}
|
2098
2249
|
|
2099
2250
|
choice.data("select2-data", data);
|
2100
2251
|
choice.insertBefore(this.searchContainer);
|
@@ -2117,6 +2268,12 @@
|
|
2117
2268
|
|
2118
2269
|
data = selected.data("select2-data");
|
2119
2270
|
|
2271
|
+
if (!data) {
|
2272
|
+
// prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued
|
2273
|
+
// and invoked on an element already removed
|
2274
|
+
return;
|
2275
|
+
}
|
2276
|
+
|
2120
2277
|
index = indexOf(this.id(data), val);
|
2121
2278
|
|
2122
2279
|
if (index >= 0) {
|
@@ -2131,33 +2288,30 @@
|
|
2131
2288
|
// multi
|
2132
2289
|
postprocessResults: function () {
|
2133
2290
|
var val = this.getVal(),
|
2134
|
-
choices = this.results.find(".select2-result
|
2291
|
+
choices = this.results.find(".select2-result"),
|
2135
2292
|
compound = this.results.find(".select2-result-with-children"),
|
2136
2293
|
self = this;
|
2137
2294
|
|
2138
2295
|
choices.each2(function (i, choice) {
|
2139
2296
|
var id = self.id(choice.data("select2-data"));
|
2140
2297
|
if (indexOf(id, val) >= 0) {
|
2141
|
-
choice.addClass("select2-
|
2142
|
-
|
2143
|
-
choice.
|
2298
|
+
choice.addClass("select2-selected");
|
2299
|
+
// mark all children of the selected parent as selected
|
2300
|
+
choice.find(".select2-result-selectable").addClass("select2-selected");
|
2144
2301
|
}
|
2145
2302
|
});
|
2146
2303
|
|
2147
|
-
compound.each2(function(i,
|
2148
|
-
if
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2304
|
+
compound.each2(function(i, choice) {
|
2305
|
+
// hide an optgroup if it doesnt have any selectable children
|
2306
|
+
if (!choice.is('.select2-result-selectable')
|
2307
|
+
&& choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
|
2308
|
+
choice.addClass("select2-selected");
|
2152
2309
|
}
|
2153
2310
|
});
|
2154
2311
|
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2158
|
-
return false;
|
2159
|
-
}
|
2160
|
-
});
|
2312
|
+
if (this.highlight() == -1){
|
2313
|
+
self.highlight(0);
|
2314
|
+
}
|
2161
2315
|
|
2162
2316
|
},
|
2163
2317
|
|
@@ -2182,6 +2336,11 @@
|
|
2182
2336
|
if (searchWidth < 40) {
|
2183
2337
|
searchWidth = maxWidth - sideBorderPadding;
|
2184
2338
|
}
|
2339
|
+
|
2340
|
+
if (searchWidth <= 0) {
|
2341
|
+
searchWidth = minimumWidth
|
2342
|
+
}
|
2343
|
+
|
2185
2344
|
this.search.width(searchWidth);
|
2186
2345
|
},
|
2187
2346
|
|
@@ -2214,7 +2373,7 @@
|
|
2214
2373
|
|
2215
2374
|
// multi
|
2216
2375
|
val: function () {
|
2217
|
-
var val, data = [], self=this;
|
2376
|
+
var val, triggerChange = false, data = [], self=this;
|
2218
2377
|
|
2219
2378
|
if (arguments.length === 0) {
|
2220
2379
|
return this.getVal();
|
@@ -2222,10 +2381,18 @@
|
|
2222
2381
|
|
2223
2382
|
val = arguments[0];
|
2224
2383
|
|
2225
|
-
if (
|
2384
|
+
if (arguments.length > 1) {
|
2385
|
+
triggerChange = arguments[1];
|
2386
|
+
}
|
2387
|
+
|
2388
|
+
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
|
2389
|
+
if (!val && val !== 0) {
|
2226
2390
|
this.opts.element.val("");
|
2227
2391
|
this.updateSelection([]);
|
2228
2392
|
this.clearSearch();
|
2393
|
+
if (triggerChange) {
|
2394
|
+
this.triggerChange();
|
2395
|
+
}
|
2229
2396
|
return;
|
2230
2397
|
}
|
2231
2398
|
|
@@ -2237,6 +2404,9 @@
|
|
2237
2404
|
data.push({id: $(this).attr("value"), text: $(this).text()});
|
2238
2405
|
});
|
2239
2406
|
this.updateSelection(data);
|
2407
|
+
if (triggerChange) {
|
2408
|
+
this.triggerChange();
|
2409
|
+
}
|
2240
2410
|
} else {
|
2241
2411
|
if (this.opts.initSelection === undefined) {
|
2242
2412
|
throw new Error("val() cannot be called if initSelection() is not defined")
|
@@ -2247,6 +2417,9 @@
|
|
2247
2417
|
self.setVal(ids);
|
2248
2418
|
self.updateSelection(data);
|
2249
2419
|
self.clearSearch();
|
2420
|
+
if (triggerChange) {
|
2421
|
+
self.triggerChange();
|
2422
|
+
}
|
2250
2423
|
});
|
2251
2424
|
}
|
2252
2425
|
this.clearSearch();
|
@@ -2349,28 +2522,34 @@
|
|
2349
2522
|
// plugin defaults, accessible to users
|
2350
2523
|
$.fn.select2.defaults = {
|
2351
2524
|
width: "copy",
|
2525
|
+
loadMorePadding: 0,
|
2352
2526
|
closeOnSelect: true,
|
2353
2527
|
openOnEnter: true,
|
2354
2528
|
containerCss: {},
|
2355
2529
|
dropdownCss: {},
|
2356
2530
|
containerCssClass: "",
|
2357
2531
|
dropdownCssClass: "",
|
2358
|
-
formatResult: function(result, container, query) {
|
2532
|
+
formatResult: function(result, container, query, escapeMarkup) {
|
2359
2533
|
var markup=[];
|
2360
|
-
markMatch(result.text, query.term, markup);
|
2534
|
+
markMatch(result.text, query.term, markup, escapeMarkup);
|
2361
2535
|
return markup.join("");
|
2362
2536
|
},
|
2363
2537
|
formatSelection: function (data, container) {
|
2364
2538
|
return data ? data.text : undefined;
|
2365
2539
|
},
|
2540
|
+
sortResults: function (results, container, query) {
|
2541
|
+
return results;
|
2542
|
+
},
|
2366
2543
|
formatResultCssClass: function(data) {return undefined;},
|
2367
2544
|
formatNoMatches: function () { return "No matches found"; },
|
2368
|
-
formatInputTooShort: function (input, min) { return "Please enter " +
|
2545
|
+
formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " more character" + (n == 1? "" : "s"); },
|
2546
|
+
formatInputTooLong: function (input, max) { var n = input.length - max; return "Please enter " + n + " less character" + (n == 1? "" : "s"); },
|
2369
2547
|
formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
|
2370
2548
|
formatLoadMore: function (pageNumber) { return "Loading more results..."; },
|
2371
2549
|
formatSearching: function () { return "Searching..."; },
|
2372
2550
|
minimumResultsForSearch: 0,
|
2373
2551
|
minimumInputLength: 0,
|
2552
|
+
maximumInputLength: null,
|
2374
2553
|
maximumSelectionSize: 0,
|
2375
2554
|
id: function (e) { return e.id; },
|
2376
2555
|
matcher: function(term, text) {
|
@@ -2380,12 +2559,22 @@
|
|
2380
2559
|
tokenSeparators: [],
|
2381
2560
|
tokenizer: defaultTokenizer,
|
2382
2561
|
escapeMarkup: function (markup) {
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2562
|
+
var replace_map = {
|
2563
|
+
'\\': '\',
|
2564
|
+
'&': '&',
|
2565
|
+
'<': '<',
|
2566
|
+
'>': '>',
|
2567
|
+
'"': '"',
|
2568
|
+
"'": ''',
|
2569
|
+
"/": '/'
|
2570
|
+
};
|
2571
|
+
|
2572
|
+
return String(markup).replace(/[&<>"'/\\]/g, function (match) {
|
2573
|
+
return replace_map[match[0]];
|
2574
|
+
});
|
2387
2575
|
},
|
2388
|
-
blurOnChange: false
|
2576
|
+
blurOnChange: false,
|
2577
|
+
selectOnBlur: false
|
2389
2578
|
};
|
2390
2579
|
|
2391
2580
|
// exports
|