select2-rails 3.3.0 → 3.3.1

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 CHANGED
@@ -26,7 +26,7 @@ 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.2`.
29
+ From `v2.1.0` on, `select2-rails`'s version will match the version of `Select2` it uses.
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
 
File without changes
File without changes
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  Copyright 2012 Igor Vaynberg
3
3
 
4
- Version: 3.3.0 Timestamp: Tue Feb 5 18:33:54 PST 2013
4
+ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 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
@@ -103,7 +103,9 @@ the specific language governing permissions and limitations under the Apache Lic
103
103
 
104
104
  function indexOf(value, array) {
105
105
  var i = 0, l = array.length;
106
- for (; i < l; i = i + 1) if (value === array[i]) return i;
106
+ for (; i < l; i = i + 1) {
107
+ if (equal(value, array[i])) return i;
108
+ }
107
109
  return -1;
108
110
  }
109
111
 
@@ -113,7 +115,12 @@ the specific language governing permissions and limitations under the Apache Lic
113
115
  * @param b
114
116
  */
115
117
  function equal(a, b) {
116
- return a===b;
118
+ if (a === b) return true;
119
+ if (a === undefined || b === undefined) return false;
120
+ if (a === null || b === null) return false;
121
+ if (a.constructor === String) return a === b+'';
122
+ if (b.constructor === String) return b === a+'';
123
+ return false;
117
124
  }
118
125
 
119
126
  /**
@@ -211,6 +218,34 @@ the specific language governing permissions and limitations under the Apache Lic
211
218
  });
212
219
  }
213
220
 
221
+ function focus($el) {
222
+ if ($el[0] === document.activeElement) return;
223
+
224
+ /* set the focus in a 0 timeout - that way the focus is set after the processing
225
+ of the current event has finished - which seems like the only reliable way
226
+ to set focus */
227
+ window.setTimeout(function() {
228
+ var el=$el[0], pos=$el.val().length, range;
229
+
230
+ $el.focus();
231
+
232
+ /* after the focus is set move the caret to the end, necessary when we val()
233
+ just before setting focus */
234
+ if(el.setSelectionRange)
235
+ {
236
+ el.setSelectionRange(pos, pos);
237
+ }
238
+ else if (el.createTextRange) {
239
+ range = el.createTextRange();
240
+ range.collapse(true);
241
+ range.moveEnd('character', pos);
242
+ range.moveStart('character', pos);
243
+ range.select();
244
+ }
245
+
246
+ }, 0);
247
+ }
248
+
214
249
  function killEvent(event) {
215
250
  event.preventDefault();
216
251
  event.stopPropagation();
@@ -243,6 +278,32 @@ the specific language governing permissions and limitations under the Apache Lic
243
278
  return sizer.width();
244
279
  }
245
280
 
281
+ function syncCssClasses(dest, src, adapter) {
282
+ var classes, replacements = [], adapted;
283
+
284
+ classes = dest.attr("class");
285
+ if (typeof classes === "string") {
286
+ $(classes.split(" ")).each2(function() {
287
+ if (this.indexOf("select2-") === 0) {
288
+ replacements.push(this);
289
+ }
290
+ });
291
+ }
292
+ classes = src.attr("class");
293
+ if (typeof classes === "string") {
294
+ $(classes.split(" ")).each2(function() {
295
+ if (this.indexOf("select2-") !== 0) {
296
+ adapted = adapter(this);
297
+ if (typeof adapted === "string" && adapted.length > 0) {
298
+ replacements.push(this);
299
+ }
300
+ }
301
+ });
302
+ }
303
+ dest.attr("class", replacements.join(" "));
304
+ }
305
+
306
+
246
307
  function markMatch(text, term, markup, escapeMarkup) {
247
308
  var match=text.toUpperCase().indexOf(term.toUpperCase()),
248
309
  tl=term.length;
@@ -279,7 +340,9 @@ the specific language governing permissions and limitations under the Apache Lic
279
340
  var timeout, // current scheduled but not yet executed request
280
341
  requestSequence = 0, // sequence used to drop out-of-order responses
281
342
  handler = null,
282
- quietMillis = options.quietMillis || 100;
343
+ quietMillis = options.quietMillis || 100,
344
+ ajaxUrl = options.url,
345
+ self = this;
283
346
 
284
347
  return function (query) {
285
348
  window.clearTimeout(timeout);
@@ -287,31 +350,40 @@ the specific language governing permissions and limitations under the Apache Lic
287
350
  requestSequence += 1; // increment the sequence
288
351
  var requestNumber = requestSequence, // this request's sequence number
289
352
  data = options.data, // ajax data function
290
- url = options.url, // ajax url string or function
353
+ url = ajaxUrl, // ajax url string or function
291
354
  transport = options.transport || $.ajax,
292
- traditional = options.traditional || false,
293
- type = options.type || 'GET'; // set type of request (GET or POST)
355
+ type = options.type || 'GET', // set type of request (GET or POST)
356
+ params = {};
294
357
 
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;
358
+ data = data ? data.call(self, query.term, query.page, query.context) : null;
359
+ url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
297
360
 
298
361
  if( null !== handler) { handler.abort(); }
299
362
 
300
- handler = transport.call(null, {
363
+ if (options.params) {
364
+ if ($.isFunction(options.params)) {
365
+ $.extend(params, options.params.call(self));
366
+ } else {
367
+ $.extend(params, options.params);
368
+ }
369
+ }
370
+
371
+ $.extend(params, {
301
372
  url: url,
302
373
  dataType: options.dataType,
303
374
  data: data,
304
375
  type: type,
305
- traditional: traditional,
376
+ cache: false,
306
377
  success: function (data) {
307
378
  if (requestNumber < requestSequence) {
308
379
  return;
309
380
  }
310
- // TODO 3.0 - replace query.page with query so users have access to term, page, etc.
381
+ // TODO - replace query.page with query so users have access to term, page, etc.
311
382
  var results = options.results(data, query.page);
312
383
  query.callback(results);
313
384
  }
314
385
  });
386
+ handler = transport.call(self, params);
315
387
  }, quietMillis);
316
388
  };
317
389
  }
@@ -333,22 +405,33 @@ the specific language governing permissions and limitations under the Apache Lic
333
405
  function local(options) {
334
406
  var data = options, // data elements
335
407
  dataText,
408
+ tmp,
336
409
  text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search
337
410
 
338
- if (!$.isArray(data)) {
339
- text = data.text;
411
+ if ($.isArray(data)) {
412
+ tmp = data;
413
+ data = { results: tmp };
414
+ }
415
+
416
+ if ($.isFunction(data) === false) {
417
+ tmp = data;
418
+ data = function() { return tmp; };
419
+ }
420
+
421
+ var dataItem = data();
422
+ if (dataItem.text) {
423
+ text = dataItem.text;
340
424
  // if text is not a function we assume it to be a key name
341
425
  if (!$.isFunction(text)) {
342
- dataText = data.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
343
- text = function (item) { return item[dataText]; };
426
+ dataText = data.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
427
+ text = function (item) { return item[dataText]; };
344
428
  }
345
- data = data.results;
346
429
  }
347
430
 
348
431
  return function (query) {
349
432
  var t = query.term, filtered = { results: [] }, process;
350
433
  if (t === "") {
351
- query.callback({results: data});
434
+ query.callback(data());
352
435
  return;
353
436
  }
354
437
 
@@ -372,7 +455,7 @@ the specific language governing permissions and limitations under the Apache Lic
372
455
  }
373
456
  };
374
457
 
375
- $(data).each2(function(i, datum) { process(datum, filtered.results); });
458
+ $(data().results).each2(function(i, datum) { process(datum, filtered.results); });
376
459
  query.callback(filtered);
377
460
  };
378
461
  }
@@ -526,28 +609,7 @@ the specific language governing permissions and limitations under the Apache Lic
526
609
  // cache the body so future lookups are cheap
527
610
  this.body = thunk(function() { return opts.element.closest("body"); });
528
611
 
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
-
548
- if (opts.element.attr("class") !== undefined) {
549
- this.container.addClass(opts.element.attr("class").replace(/validate\[[\S ]+] ?/, ''));
550
- }
612
+ syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
551
613
 
552
614
  this.container.css(evaluate(opts.containerCss));
553
615
  this.container.addClass(evaluate(opts.containerCssClass));
@@ -558,7 +620,7 @@ the specific language governing permissions and limitations under the Apache Lic
558
620
  this.opts.element
559
621
  .data("select2", this)
560
622
  .addClass("select2-offscreen")
561
- .bind("focus.select2", function() { $(this).select2("focus")})
623
+ .bind("focus.select2", function() { $(this).select2("focus"); })
562
624
  .attr("tabIndex", "-1")
563
625
  .before(this.container);
564
626
  this.container.data("select2", this);
@@ -577,10 +639,9 @@ the specific language governing permissions and limitations under the Apache Lic
577
639
 
578
640
  // initialize the container
579
641
  this.initContainer();
580
- this.initContainerWidth();
581
642
 
582
643
  installFilteredMouseMove(this.results);
583
- this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
644
+ this.dropdown.delegate(resultsSelector, "mousemove-filtered touchstart touchmove touchend", this.bind(this.highlightUnderEvent));
584
645
 
585
646
  installDebouncedScroll(80, this.results);
586
647
  this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
@@ -600,18 +661,15 @@ the specific language governing permissions and limitations under the Apache Lic
600
661
  }
601
662
 
602
663
  installKeyUpChangeEvent(search);
603
- search.bind("keyup-change", this.bind(this.updateResults));
604
- search.bind("focus", function () { search.addClass("select2-focused"); if (search.val() === " ") search.val(""); });
664
+ search.bind("keyup-change input paste", this.bind(this.updateResults));
665
+ search.bind("focus", function () { search.addClass("select2-focused"); });
605
666
  search.bind("blur", function () { search.removeClass("select2-focused");});
606
667
 
607
668
  this.dropdown.delegate(resultsSelector, "mouseup", this.bind(function (e) {
608
669
  if ($(e.target).closest(".select2-result-selectable").length > 0) {
609
670
  this.highlightUnderEvent(e);
610
671
  this.selectHighlighted(e);
611
- } else {
612
- this.focusSearch();
613
672
  }
614
- killEvent(e);
615
673
  }));
616
674
 
617
675
  // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
@@ -642,9 +700,10 @@ the specific language governing permissions and limitations under the Apache Lic
642
700
  select2.container.remove();
643
701
  select2.dropdown.remove();
644
702
  select2.opts.element
703
+ .removeClass("select2-offscreen")
645
704
  .removeData("select2")
646
705
  .unbind(".select2")
647
- .attr("tabIndex", this.elementTabIndex)
706
+ .attr({"tabIndex": this.elementTabIndex})
648
707
  .show();
649
708
  }
650
709
  },
@@ -771,7 +830,7 @@ the specific language governing permissions and limitations under the Apache Lic
771
830
  });
772
831
  // this is needed because inside val() we construct choices from options and there id is hardcoded
773
832
  opts.id=function(e) { return e.id; };
774
- opts.formatResultCssClass = function(data) { return data.css; }
833
+ opts.formatResultCssClass = function(data) { return data.css; };
775
834
  } else {
776
835
  if (!("query" in opts)) {
777
836
 
@@ -780,7 +839,7 @@ the specific language governing permissions and limitations under the Apache Lic
780
839
  if (ajaxUrl && ajaxUrl.length > 0) {
781
840
  opts.ajax.url = ajaxUrl;
782
841
  }
783
- opts.query = ajax(opts.ajax);
842
+ opts.query = ajax.call(opts.element, opts.ajax);
784
843
  } else if ("data" in opts) {
785
844
  opts.query = local(opts.data);
786
845
  } else if ("tags" in opts) {
@@ -788,17 +847,19 @@ the specific language governing permissions and limitations under the Apache Lic
788
847
  if (opts.createSearchChoice === undefined) {
789
848
  opts.createSearchChoice = function (term) { return {id: term, text: term}; };
790
849
  }
791
- opts.initSelection = function (element, callback) {
792
- var data = [];
793
- $(splitVal(element.val(), opts.separator)).each(function () {
794
- var id = this, text = this, tags=opts.tags;
795
- if ($.isFunction(tags)) tags=tags();
796
- $(tags).each(function() { if (equal(this.id, id)) { text = this.text; return false; } });
797
- data.push({id: id, text: text});
798
- });
799
-
800
- callback(data);
801
- };
850
+ if (opts.initSelection === undefined) {
851
+ opts.initSelection = function (element, callback) {
852
+ var data = [];
853
+ $(splitVal(element.val(), opts.separator)).each(function () {
854
+ var id = this, text = this, tags=opts.tags;
855
+ if ($.isFunction(tags)) tags=tags();
856
+ $(tags).each(function() { if (equal(this.id, id)) { text = this.text; return false; } });
857
+ data.push({id: id, text: text});
858
+ });
859
+
860
+ callback(data);
861
+ };
862
+ }
802
863
  }
803
864
  }
804
865
  }
@@ -823,8 +884,13 @@ the specific language governing permissions and limitations under the Apache Lic
823
884
  }));
824
885
 
825
886
  sync = this.bind(function () {
826
- var enabled = this.opts.element.attr("disabled") !== "disabled";
827
- var readonly = this.opts.element.attr("readonly") === "readonly";
887
+
888
+ var enabled, readonly, self = this;
889
+
890
+ // sync enabled state
891
+
892
+ enabled = this.opts.element.attr("disabled") !== "disabled";
893
+ readonly = this.opts.element.attr("readonly") === "readonly";
828
894
 
829
895
  enabled = enabled && !readonly;
830
896
 
@@ -835,6 +901,14 @@ the specific language governing permissions and limitations under the Apache Lic
835
901
  this.disable();
836
902
  }
837
903
  }
904
+
905
+
906
+ syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
907
+ this.container.addClass(evaluate(this.opts.containerCssClass));
908
+
909
+ syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
910
+ this.dropdown.addClass(evaluate(this.opts.dropdownCssClass));
911
+
838
912
  });
839
913
 
840
914
  // mozilla and IE
@@ -903,21 +977,21 @@ the specific language governing permissions and limitations under the Apache Lic
903
977
  height = this.container.outerHeight(false),
904
978
  width = this.container.outerWidth(false),
905
979
  dropHeight = this.dropdown.outerHeight(false),
906
- viewPortRight = $(window).scrollLeft() + document.documentElement.clientWidth,
907
- viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight,
980
+ viewPortRight = $(window).scrollLeft() + $(window).width(),
981
+ viewportBottom = $(window).scrollTop() + $(window).height(),
908
982
  dropTop = offset.top + height,
909
983
  dropLeft = offset.left,
910
984
  enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
911
985
  enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),
912
- dropWidth = this.dropdown.outerWidth(false),
913
- enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
986
+ dropWidth = this.dropdown.outerWidth(false),
987
+ enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
914
988
  aboveNow = this.dropdown.hasClass("select2-drop-above"),
915
989
  bodyOffset,
916
990
  above,
917
991
  css;
918
992
 
919
- // console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
920
- // console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove);
993
+ //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
994
+ //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove);
921
995
 
922
996
  // fix positioning when body has an offset and is not position: static
923
997
 
@@ -937,9 +1011,9 @@ the specific language governing permissions and limitations under the Apache Lic
937
1011
  if (!enoughRoomBelow && enoughRoomAbove) above = true;
938
1012
  }
939
1013
 
940
- if (!enoughRoomOnRight) {
941
- dropLeft = offset.left + width - dropWidth;
942
- }
1014
+ if (!enoughRoomOnRight) {
1015
+ dropLeft = offset.left + width - dropWidth;
1016
+ }
943
1017
 
944
1018
  if (above) {
945
1019
  dropTop = offset.top - dropHeight;
@@ -966,7 +1040,7 @@ the specific language governing permissions and limitations under the Apache Lic
966
1040
 
967
1041
  if (this.opened()) return false;
968
1042
 
969
- event = $.Event("open");
1043
+ event = $.Event("opening");
970
1044
  this.opts.element.trigger(event);
971
1045
  return !event.isDefaultPrevented();
972
1046
  },
@@ -1007,8 +1081,6 @@ the specific language governing permissions and limitations under the Apache Lic
1007
1081
 
1008
1082
  this.clearDropdownAlignmentPreference();
1009
1083
 
1010
- if (this.search.val() === " ") { this.search.val(""); }
1011
-
1012
1084
  this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
1013
1085
 
1014
1086
 
@@ -1018,7 +1090,24 @@ the specific language governing permissions and limitations under the Apache Lic
1018
1090
 
1019
1091
  this.updateResults(true);
1020
1092
 
1093
+ // create the dropdown mask if doesnt already exist
1021
1094
  mask = $("#select2-drop-mask");
1095
+ if (mask.length == 0) {
1096
+ mask = $(document.createElement("div"));
1097
+ mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
1098
+ mask.hide();
1099
+ mask.appendTo(this.body());
1100
+ mask.bind("mousedown touchstart", function (e) {
1101
+ var dropdown = $("#select2-drop"), self;
1102
+ if (dropdown.length > 0) {
1103
+ self=dropdown.data("select2");
1104
+ if (self.opts.selectOnBlur) {
1105
+ self.selectHighlighted({noFocus: true});
1106
+ }
1107
+ self.close();
1108
+ }
1109
+ });
1110
+ }
1022
1111
 
1023
1112
  // ensure the mask is always right before the dropdown
1024
1113
  if (this.dropdown.prev()[0] !== mask[0]) {
@@ -1042,12 +1131,13 @@ the specific language governing permissions and limitations under the Apache Lic
1042
1131
 
1043
1132
  // attach listeners to events that can change the position of the container and thus require
1044
1133
  // the position of the dropdown to be updated as well so it does not come unglued from the container
1134
+ var that = this;
1045
1135
  this.container.parents().add(window).each(function () {
1046
1136
  $(this).bind(resize+" "+scroll+" "+orient, function (e) {
1047
1137
  $("#select2-drop-mask").css({
1048
1138
  width:document.documentElement.scrollWidth,
1049
1139
  height:document.documentElement.scrollHeight});
1050
- $("#select2-drop").data("select2").positionDropdown();
1140
+ that.positionDropdown();
1051
1141
  });
1052
1142
  });
1053
1143
 
@@ -1071,7 +1161,7 @@ the specific language governing permissions and limitations under the Apache Lic
1071
1161
  $("#select2-drop-mask").hide();
1072
1162
  this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id
1073
1163
  this.dropdown.hide();
1074
- this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
1164
+ this.container.removeClass("select2-dropdown-open");
1075
1165
  this.results.empty();
1076
1166
  this.clearSearch();
1077
1167
 
@@ -1083,6 +1173,11 @@ the specific language governing permissions and limitations under the Apache Lic
1083
1173
 
1084
1174
  },
1085
1175
 
1176
+ //abstract
1177
+ getMaximumSelectionSize: function() {
1178
+ return evaluate(this.opts.maximumSelectionSize);
1179
+ },
1180
+
1086
1181
  // abstract
1087
1182
  ensureHighlightVisible: function () {
1088
1183
  var results = this.results, children, index, child, hb, rb, y, more;
@@ -1150,7 +1245,9 @@ the specific language governing permissions and limitations under the Apache Lic
1150
1245
 
1151
1246
  // abstract
1152
1247
  highlight: function (index) {
1153
- var choices = this.findHighlightableChoices();
1248
+ var choices = this.findHighlightableChoices(),
1249
+ choice,
1250
+ data;
1154
1251
 
1155
1252
  if (arguments.length === 0) {
1156
1253
  return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
@@ -1161,8 +1258,15 @@ the specific language governing permissions and limitations under the Apache Lic
1161
1258
 
1162
1259
  this.results.find(".select2-highlighted").removeClass("select2-highlighted");
1163
1260
 
1164
- $(choices[index]).addClass("select2-highlighted");
1261
+ choice = $(choices[index]);
1262
+ choice.addClass("select2-highlighted");
1263
+
1165
1264
  this.ensureHighlightVisible();
1265
+
1266
+ data = choice.data("select2-data");
1267
+ if (data) {
1268
+ this.opts.element.trigger({ type: "highlight", val: this.id(data), choice: data });
1269
+ }
1166
1270
  },
1167
1271
 
1168
1272
  // abstract
@@ -1199,6 +1303,7 @@ the specific language governing permissions and limitations under the Apache Lic
1199
1303
  if (below <= this.opts.loadMorePadding) {
1200
1304
  more.addClass("select2-active");
1201
1305
  this.opts.query({
1306
+ element: this.opts.element,
1202
1307
  term: term,
1203
1308
  page: page,
1204
1309
  context: context,
@@ -1219,6 +1324,7 @@ the specific language governing permissions and limitations under the Apache Lic
1219
1324
  }
1220
1325
  self.positionDropdown();
1221
1326
  self.resultsPage = page;
1327
+ self.context = data.context;
1222
1328
  })});
1223
1329
  }
1224
1330
  },
@@ -1255,7 +1361,7 @@ the specific language governing permissions and limitations under the Apache Lic
1255
1361
  postRender();
1256
1362
  }
1257
1363
 
1258
- var maxSelSize = $.isFunction(opts.maximumSelectionSize) ? opts.maximumSelectionSize() : opts.maximumSelectionSize;
1364
+ var maxSelSize = this.getMaximumSelectionSize();
1259
1365
  if (maxSelSize >=1) {
1260
1366
  data = this.data();
1261
1367
  if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
@@ -1292,7 +1398,9 @@ the specific language governing permissions and limitations under the Apache Lic
1292
1398
  }
1293
1399
 
1294
1400
  this.resultsPage = 1;
1401
+
1295
1402
  opts.query({
1403
+ element: opts.element,
1296
1404
  term: search.val(),
1297
1405
  page: this.resultsPage,
1298
1406
  context: null,
@@ -1305,7 +1413,6 @@ the specific language governing permissions and limitations under the Apache Lic
1305
1413
 
1306
1414
  // save context, if any
1307
1415
  this.context = (data.context===undefined) ? null : data.context;
1308
-
1309
1416
  // create a default choice and prepend it to the list
1310
1417
  if (this.opts.createSearchChoice && search.val() !== "") {
1311
1418
  def = this.opts.createSearchChoice.call(null, search.val(), data.results);
@@ -1351,28 +1458,15 @@ the specific language governing permissions and limitations under the Apache Lic
1351
1458
 
1352
1459
  this.close();
1353
1460
  this.container.removeClass("select2-container-active");
1354
- this.dropdown.removeClass("select2-drop-active");
1355
1461
  // synonymous to .is(':focus'), which is available in jquery >= 1.6
1356
1462
  if (this.search[0] === document.activeElement) { this.search.blur(); }
1357
1463
  this.clearSearch();
1358
1464
  this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
1359
- this.opts.element.triggerHandler("blur");
1360
1465
  },
1361
1466
 
1362
1467
  // abstract
1363
1468
  focusSearch: function () {
1364
- // need to do it here as well as in timeout so it works in IE
1365
- this.search.show();
1366
- this.search.focus();
1367
-
1368
- /* we do this in a timeout so that current event processing can complete before this code is executed.
1369
- this makes sure the search field is focussed even if the current event would blur it */
1370
- window.setTimeout(this.bind(function () {
1371
- // reset the value so IE places the cursor at the end of the input box
1372
- this.search.show();
1373
- this.search.focus();
1374
- this.search.val(this.search.val());
1375
- }), 10);
1469
+ focus(this.search);
1376
1470
  },
1377
1471
 
1378
1472
  // abstract
@@ -1389,14 +1483,6 @@ the specific language governing permissions and limitations under the Apache Lic
1389
1483
 
1390
1484
  // abstract
1391
1485
  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
-
1400
1486
  return this.opts.element.attr("placeholder") ||
1401
1487
  this.opts.element.attr("data-placeholder") || // jquery 1.4 compat
1402
1488
  this.opts.element.data("placeholder") ||
@@ -1451,7 +1537,7 @@ the specific language governing permissions and limitations under the Apache Lic
1451
1537
 
1452
1538
  var width = resolveContainerWidth.call(this);
1453
1539
  if (width !== null) {
1454
- this.container.attr("style", "width: "+width);
1540
+ this.container.css("width", width);
1455
1541
  }
1456
1542
  }
1457
1543
  });
@@ -1464,11 +1550,12 @@ the specific language governing permissions and limitations under the Apache Lic
1464
1550
  var container = $(document.createElement("div")).attr({
1465
1551
  "class": "select2-container"
1466
1552
  }).html([
1467
- " <a href='javascript:void(0)' onclick='return false;' class='select2-choice'>",
1553
+ "<a href='javascript:void(0)' onclick='return false;' class='select2-choice' tabindex='-1'>",
1468
1554
  " <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
1469
1555
  " <div><b></b></div>" ,
1470
1556
  "</a>",
1471
- " <div class='select2-drop select2-offscreen'>" ,
1557
+ "<input class='select2-focusser select2-offscreen' type='text'/>",
1558
+ "<div class='select2-drop' style='display:none'>" ,
1472
1559
  " <div class='select2-search'>" ,
1473
1560
  " <input type='text' autocomplete='off' class='select2-input'/>" ,
1474
1561
  " </div>" ,
@@ -1484,8 +1571,7 @@ the specific language governing permissions and limitations under the Apache Lic
1484
1571
 
1485
1572
  this.parent.disable.apply(this, arguments);
1486
1573
 
1487
- this.selection.attr("tabIndex", "-1");
1488
- this.search.attr("tabIndex", "-1");
1574
+ this.focusser.attr("disabled", "disabled");
1489
1575
  },
1490
1576
 
1491
1577
  // single
@@ -1494,45 +1580,45 @@ the specific language governing permissions and limitations under the Apache Lic
1494
1580
 
1495
1581
  this.parent.enable.apply(this, arguments);
1496
1582
 
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");
1583
+ this.focusser.removeAttr("disabled");
1504
1584
  },
1505
1585
 
1506
1586
  // single
1507
1587
  opening: function () {
1508
- this.search.show();
1509
1588
  this.parent.opening.apply(this, arguments);
1510
- this.dropdown.removeClass("select2-offscreen");
1589
+ this.focusser.attr("disabled", "disabled");
1590
+
1591
+ this.opts.element.trigger($.Event("open"));
1511
1592
  },
1512
1593
 
1513
1594
  // single
1514
1595
  close: function () {
1515
1596
  if (!this.opened()) return;
1516
1597
  this.parent.close.apply(this, arguments);
1517
- this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show();
1598
+ this.focusser.removeAttr("disabled");
1599
+ focus(this.focusser);
1518
1600
  },
1519
1601
 
1520
1602
  // single
1521
1603
  focus: function () {
1522
- this.close();
1523
- this.selection.focus();
1524
- this.opts.element.triggerHandler("focus");
1604
+ if (this.opened()) {
1605
+ this.close();
1606
+ } else {
1607
+ this.focusser.removeAttr("disabled");
1608
+ this.focusser.focus();
1609
+ }
1525
1610
  },
1526
1611
 
1527
1612
  // single
1528
1613
  isFocused: function () {
1529
- return this.selection[0] === document.activeElement;
1614
+ return this.container.hasClass("select2-container-active");
1530
1615
  },
1531
1616
 
1532
1617
  // single
1533
1618
  cancel: function () {
1534
1619
  this.parent.cancel.apply(this, arguments);
1535
- this.selection.focus();
1620
+ this.focusser.removeAttr("disabled");
1621
+ this.focusser.focus();
1536
1622
  },
1537
1623
 
1538
1624
  // single
@@ -1543,8 +1629,12 @@ the specific language governing permissions and limitations under the Apache Lic
1543
1629
  dropdown = this.dropdown,
1544
1630
  clickingInside = false;
1545
1631
 
1632
+ this.showSearch(this.opts.minimumResultsForSearch >= 0);
1633
+
1546
1634
  this.selection = selection = container.find(".select2-choice");
1547
1635
 
1636
+ this.focusser = container.find(".select2-focusser");
1637
+
1548
1638
  this.search.bind("keydown", this.bind(function (e) {
1549
1639
  if (!this.enabled) return;
1550
1640
 
@@ -1554,56 +1644,62 @@ the specific language governing permissions and limitations under the Apache Lic
1554
1644
  return;
1555
1645
  }
1556
1646
 
1557
- if (this.opened()) {
1558
- switch (e.which) {
1559
- case KEY.UP:
1560
- case KEY.DOWN:
1561
- this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
1562
- killEvent(e);
1563
- return;
1564
- case KEY.TAB:
1565
- case KEY.ENTER:
1566
- this.selectHighlighted();
1567
- killEvent(e);
1568
- return;
1569
- case KEY.ESC:
1570
- this.cancel(e);
1571
- killEvent(e);
1572
- return;
1573
- }
1574
- } else {
1575
-
1576
- if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
1647
+ switch (e.which) {
1648
+ case KEY.UP:
1649
+ case KEY.DOWN:
1650
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
1651
+ killEvent(e);
1577
1652
  return;
1578
- }
1579
-
1580
- if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
1653
+ case KEY.TAB:
1654
+ case KEY.ENTER:
1655
+ this.selectHighlighted();
1656
+ killEvent(e);
1581
1657
  return;
1582
- }
1658
+ case KEY.ESC:
1659
+ this.cancel(e);
1660
+ killEvent(e);
1661
+ return;
1662
+ }
1663
+ }));
1664
+
1665
+ this.focusser.bind("keydown", this.bind(function (e) {
1666
+ if (!this.enabled) return;
1667
+
1668
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
1669
+ return;
1670
+ }
1671
+
1672
+ if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
1673
+ killEvent(e);
1674
+ return;
1675
+ }
1583
1676
 
1677
+ if (e.which == KEY.DOWN || e.which == KEY.UP
1678
+ || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
1584
1679
  this.open();
1680
+ killEvent(e);
1681
+ return;
1682
+ }
1585
1683
 
1586
- if (e.which === KEY.ENTER) {
1587
- // do not propagate the event otherwise we open, and propagate enter which closes
1588
- return;
1684
+ if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
1685
+ if (this.opts.allowClear) {
1686
+ this.clear();
1589
1687
  }
1688
+ killEvent(e);
1689
+ return;
1590
1690
  }
1591
1691
  }));
1592
1692
 
1593
- this.search.bind("focus", this.bind(function() {
1594
- this.selection.attr("tabIndex", "-1");
1595
- }));
1596
- this.search.bind("blur", this.bind(function() {
1597
- if (!this.opened()) this.container.removeClass("select2-container-active");
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);
1693
+
1694
+ installKeyUpChangeEvent(this.focusser);
1695
+ this.focusser.bind("keyup-change input", this.bind(function(e) {
1696
+ if (this.opened()) return;
1697
+ this.open();
1698
+ if (this.showSearchInput !== false) {
1699
+ this.search.val(this.focusser.val());
1700
+ }
1701
+ this.focusser.val("");
1702
+ killEvent(e);
1607
1703
  }));
1608
1704
 
1609
1705
  selection.delegate("abbr", "mousedown", this.bind(function (e) {
@@ -1611,7 +1707,6 @@ the specific language governing permissions and limitations under the Apache Lic
1611
1707
  this.clear();
1612
1708
  killEventImmediately(e);
1613
1709
  this.close();
1614
- this.triggerChange();
1615
1710
  this.selection.focus();
1616
1711
  }));
1617
1712
 
@@ -1620,71 +1715,47 @@ the specific language governing permissions and limitations under the Apache Lic
1620
1715
 
1621
1716
  if (this.opened()) {
1622
1717
  this.close();
1623
- this.selection.focus();
1624
1718
  } else if (this.enabled) {
1625
1719
  this.open();
1626
1720
  }
1627
1721
 
1722
+ killEvent(e);
1723
+
1628
1724
  clickingInside = false;
1629
1725
  }));
1630
1726
 
1631
1727
  dropdown.bind("mousedown", this.bind(function() { this.search.focus(); }));
1632
1728
 
1633
- selection.bind("focus", this.bind(function() {
1634
- if (!this.enabled) return;
1635
-
1636
- this.container.addClass("select2-container-active");
1637
- // hide the search so the tab key does not focus on it
1638
- this.search.attr("tabIndex", "-1");
1729
+ selection.bind("focus", this.bind(function(e) {
1730
+ killEvent(e);
1639
1731
  }));
1640
1732
 
1641
- selection.bind("blur", this.bind(function() {
1733
+ this.focusser.bind("focus", this.bind(function(){
1734
+ this.container.addClass("select2-container-active");
1735
+ })).bind("blur", this.bind(function() {
1642
1736
  if (!this.opened()) {
1643
1737
  this.container.removeClass("select2-container-active");
1644
1738
  }
1645
- window.setTimeout(this.bind(function() { this.search.attr("tabIndex", this.elementTabIndex || 0); }), 10);
1646
- }));
1647
-
1648
- selection.bind("keydown", this.bind(function(e) {
1649
- if (!this.enabled) return;
1650
-
1651
- if (e.which == KEY.DOWN || e.which == KEY.UP
1652
- || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
1653
- this.open();
1654
- killEvent(e);
1655
- return;
1656
- }
1657
-
1658
- if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
1659
- if (this.opts.allowClear) {
1660
- this.clear();
1661
- }
1662
- killEvent(e);
1663
- return;
1664
- }
1665
- }));
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();
1673
1739
  }));
1740
+ this.search.bind("focus", this.bind(function(){
1741
+ this.container.addClass("select2-container-active");
1742
+ }))
1674
1743
 
1744
+ this.initContainerWidth();
1675
1745
  this.setPlaceholder();
1676
1746
 
1677
- this.search.bind("focus", this.bind(function() {
1678
- this.container.addClass("select2-container-active");
1679
- }));
1680
1747
  },
1681
1748
 
1682
1749
  // single
1683
1750
  clear: function() {
1751
+ var data=this.selection.data("select2-data");
1684
1752
  this.opts.element.val("");
1685
1753
  this.selection.find("span").empty();
1686
1754
  this.selection.removeData("select2-data");
1687
1755
  this.setPlaceholder();
1756
+
1757
+ this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data });
1758
+ this.triggerChange({removed:data});
1688
1759
  },
1689
1760
 
1690
1761
  /**
@@ -1739,6 +1810,18 @@ the specific language governing permissions and limitations under the Apache Lic
1739
1810
  return opts;
1740
1811
  },
1741
1812
 
1813
+ // single
1814
+ getPlaceholder: function() {
1815
+ // if a placeholder is specified on a single select without the first empty option ignore it
1816
+ if (this.select) {
1817
+ if (this.select.find("option").first().text() !== "") {
1818
+ return undefined;
1819
+ }
1820
+ }
1821
+
1822
+ return this.parent.getPlaceholder.apply(this, arguments);
1823
+ },
1824
+
1742
1825
  // single
1743
1826
  setPlaceholder: function () {
1744
1827
  var placeholder = this.getPlaceholder();
@@ -1776,21 +1859,31 @@ the specific language governing permissions and limitations under the Apache Lic
1776
1859
  // hide the search box if this is the first we got the results and there are a few of them
1777
1860
 
1778
1861
  if (initial === true) {
1779
- showSearchInput = this.showSearchInput = countResults(data.results) >= this.opts.minimumResultsForSearch;
1780
- this.dropdown.find(".select2-search")[showSearchInput ? "removeClass" : "addClass"]("select2-search-hidden");
1781
-
1782
- //add "select2-with-searchbox" to the container if search box is shown
1783
- $(this.dropdown, this.container)[showSearchInput ? "addClass" : "removeClass"]("select2-with-searchbox");
1862
+ var min=this.opts.minimumResultsForSearch;
1863
+ showSearchInput = min < 0 ? false : countResults(data.results) >= min;
1864
+ this.showSearch(showSearchInput);
1784
1865
  }
1785
1866
 
1786
1867
  },
1787
1868
 
1869
+ // single
1870
+ showSearch: function(showSearchInput) {
1871
+ this.showSearchInput = showSearchInput;
1872
+
1873
+ this.dropdown.find(".select2-search")[showSearchInput ? "removeClass" : "addClass"]("select2-search-hidden");
1874
+ //add "select2-with-searchbox" to the container if search box is shown
1875
+ $(this.dropdown, this.container)[showSearchInput ? "addClass" : "removeClass"]("select2-with-searchbox");
1876
+ },
1877
+
1788
1878
  // single
1789
1879
  onSelect: function (data, options) {
1790
1880
  var old = this.opts.element.val();
1791
1881
 
1792
1882
  this.opts.element.val(this.id(data));
1793
1883
  this.updateSelection(data);
1884
+
1885
+ this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
1886
+
1794
1887
  this.close();
1795
1888
 
1796
1889
  if (!options || !options.noFocus)
@@ -1862,7 +1955,9 @@ the specific language governing permissions and limitations under the Apache Lic
1862
1955
  self.opts.element.val(!data ? "" : self.id(data));
1863
1956
  self.updateSelection(data);
1864
1957
  self.setPlaceholder();
1865
- self.triggerChange();
1958
+ if (triggerChange) {
1959
+ self.triggerChange();
1960
+ }
1866
1961
  });
1867
1962
  }
1868
1963
  },
@@ -1870,6 +1965,7 @@ the specific language governing permissions and limitations under the Apache Lic
1870
1965
  // single
1871
1966
  clearSearch: function () {
1872
1967
  this.search.val("");
1968
+ this.focusser.val("");
1873
1969
  },
1874
1970
 
1875
1971
  // single
@@ -1919,15 +2015,14 @@ the specific language governing permissions and limitations under the Apache Lic
1919
2015
 
1920
2016
  if (opts.element.get(0).tagName.toLowerCase() === "select") {
1921
2017
  // install sthe selection initializer
1922
- opts.initSelection = function (element,callback) {
2018
+ opts.initSelection = function (element, callback) {
1923
2019
 
1924
2020
  var data = [];
2021
+
1925
2022
  element.find(":selected").each2(function (i, elm) {
1926
- data.push({id: elm.attr("value"), text: elm.text(), element: elm});
2023
+ data.push({id: elm.attr("value"), text: elm.text(), element: elm[0]});
1927
2024
  });
1928
-
1929
- if ($.isFunction(callback))
1930
- callback(data);
2025
+ callback(data);
1931
2026
  };
1932
2027
  } else if ("data" in opts) {
1933
2028
  // install default initSelection when applied to hidden input and data is local
@@ -1958,6 +2053,13 @@ the specific language governing permissions and limitations under the Apache Lic
1958
2053
  this.searchContainer = this.container.find(".select2-search-field");
1959
2054
  this.selection = selection = this.container.find(selector);
1960
2055
 
2056
+ this.search.bind("input paste", this.bind(function() {
2057
+ if (!this.enabled) return;
2058
+ if (!this.opened()) {
2059
+ this.open();
2060
+ }
2061
+ }));
2062
+
1961
2063
  this.search.bind("keydown", this.bind(function (e) {
1962
2064
  if (!this.enabled) return;
1963
2065
 
@@ -2005,8 +2107,12 @@ the specific language governing permissions and limitations under the Apache Lic
2005
2107
  return;
2006
2108
  }
2007
2109
 
2008
- if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
2009
- return;
2110
+ if (e.which === KEY.ENTER) {
2111
+ if (this.opts.openOnEnter === false) {
2112
+ return;
2113
+ } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
2114
+ return;
2115
+ }
2010
2116
  }
2011
2117
 
2012
2118
  this.open();
@@ -2045,6 +2151,8 @@ the specific language governing permissions and limitations under the Apache Lic
2045
2151
  this.clearPlaceholder();
2046
2152
  }));
2047
2153
 
2154
+ this.initContainerWidth();
2155
+
2048
2156
  // set the placeholder if necessary
2049
2157
  this.clearSearch();
2050
2158
  },
@@ -2098,9 +2206,7 @@ the specific language governing permissions and limitations under the Apache Lic
2098
2206
  // stretch the search box to full width of the container so as much of the placeholder is visible as possible
2099
2207
  this.resizeSearch();
2100
2208
  } else {
2101
- // we set this to " " instead of "" and later clear it on focus() because there is a firefox bug
2102
- // that does not properly render the caret when the field starts out blank
2103
- this.search.val(" ").width(10);
2209
+ this.search.val("").width(10);
2104
2210
  }
2105
2211
  },
2106
2212
 
@@ -2108,9 +2214,6 @@ the specific language governing permissions and limitations under the Apache Lic
2108
2214
  clearPlaceholder: function () {
2109
2215
  if (this.search.hasClass("select2-default")) {
2110
2216
  this.search.val("").removeClass("select2-default");
2111
- } else {
2112
- // work around for the space character we set to avoid firefox caret bug
2113
- if (this.search.val() === " ") this.search.val("");
2114
2217
  }
2115
2218
  },
2116
2219
 
@@ -2121,6 +2224,8 @@ the specific language governing permissions and limitations under the Apache Lic
2121
2224
  this.clearPlaceholder();
2122
2225
  this.resizeSearch();
2123
2226
  this.focusSearch();
2227
+
2228
+ this.opts.element.trigger($.Event("open"));
2124
2229
  },
2125
2230
 
2126
2231
  // multi
@@ -2176,6 +2281,9 @@ the specific language governing permissions and limitations under the Apache Lic
2176
2281
  // multi
2177
2282
  onSelect: function (data, options) {
2178
2283
  this.addSelectedChoice(data);
2284
+
2285
+ this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
2286
+
2179
2287
  if (this.select || !this.opts.closeOnSelect) this.postprocessResults();
2180
2288
 
2181
2289
  if (this.opts.closeOnSelect) {
@@ -2185,10 +2293,16 @@ the specific language governing permissions and limitations under the Apache Lic
2185
2293
  if (this.countSelectableResults()>0) {
2186
2294
  this.search.width(10);
2187
2295
  this.resizeSearch();
2296
+ if (this.val().length >= this.getMaximumSelectionSize()) {
2297
+ // if we reached max selection size repaint the results so choices
2298
+ // are replaced with the max selection reached message
2299
+ this.updateResults(true);
2300
+ }
2188
2301
  this.positionDropdown();
2189
2302
  } else {
2190
2303
  // if nothing left to select close
2191
2304
  this.close();
2305
+ this.search.width(10);
2192
2306
  }
2193
2307
  }
2194
2308
 
@@ -2282,6 +2396,8 @@ the specific language governing permissions and limitations under the Apache Lic
2282
2396
  if (this.select) this.postprocessResults();
2283
2397
  }
2284
2398
  selected.remove();
2399
+
2400
+ this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data });
2285
2401
  this.triggerChange({ removed: data });
2286
2402
  },
2287
2403
 
@@ -2317,7 +2433,6 @@ the specific language governing permissions and limitations under the Apache Lic
2317
2433
 
2318
2434
  // multi
2319
2435
  resizeSearch: function () {
2320
-
2321
2436
  var minimumWidth, left, maxWidth, containerLeft, searchWidth,
2322
2437
  sideBorderPadding = getSideBorderPadding(this.search);
2323
2438
 
@@ -2329,6 +2444,7 @@ the specific language governing permissions and limitations under the Apache Lic
2329
2444
  containerLeft = this.selection.offset().left;
2330
2445
 
2331
2446
  searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
2447
+
2332
2448
  if (searchWidth < minimumWidth) {
2333
2449
  searchWidth = maxWidth - sideBorderPadding;
2334
2450
  }
@@ -2338,7 +2454,7 @@ the specific language governing permissions and limitations under the Apache Lic
2338
2454
  }
2339
2455
 
2340
2456
  if (searchWidth <= 0) {
2341
- searchWidth = minimumWidth
2457
+ searchWidth = minimumWidth;
2342
2458
  }
2343
2459
 
2344
2460
  this.search.width(searchWidth);
@@ -2400,16 +2516,13 @@ the specific language governing permissions and limitations under the Apache Lic
2400
2516
  this.setVal(val);
2401
2517
 
2402
2518
  if (this.select) {
2403
- this.select.find(":selected").each(function () {
2404
- data.push({id: $(this).attr("value"), text: $(this).text()});
2405
- });
2406
- this.updateSelection(data);
2519
+ this.opts.initSelection(this.select, this.bind(this.updateSelection));
2407
2520
  if (triggerChange) {
2408
2521
  this.triggerChange();
2409
2522
  }
2410
2523
  } else {
2411
2524
  if (this.opts.initSelection === undefined) {
2412
- throw new Error("val() cannot be called if initSelection() is not defined")
2525
+ throw new Error("val() cannot be called if initSelection() is not defined");
2413
2526
  }
2414
2527
 
2415
2528
  this.opts.initSelection(this.opts.element, function(data){
@@ -2468,7 +2581,7 @@ the specific language governing permissions and limitations under the Apache Lic
2468
2581
  .get();
2469
2582
  } else {
2470
2583
  if (!values) { values = []; }
2471
- ids = $.map(values, function(e) { return self.opts.id(e)});
2584
+ ids = $.map(values, function(e) { return self.opts.id(e); });
2472
2585
  this.setVal(ids);
2473
2586
  this.updateSelection(values);
2474
2587
  this.clearSearch();
@@ -2574,7 +2687,9 @@ the specific language governing permissions and limitations under the Apache Lic
2574
2687
  });
2575
2688
  },
2576
2689
  blurOnChange: false,
2577
- selectOnBlur: false
2690
+ selectOnBlur: false,
2691
+ adaptContainerCssClass: function(c) { return c; },
2692
+ adaptDropdownCssClass: function(c) { return null; }
2578
2693
  };
2579
2694
 
2580
2695
  // exports