bootstrap-select-wrapper-rails 1.6.3 → 1.9.4

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bootstrap/select/wrapper/rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/bootstrap-select.js +1715 -1213
  4. data/vendor/assets/javascripts/bootstrap-select.js.map +1 -0
  5. data/vendor/assets/javascripts/bootstrap-select.min.js +6 -6
  6. data/vendor/assets/javascripts/i18n/defaults-ar_AR.js +49 -0
  7. data/vendor/assets/javascripts/i18n/defaults-ar_AR.min.js +12 -0
  8. data/vendor/assets/javascripts/i18n/defaults-bg_BG.js +44 -0
  9. data/vendor/assets/javascripts/i18n/defaults-bg_BG.min.js +7 -0
  10. data/vendor/assets/javascripts/i18n/defaults-cro_CRO.js +44 -0
  11. data/vendor/assets/javascripts/i18n/defaults-cro_CRO.min.js +7 -0
  12. data/vendor/assets/javascripts/i18n/defaults-cs_CZ.js +35 -15
  13. data/vendor/assets/javascripts/i18n/defaults-cs_CZ.min.js +6 -6
  14. data/vendor/assets/javascripts/i18n/defaults-da_DK.js +44 -0
  15. data/vendor/assets/javascripts/i18n/defaults-da_DK.min.js +7 -0
  16. data/vendor/assets/javascripts/i18n/defaults-de_DE.js +35 -15
  17. data/vendor/assets/javascripts/i18n/defaults-de_DE.min.js +6 -6
  18. data/vendor/assets/javascripts/i18n/defaults-en_US.js +42 -24
  19. data/vendor/assets/javascripts/i18n/defaults-en_US.min.js +6 -6
  20. data/vendor/assets/javascripts/i18n/defaults-es_CL.js +35 -15
  21. data/vendor/assets/javascripts/i18n/defaults-es_CL.min.js +6 -6
  22. data/vendor/assets/javascripts/i18n/defaults-eu.js +35 -15
  23. data/vendor/assets/javascripts/i18n/defaults-eu.min.js +6 -6
  24. data/vendor/assets/javascripts/i18n/defaults-fa_IR.js +37 -0
  25. data/vendor/assets/javascripts/i18n/defaults-fa_IR.min.js +7 -0
  26. data/vendor/assets/javascripts/i18n/defaults-fi_FI.js +44 -0
  27. data/vendor/assets/javascripts/i18n/defaults-fi_FI.min.js +7 -0
  28. data/vendor/assets/javascripts/i18n/defaults-fr_FR.js +42 -22
  29. data/vendor/assets/javascripts/i18n/defaults-fr_FR.min.js +6 -6
  30. data/vendor/assets/javascripts/i18n/defaults-hu_HU.js +44 -0
  31. data/vendor/assets/javascripts/i18n/defaults-hu_HU.min.js +7 -0
  32. data/vendor/assets/javascripts/i18n/defaults-id_ID.js +37 -0
  33. data/vendor/assets/javascripts/i18n/defaults-id_ID.min.js +7 -0
  34. data/vendor/assets/javascripts/i18n/defaults-it_IT.js +35 -15
  35. data/vendor/assets/javascripts/i18n/defaults-it_IT.min.js +6 -6
  36. data/vendor/assets/javascripts/i18n/defaults-ko_KR.js +44 -0
  37. data/vendor/assets/javascripts/i18n/defaults-ko_KR.min.js +7 -0
  38. data/vendor/assets/javascripts/i18n/defaults-nb_NO.js +70 -0
  39. data/vendor/assets/javascripts/i18n/defaults-nb_NO.min.js +13 -0
  40. data/vendor/assets/javascripts/i18n/defaults-nl_NL.js +35 -15
  41. data/vendor/assets/javascripts/i18n/defaults-nl_NL.min.js +6 -6
  42. data/vendor/assets/javascripts/i18n/defaults-pl_PL.js +37 -17
  43. data/vendor/assets/javascripts/i18n/defaults-pl_PL.min.js +6 -6
  44. data/vendor/assets/javascripts/i18n/defaults-pt_BR.js +35 -15
  45. data/vendor/assets/javascripts/i18n/defaults-pt_BR.min.js +6 -6
  46. data/vendor/assets/javascripts/i18n/defaults-pt_PT.js +35 -0
  47. data/vendor/assets/javascripts/i18n/defaults-pt_PT.min.js +7 -0
  48. data/vendor/assets/javascripts/i18n/defaults-ro_RO.js +35 -15
  49. data/vendor/assets/javascripts/i18n/defaults-ro_RO.min.js +6 -6
  50. data/vendor/assets/javascripts/i18n/defaults-ru_RU.js +36 -15
  51. data/vendor/assets/javascripts/i18n/defaults-ru_RU.min.js +6 -6
  52. data/vendor/assets/javascripts/i18n/defaults-sk_SK.js +37 -0
  53. data/vendor/assets/javascripts/i18n/defaults-sk_SK.min.js +7 -0
  54. data/vendor/assets/javascripts/i18n/defaults-sl_SI.js +44 -0
  55. data/vendor/assets/javascripts/i18n/defaults-sl_SI.min.js +7 -0
  56. data/vendor/assets/javascripts/i18n/defaults-sv_SE.js +44 -0
  57. data/vendor/assets/javascripts/i18n/defaults-sv_SE.min.js +7 -0
  58. data/vendor/assets/javascripts/i18n/defaults-tr_TR.js +44 -0
  59. data/vendor/assets/javascripts/i18n/defaults-tr_TR.min.js +7 -0
  60. data/vendor/assets/javascripts/i18n/defaults-ua_UA.js +35 -15
  61. data/vendor/assets/javascripts/i18n/defaults-ua_UA.min.js +6 -6
  62. data/vendor/assets/javascripts/i18n/defaults-zh_CN.js +35 -15
  63. data/vendor/assets/javascripts/i18n/defaults-zh_CN.min.js +6 -6
  64. data/vendor/assets/javascripts/i18n/defaults-zh_TW.js +37 -17
  65. data/vendor/assets/javascripts/i18n/defaults-zh_TW.min.js +6 -6
  66. data/vendor/assets/stylesheets/bootstrap-select.css +71 -54
  67. data/vendor/assets/stylesheets/bootstrap-select.css.map +1 -0
  68. data/vendor/assets/stylesheets/bootstrap-select.min.css +6 -6
  69. metadata +35 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de36659724f64cd38b3d7cd9a61b8cf1440d53e6
4
- data.tar.gz: d9463f2079aaef7c236019caa934da74e19bf900
3
+ metadata.gz: a12f9c99d9437c92d754f2ea340cabbfb14d21f6
4
+ data.tar.gz: d9df28b709efc37ea6ff2bb1ca91f9da75500e8f
5
5
  SHA512:
6
- metadata.gz: 519aa5aa0f2f8b01037f4897a08622ee6fe6110a7c099f70ff06c454c0baf2369c44f1e6c0331465c52967ffe78d5557891c4c89869cfc7eb03e3139170d19e9
7
- data.tar.gz: 037ba8f1108bbd2b9673a3d7a713d3cb72778764d3326dbb1dbdc574929d97e0f7fbff95d8500036048639b74e334293c9f7001a531856bd99cbd9f72fa15f32
6
+ metadata.gz: 6f0c7e76dac0f75579e738fa1bb34497df6cd9c81841113e379ddc6e2a2b49f8c37aab1062322b1c3db290cd81dcfa61060436141870a50b1e51ed889b58f99b
7
+ data.tar.gz: 208389122337f18164ccc6d327e99c29b7bb4a797a699d0a6aa3b58d8016fc9d51d226bfe355272fbff69e7bcb7c05c7dfeed419052f9f852f9bfa9ea9d944fb
@@ -2,7 +2,7 @@ module Bootstrap
2
2
  module Select
3
3
  module Wrapper
4
4
  module Rails
5
- VERSION = "1.6.3"
5
+ VERSION = "1.9.4"
6
6
  end
7
7
  end
8
8
  end
@@ -1,1215 +1,1717 @@
1
- /*!
2
- * Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
3
- *
4
- * Copyright 2013-2014 bootstrap-select
5
- * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
6
- */
7
- (function ($) {
8
- 'use strict';
9
-
10
- // Case insensitive search
11
- $.expr[':'].icontains = function (obj, index, meta) {
12
- return icontains($(obj).text(), meta[3]);
13
- };
14
-
15
- // Case and accent insensitive search
16
- $.expr[':'].aicontains = function (obj, index, meta) {
17
- return icontains($(obj).data('normalizedText') || $(obj).text(), meta[3]);
18
- };
19
-
20
- /**
21
- * Actual implementation of the case insensitive search.
22
- * @access private
23
- * @param {String} haystack
24
- * @param {String} needle
25
- * @returns {boolean}
26
- */
27
- function icontains(haystack, needle) {
28
- return haystack.toUpperCase().indexOf(needle.toUpperCase()) > -1;
29
- }
30
-
31
- /**
32
- * Remove all diatrics from the given text.
33
- * @access private
34
- * @param {String} text
35
- * @returns {String}
36
- */
37
- function normalizeToBase(text) {
38
- var rExps = [
39
- {re: /[\xC0-\xC6]/g, ch: "A"},
40
- {re: /[\xE0-\xE6]/g, ch: "a"},
41
- {re: /[\xC8-\xCB]/g, ch: "E"},
42
- {re: /[\xE8-\xEB]/g, ch: "e"},
43
- {re: /[\xCC-\xCF]/g, ch: "I"},
44
- {re: /[\xEC-\xEF]/g, ch: "i"},
45
- {re: /[\xD2-\xD6]/g, ch: "O"},
46
- {re: /[\xF2-\xF6]/g, ch: "o"},
47
- {re: /[\xD9-\xDC]/g, ch: "U"},
48
- {re: /[\xF9-\xFC]/g, ch: "u"},
49
- {re: /[\xC7-\xE7]/g, ch: "c"},
50
- {re: /[\xD1]/g, ch: "N"},
51
- {re: /[\xF1]/g, ch: "n"}
52
- ];
53
- $.each(rExps, function () {
54
- text = text.replace(this.re, this.ch);
55
- });
56
- return text;
57
- }
58
-
59
-
60
- function htmlEscape(html) {
61
- var escapeMap = {
62
- '&': '&',
63
- '<': '&lt;',
64
- '>': '&gt;',
65
- '"': '&quot;',
66
- "'": '&#x27;',
67
- '`': '&#x60;'
68
- };
69
- var source = '(?:' + Object.keys(escapeMap).join('|') + ')',
70
- testRegexp = new RegExp(source),
71
- replaceRegexp = new RegExp(source, 'g'),
72
- string = html == null ? '' : '' + html;
73
- return testRegexp.test(string) ? string.replace(replaceRegexp, function (match) {
74
- return escapeMap[match];
75
- }) : string;
76
- }
77
-
78
- var Selectpicker = function (element, options, e) {
79
- if (e) {
80
- e.stopPropagation();
81
- e.preventDefault();
82
- }
83
-
84
- this.$element = $(element);
85
- this.$newElement = null;
86
- this.$button = null;
87
- this.$menu = null;
88
- this.$lis = null;
89
- this.options = options;
90
-
91
- // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a
92
- // data-attribute)
93
- if (this.options.title === null) {
94
- this.options.title = this.$element.attr('title');
95
- }
96
-
97
- //Expose public methods
98
- this.val = Selectpicker.prototype.val;
99
- this.render = Selectpicker.prototype.render;
100
- this.refresh = Selectpicker.prototype.refresh;
101
- this.setStyle = Selectpicker.prototype.setStyle;
102
- this.selectAll = Selectpicker.prototype.selectAll;
103
- this.deselectAll = Selectpicker.prototype.deselectAll;
104
- this.destroy = Selectpicker.prototype.remove;
105
- this.remove = Selectpicker.prototype.remove;
106
- this.show = Selectpicker.prototype.show;
107
- this.hide = Selectpicker.prototype.hide;
108
-
109
- this.init();
110
- };
111
-
112
- Selectpicker.VERSION = '1.6.3';
113
-
114
- // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.
115
- Selectpicker.DEFAULTS = {
116
- noneSelectedText: 'Nothing selected',
117
- noneResultsText: 'No results match',
118
- countSelectedText: function (numSelected, numTotal) {
119
- return (numSelected == 1) ? "{0} item selected" : "{0} items selected";
120
- },
121
- maxOptionsText: function (numAll, numGroup) {
122
- var arr = [];
123
-
124
- arr[0] = (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)';
125
- arr[1] = (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)';
126
-
127
- return arr;
128
- },
129
- selectAllText: 'Select All',
130
- deselectAllText: 'Deselect All',
131
- multipleSeparator: ', ',
132
- style: 'btn-default',
133
- size: 'auto',
134
- title: null,
135
- selectedTextFormat: 'values',
136
- width: false,
137
- container: false,
138
- hideDisabled: false,
139
- showSubtext: false,
140
- showIcon: true,
141
- showContent: true,
142
- dropupAuto: true,
143
- header: false,
144
- liveSearch: false,
145
- actionsBox: false,
146
- iconBase: 'glyphicon',
147
- tickIcon: 'glyphicon-ok',
148
- maxOptions: false,
149
- mobile: false,
150
- selectOnTab: false,
151
- dropdownAlignRight: false,
152
- searchAccentInsensitive: false
153
- };
154
-
155
- Selectpicker.prototype = {
156
-
157
- constructor: Selectpicker,
158
-
159
- init: function () {
160
- var that = this,
161
- id = this.$element.attr('id');
162
-
163
- this.$element.hide();
164
- this.multiple = this.$element.prop('multiple');
165
- this.autofocus = this.$element.prop('autofocus');
166
- this.$newElement = this.createView();
167
- this.$element.after(this.$newElement);
168
- this.$menu = this.$newElement.find('> .dropdown-menu');
169
- this.$button = this.$newElement.find('> button');
170
- this.$searchbox = this.$newElement.find('input');
171
-
172
- if (this.options.dropdownAlignRight)
173
- this.$menu.addClass('dropdown-menu-right');
174
-
175
- if (typeof id !== 'undefined') {
176
- this.$button.attr('data-id', id);
177
- $('label[for="' + id + '"]').click(function (e) {
178
- e.preventDefault();
179
- that.$button.focus();
180
- });
181
- }
182
-
183
- this.checkDisabled();
184
- this.clickListener();
185
- if (this.options.liveSearch) this.liveSearchListener();
186
- this.render();
187
- this.liHeight();
188
- this.setStyle();
189
- this.setWidth();
190
- if (this.options.container) this.selectPosition();
191
- this.$menu.data('this', this);
192
- this.$newElement.data('this', this);
193
- if (this.options.mobile) this.mobile();
194
- },
195
-
196
- createDropdown: function () {
197
- // Options
198
- // If we are multiple, then add the show-tick class by default
199
- var multiple = this.multiple ? ' show-tick' : '',
200
- inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',
201
- autofocus = this.autofocus ? ' autofocus' : '',
202
- btnSize = this.$element.parents().hasClass('form-group-lg') ? ' btn-lg' : (this.$element.parents().hasClass('form-group-sm') ? ' btn-sm' : '');
203
- // Elements
204
- var header = this.options.header ? '<div class="popover-title"><button type="button" class="close" aria-hidden="true">&times;</button>' + this.options.header + '</div>' : '';
205
- var searchbox = this.options.liveSearch ? '<div class="bs-searchbox"><input type="text" class="input-block-level form-control" autocomplete="off" /></div>' : '';
206
- var actionsbox = this.options.actionsBox ? '<div class="bs-actionsbox">' +
207
- '<div class="btn-group btn-block">' +
208
- '<button class="actions-btn bs-select-all btn btn-sm btn-default">' +
209
- this.options.selectAllText +
210
- '</button>' +
211
- '<button class="actions-btn bs-deselect-all btn btn-sm btn-default">' +
212
- this.options.deselectAllText +
213
- '</button>' +
214
- '</div>' +
215
- '</div>' : '';
216
- var drop =
217
- '<div class="btn-group bootstrap-select' + multiple + inputGroup + '">' +
218
- '<button type="button" class="btn dropdown-toggle selectpicker' + btnSize + '" data-toggle="dropdown"' + autofocus + '>' +
219
- '<span class="filter-option pull-left"></span>&nbsp;' +
220
- '<span class="caret"></span>' +
221
- '</button>' +
222
- '<div class="dropdown-menu open">' +
223
- header +
224
- searchbox +
225
- actionsbox +
226
- '<ul class="dropdown-menu inner selectpicker" role="menu">' +
227
- '</ul>' +
228
- '</div>' +
229
- '</div>';
230
-
231
- return $(drop);
232
- },
233
-
234
- createView: function () {
235
- var $drop = this.createDropdown();
236
- var $li = this.createLi();
237
- $drop.find('ul').append($li);
238
- return $drop;
239
- },
240
-
241
- reloadLi: function () {
242
- //Remove all children.
243
- this.destroyLi();
244
- //Re build
245
- var $li = this.createLi();
246
- this.$menu.find('ul').append($li);
247
- },
248
-
249
- destroyLi: function () {
250
- this.$menu.find('li').remove();
251
- },
252
-
253
- createLi: function () {
254
- var that = this,
255
- _li = [],
256
- optID = 0;
257
-
258
- // Helper functions
259
- /**
260
- * @param content
261
- * @param [index]
262
- * @param [classes]
263
- * @returns {string}
264
- */
265
- var generateLI = function (content, index, classes) {
266
- return '<li' +
267
- (typeof classes !== 'undefined' ? ' class="' + classes + '"' : '') +
268
- (typeof index !== 'undefined' | null === index ? ' data-original-index="' + index + '"' : '') +
269
- '>' + content + '</li>';
270
- };
271
-
272
- /**
273
- * @param text
274
- * @param [classes]
275
- * @param [inline]
276
- * @param [optgroup]
277
- * @returns {string}
278
- */
279
- var generateA = function (text, classes, inline, optgroup) {
280
- var normText = normalizeToBase(htmlEscape(text));
281
- return '<a tabindex="0"' +
282
- (typeof classes !== 'undefined' ? ' class="' + classes + '"' : '') +
283
- (typeof inline !== 'undefined' ? ' style="' + inline + '"' : '') +
284
- (typeof optgroup !== 'undefined' ? 'data-optgroup="' + optgroup + '"' : '') +
285
- ' data-normalized-text="' + normText + '"' +
286
- '>' + text +
287
- '<span class="' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark"></span>' +
288
- '</a>';
289
- };
290
-
291
- this.$element.find('option').each(function () {
292
- var $this = $(this);
293
-
294
- // Get the class and text for the option
295
- var optionClass = $this.attr('class') || '',
296
- inline = $this.attr('style'),
297
- text = $this.data('content') ? $this.data('content') : $this.html(),
298
- subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class="muted text-muted">' + $this.data('subtext') + '</small>' : '',
299
- icon = typeof $this.data('icon') !== 'undefined' ? '<span class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></span> ' : '',
300
- isDisabled = $this.is(':disabled') || $this.parent().is(':disabled'),
301
- index = $this[0].index;
302
- if (icon !== '' && isDisabled) {
303
- icon = '<span>' + icon + '</span>';
304
- }
305
-
306
- if (!$this.data('content')) {
307
- // Prepend any icon and append any subtext to the main text.
308
- text = icon + '<span class="text">' + text + subtext + '</span>';
309
- }
310
-
311
- if (that.options.hideDisabled && isDisabled) {
312
- return;
313
- }
314
-
315
- if ($this.parent().is('optgroup') && $this.data('divider') !== true) {
316
- if ($this.index() === 0) { // Is it the first option of the optgroup?
317
- optID += 1;
318
-
319
- // Get the opt group label
320
- var label = $this.parent().attr('label');
321
- var labelSubtext = typeof $this.parent().data('subtext') !== 'undefined' ? '<small class="muted text-muted">' + $this.parent().data('subtext') + '</small>' : '';
322
- var labelIcon = $this.parent().data('icon') ? '<span class="' + that.options.iconBase + ' ' + $this.parent().data('icon') + '"></span> ' : '';
323
- label = labelIcon + '<span class="text">' + label + labelSubtext + '</span>';
324
-
325
- if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?
326
- _li.push(generateLI('', null, 'divider'));
327
- }
328
-
329
- _li.push(generateLI(label, null, 'dropdown-header'));
330
- }
331
-
332
- _li.push(generateLI(generateA(text, 'opt ' + optionClass, inline, optID), index));
333
- } else if ($this.data('divider') === true) {
334
- _li.push(generateLI('', index, 'divider'));
335
- } else if ($this.data('hidden') === true) {
336
- _li.push(generateLI(generateA(text, optionClass, inline), index, 'hide is-hidden'));
337
- } else {
338
- _li.push(generateLI(generateA(text, optionClass, inline), index));
339
- }
340
- });
341
-
342
- //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button
343
- if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {
344
- this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
345
- }
346
-
347
- return $(_li.join(''));
348
- },
349
-
350
- findLis: function () {
351
- if (this.$lis == null) this.$lis = this.$menu.find('li');
352
- return this.$lis;
353
- },
354
-
355
- /**
356
- * @param [updateLi] defaults to true
357
- */
358
- render: function (updateLi) {
359
- var that = this;
360
-
361
- //Update the LI to match the SELECT
362
- if (updateLi !== false) {
363
- this.$element.find('option').each(function (index) {
364
- that.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled'));
365
- that.setSelected(index, $(this).is(':selected'));
366
- });
367
- }
368
-
369
- this.tabIndex();
370
- var notDisabled = this.options.hideDisabled ? ':not([disabled])' : '';
371
- var selectedItems = this.$element.find('option:selected' + notDisabled).map(function () {
372
- var $this = $(this);
373
- var icon = $this.data('icon') && that.options.showIcon ? '<i class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></i> ' : '';
374
- var subtext;
375
- if (that.options.showSubtext && $this.attr('data-subtext') && !that.multiple) {
376
- subtext = ' <small class="muted text-muted">' + $this.data('subtext') + '</small>';
377
- } else {
378
- subtext = '';
379
- }
380
- if ($this.data('content') && that.options.showContent) {
381
- return $this.data('content');
382
- } else if (typeof $this.attr('title') !== 'undefined') {
383
- return $this.attr('title');
384
- } else {
385
- return icon + $this.html() + subtext;
386
- }
387
- }).toArray();
388
-
389
- //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled
390
- //Convert all the values into a comma delimited string
391
- var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);
392
-
393
- //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
394
- if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {
395
- var max = this.options.selectedTextFormat.split('>');
396
- if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {
397
- notDisabled = this.options.hideDisabled ? ', [disabled]' : '';
398
- var totalCount = this.$element.find('option').not('[data-divider="true"], [data-hidden="true"]' + notDisabled).length,
399
- tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;
400
- title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());
401
- }
402
- }
403
-
404
- this.options.title = this.$element.attr('title');
405
-
406
- if (this.options.selectedTextFormat == 'static') {
407
- title = this.options.title;
408
- }
409
-
410
- //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
411
- if (!title) {
412
- title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;
413
- }
414
-
415
- this.$button.attr('title', htmlEscape(title));
416
- this.$newElement.find('.filter-option').html(title);
417
- },
418
-
419
- /**
420
- * @param [style]
421
- * @param [status]
422
- */
423
- setStyle: function (style, status) {
424
- if (this.$element.attr('class')) {
425
- this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|validate\[.*\]/gi, ''));
426
- }
427
-
428
- var buttonClass = style ? style : this.options.style;
429
-
430
- if (status == 'add') {
431
- this.$button.addClass(buttonClass);
432
- } else if (status == 'remove') {
433
- this.$button.removeClass(buttonClass);
434
- } else {
435
- this.$button.removeClass(this.options.style);
436
- this.$button.addClass(buttonClass);
437
- }
438
- },
439
-
440
- liHeight: function () {
441
- if (this.options.size === false) return;
442
-
443
- var $selectClone = this.$menu.parent().clone().find('> .dropdown-toggle').prop('autofocus', false).end().appendTo('body'),
444
- $menuClone = $selectClone.addClass('open').find('> .dropdown-menu'),
445
- liHeight = $menuClone.find('li').not('.divider').not('.dropdown-header').filter(':visible').children('a').outerHeight(),
446
- headerHeight = this.options.header ? $menuClone.find('.popover-title').outerHeight() : 0,
447
- searchHeight = this.options.liveSearch ? $menuClone.find('.bs-searchbox').outerHeight() : 0,
448
- actionsHeight = this.options.actionsBox ? $menuClone.find('.bs-actionsbox').outerHeight() : 0;
449
-
450
- $selectClone.remove();
451
-
452
- this.$newElement
453
- .data('liHeight', liHeight)
454
- .data('headerHeight', headerHeight)
455
- .data('searchHeight', searchHeight)
456
- .data('actionsHeight', actionsHeight);
457
- },
458
-
459
- setSize: function () {
460
- this.findLis();
461
- var that = this,
462
- menu = this.$menu,
463
- menuInner = menu.find('.inner'),
464
- selectHeight = this.$newElement.outerHeight(),
465
- liHeight = this.$newElement.data('liHeight'),
466
- headerHeight = this.$newElement.data('headerHeight'),
467
- searchHeight = this.$newElement.data('searchHeight'),
468
- actionsHeight = this.$newElement.data('actionsHeight'),
469
- divHeight = this.$lis.filter('.divider').outerHeight(true),
470
- menuPadding = parseInt(menu.css('padding-top')) +
471
- parseInt(menu.css('padding-bottom')) +
472
- parseInt(menu.css('border-top-width')) +
473
- parseInt(menu.css('border-bottom-width')),
474
- notDisabled = this.options.hideDisabled ? ', .disabled' : '',
475
- $window = $(window),
476
- menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2,
477
- menuHeight,
478
- selectOffsetTop,
479
- selectOffsetBot,
480
- posVert = function () {
481
- // JQuery defines a scrollTop function, but in pure JS it's a property
482
- //noinspection JSValidateTypes
483
- selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();
484
- selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;
485
- };
486
- posVert();
487
- if (this.options.header) menu.css('padding-top', 0);
488
-
489
- if (this.options.size == 'auto') {
490
- var getSize = function () {
491
- var minHeight,
492
- lisVis = that.$lis.not('.hide');
493
-
494
- posVert();
495
- menuHeight = selectOffsetBot - menuExtras;
496
-
497
- if (that.options.dropupAuto) {
498
- that.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && ((menuHeight - menuExtras) < menu.height()));
499
- }
500
- if (that.$newElement.hasClass('dropup')) {
501
- menuHeight = selectOffsetTop - menuExtras;
502
- }
503
-
504
- if ((lisVis.length + lisVis.filter('.dropdown-header').length) > 3) {
505
- minHeight = liHeight * 3 + menuExtras - 2;
506
- } else {
507
- minHeight = 0;
508
- }
509
-
510
- menu.css({
511
- 'max-height': menuHeight + 'px',
512
- 'overflow': 'hidden',
513
- 'min-height': minHeight + headerHeight + searchHeight + actionsHeight + 'px'
514
- });
515
- menuInner.css({
516
- 'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - menuPadding + 'px',
517
- 'overflow-y': 'auto',
518
- 'min-height': Math.max(minHeight - menuPadding, 0) + 'px'
519
- });
520
- };
521
- getSize();
522
- this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);
523
- $(window).off('resize.getSize').on('resize.getSize', getSize);
524
- $(window).off('scroll.getSize').on('scroll.getSize', getSize);
525
- } else if (this.options.size && this.options.size != 'auto' && menu.find('li' + notDisabled).length > this.options.size) {
526
- var optIndex = this.$lis.not('.divider' + notDisabled).find(' > *').slice(0, this.options.size).last().parent().index();
527
- var divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;
528
- menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;
529
- if (that.options.dropupAuto) {
530
- //noinspection JSUnusedAssignment
531
- this.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && (menuHeight < menu.height()));
532
- }
533
- menu.css({'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + 'px', 'overflow': 'hidden'});
534
- menuInner.css({'max-height': menuHeight - menuPadding + 'px', 'overflow-y': 'auto'});
535
- }
536
- },
537
-
538
- setWidth: function () {
539
- if (this.options.width == 'auto') {
540
- this.$menu.css('min-width', '0');
541
-
542
- // Get correct width if element hidden
543
- var selectClone = this.$newElement.clone().appendTo('body');
544
- var ulWidth = selectClone.find('> .dropdown-menu').css('width');
545
- var btnWidth = selectClone.css('width', 'auto').find('> button').css('width');
546
- selectClone.remove();
547
-
548
- // Set width to whatever's larger, button title or longest option
549
- this.$newElement.css('width', Math.max(parseInt(ulWidth), parseInt(btnWidth)) + 'px');
550
- } else if (this.options.width == 'fit') {
551
- // Remove inline min-width so width can be changed from 'auto'
552
- this.$menu.css('min-width', '');
553
- this.$newElement.css('width', '').addClass('fit-width');
554
- } else if (this.options.width) {
555
- // Remove inline min-width so width can be changed from 'auto'
556
- this.$menu.css('min-width', '');
557
- this.$newElement.css('width', this.options.width);
558
- } else {
559
- // Remove inline min-width/width so width can be changed
560
- this.$menu.css('min-width', '');
561
- this.$newElement.css('width', '');
562
- }
563
- // Remove fit-width class if width is changed programmatically
564
- if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {
565
- this.$newElement.removeClass('fit-width');
566
- }
567
- },
568
-
569
- selectPosition: function () {
570
- var that = this,
571
- drop = '<div />',
572
- $drop = $(drop),
573
- pos,
574
- actualHeight,
575
- getPlacement = function ($element) {
576
- $drop.addClass($element.attr('class').replace(/form-control/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));
577
- pos = $element.offset();
578
- actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;
579
- $drop.css({
580
- 'top': pos.top + actualHeight,
581
- 'left': pos.left,
582
- 'width': $element[0].offsetWidth,
583
- 'position': 'absolute'
584
- });
585
- };
586
- this.$newElement.on('click', function () {
587
- if (that.isDisabled()) {
588
- return;
589
- }
590
- getPlacement($(this));
591
- $drop.appendTo(that.options.container);
592
- $drop.toggleClass('open', !$(this).hasClass('open'));
593
- $drop.append(that.$menu);
594
- });
595
- $(window).resize(function () {
596
- getPlacement(that.$newElement);
597
- });
598
- $(window).on('scroll', function () {
599
- getPlacement(that.$newElement);
600
- });
601
- $('html').on('click', function (e) {
602
- if ($(e.target).closest(that.$newElement).length < 1) {
603
- $drop.removeClass('open');
604
- }
605
- });
606
- },
607
-
608
- setSelected: function (index, selected) {
609
- this.findLis();
610
- this.$lis.filter('[data-original-index="' + index + '"]').toggleClass('selected', selected);
611
- },
612
-
613
- setDisabled: function (index, disabled) {
614
- this.findLis();
615
- if (disabled) {
616
- this.$lis.filter('[data-original-index="' + index + '"]').addClass('disabled').find('a').attr('href', '#').attr('tabindex', -1);
617
- } else {
618
- this.$lis.filter('[data-original-index="' + index + '"]').removeClass('disabled').find('a').removeAttr('href').attr('tabindex', 0);
619
- }
620
- },
621
-
622
- isDisabled: function () {
623
- return this.$element.is(':disabled');
624
- },
625
-
626
- checkDisabled: function () {
627
- var that = this;
628
-
629
- if (this.isDisabled()) {
630
- this.$button.addClass('disabled').attr('tabindex', -1);
631
- } else {
632
- if (this.$button.hasClass('disabled')) {
633
- this.$button.removeClass('disabled');
634
- }
635
-
636
- if (this.$button.attr('tabindex') == -1) {
637
- if (!this.$element.data('tabindex')) this.$button.removeAttr('tabindex');
638
- }
639
- }
640
-
641
- this.$button.click(function () {
642
- return !that.isDisabled();
643
- });
644
- },
645
-
646
- tabIndex: function () {
647
- if (this.$element.is('[tabindex]')) {
648
- this.$element.data('tabindex', this.$element.attr('tabindex'));
649
- this.$button.attr('tabindex', this.$element.data('tabindex'));
650
- }
651
- },
652
-
653
- clickListener: function () {
654
- var that = this;
655
-
656
- this.$newElement.on('touchstart.dropdown', '.dropdown-menu', function (e) {
657
- e.stopPropagation();
658
- });
659
-
660
- this.$newElement.on('click', function () {
661
- that.setSize();
662
- if (!that.options.liveSearch && !that.multiple) {
663
- setTimeout(function () {
664
- that.$menu.find('.selected a').focus();
665
- }, 10);
666
- }
667
- });
668
-
669
- this.$menu.on('click', 'li a', function (e) {
670
- var $this = $(this),
671
- clickedIndex = $this.parent().data('originalIndex'),
672
- prevValue = that.$element.val(),
673
- prevIndex = that.$element.prop('selectedIndex');
674
-
675
- // Don't close on multi choice menu
676
- if (that.multiple) {
677
- e.stopPropagation();
678
- }
679
-
680
- e.preventDefault();
681
-
682
- //Don't run if we have been disabled
683
- if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {
684
- var $options = that.$element.find('option'),
685
- $option = $options.eq(clickedIndex),
686
- state = $option.prop('selected'),
687
- $optgroup = $option.parent('optgroup'),
688
- maxOptions = that.options.maxOptions,
689
- maxOptionsGrp = $optgroup.data('maxOptions') || false;
690
-
691
- if (!that.multiple) { // Deselect all others if not multi select box
692
- $options.prop('selected', false);
693
- $option.prop('selected', true);
694
- that.$menu.find('.selected').removeClass('selected');
695
- that.setSelected(clickedIndex, true);
696
- } else { // Toggle the one we have chosen if we are multi select.
697
- $option.prop('selected', !state);
698
- that.setSelected(clickedIndex, !state);
699
- $this.blur();
700
-
701
- if ((maxOptions !== false) || (maxOptionsGrp !== false)) {
702
- var maxReached = maxOptions < $options.filter(':selected').length,
703
- maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;
704
-
705
- if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {
706
- if (maxOptions && maxOptions == 1) {
707
- $options.prop('selected', false);
708
- $option.prop('selected', true);
709
- that.$menu.find('.selected').removeClass('selected');
710
- that.setSelected(clickedIndex, true);
711
- } else if (maxOptionsGrp && maxOptionsGrp == 1) {
712
- $optgroup.find('option:selected').prop('selected', false);
713
- $option.prop('selected', true);
714
- var optgroupID = $this.data('optgroup');
715
-
716
- that.$menu.find('.selected').has('a[data-optgroup="' + optgroupID + '"]').removeClass('selected');
717
-
718
- that.setSelected(clickedIndex, true);
719
- } else {
720
- var maxOptionsArr = (typeof that.options.maxOptionsText === 'function') ?
721
- that.options.maxOptionsText(maxOptions, maxOptionsGrp) : that.options.maxOptionsText,
722
- maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),
723
- maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),
724
- $notify = $('<div class="notify"></div>');
725
- // If {var} is set in array, replace it
726
- /** @deprecated */
727
- if (maxOptionsArr[2]) {
728
- maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);
729
- maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);
730
- }
731
-
732
- $option.prop('selected', false);
733
-
734
- that.$menu.append($notify);
735
-
736
- if (maxOptions && maxReached) {
737
- $notify.append($('<div>' + maxTxt + '</div>'));
738
- that.$element.trigger('maxReached.bs.select');
739
- }
740
-
741
- if (maxOptionsGrp && maxReachedGrp) {
742
- $notify.append($('<div>' + maxTxtGrp + '</div>'));
743
- that.$element.trigger('maxReachedGrp.bs.select');
744
- }
745
-
746
- setTimeout(function () {
747
- that.setSelected(clickedIndex, false);
748
- }, 10);
749
-
750
- $notify.delay(750).fadeOut(300, function () {
751
- $(this).remove();
752
- });
753
- }
754
- }
755
- }
756
- }
757
-
758
- if (!that.multiple) {
759
- that.$button.focus();
760
- } else if (that.options.liveSearch) {
761
- that.$searchbox.focus();
762
- }
763
-
764
- // Trigger select 'change'
765
- if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {
766
- that.$element.change();
767
- }
768
- }
769
- });
770
-
771
- this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {
772
- if (e.target == this) {
773
- e.preventDefault();
774
- e.stopPropagation();
775
- if (!that.options.liveSearch) {
776
- that.$button.focus();
777
- } else {
778
- that.$searchbox.focus();
779
- }
780
- }
781
- });
782
-
783
- this.$menu.on('click', 'li.divider, li.dropdown-header', function (e) {
784
- e.preventDefault();
785
- e.stopPropagation();
786
- if (!that.options.liveSearch) {
787
- that.$button.focus();
788
- } else {
789
- that.$searchbox.focus();
790
- }
791
- });
792
-
793
- this.$menu.on('click', '.popover-title .close', function () {
794
- that.$button.focus();
795
- });
796
-
797
- this.$searchbox.on('click', function (e) {
798
- e.stopPropagation();
799
- });
800
-
801
-
802
- this.$menu.on('click', '.actions-btn', function (e) {
803
- if (that.options.liveSearch) {
804
- that.$searchbox.focus();
805
- } else {
806
- that.$button.focus();
807
- }
808
-
809
- e.preventDefault();
810
- e.stopPropagation();
811
-
812
- if ($(this).is('.bs-select-all')) {
813
- that.selectAll();
814
- } else {
815
- that.deselectAll();
816
- }
817
- that.$element.change();
818
- });
819
-
820
- this.$element.change(function () {
821
- that.render(false);
822
- });
823
- },
824
-
825
- liveSearchListener: function () {
826
- var that = this,
827
- no_results = $('<li class="no-results"></li>');
828
-
829
- this.$newElement.on('click.dropdown.data-api touchstart.dropdown.data-api', function () {
830
- that.$menu.find('.active').removeClass('active');
831
- if (!!that.$searchbox.val()) {
832
- that.$searchbox.val('');
833
- that.$lis.not('.is-hidden').removeClass('hide');
834
- if (!!no_results.parent().length) no_results.remove();
835
- }
836
- if (!that.multiple) that.$menu.find('.selected').addClass('active');
837
- setTimeout(function () {
838
- that.$searchbox.focus();
839
- }, 10);
840
- });
841
-
842
- this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {
843
- e.stopPropagation();
844
- });
845
-
846
- this.$searchbox.on('input propertychange', function () {
847
- if (that.$searchbox.val()) {
848
-
849
- if (that.options.searchAccentInsensitive) {
850
- that.$lis.not('.is-hidden').removeClass('hide').find('a').not(':aicontains(' + normalizeToBase(that.$searchbox.val()) + ')').parent().addClass('hide');
851
- } else {
852
- that.$lis.not('.is-hidden').removeClass('hide').find('a').not(':icontains(' + that.$searchbox.val() + ')').parent().addClass('hide');
853
- }
854
-
855
- if (!that.$menu.find('li').filter(':visible:not(.no-results)').length) {
856
- if (!!no_results.parent().length) no_results.remove();
857
- no_results.html(that.options.noneResultsText + ' "' + htmlEscape(that.$searchbox.val()) + '"').show();
858
- that.$menu.find('li').last().after(no_results);
859
- } else if (!!no_results.parent().length) {
860
- no_results.remove();
861
- }
862
-
863
- } else {
864
- that.$lis.not('.is-hidden').removeClass('hide');
865
- if (!!no_results.parent().length) no_results.remove();
866
- }
867
-
868
- that.$menu.find('li.active').removeClass('active');
869
- that.$menu.find('li').filter(':visible:not(.divider)').eq(0).addClass('active').find('a').focus();
870
- $(this).focus();
871
- });
872
- },
873
-
874
- val: function (value) {
875
- if (typeof value !== 'undefined') {
876
- this.$element.val(value);
877
- this.render();
878
-
879
- return this.$element;
880
- } else {
881
- return this.$element.val();
882
- }
883
- },
884
-
885
- selectAll: function () {
886
- this.findLis();
887
- this.$lis.not('.divider').not('.disabled').not('.selected').filter(':visible').find('a').click();
888
- },
889
-
890
- deselectAll: function () {
891
- this.findLis();
892
- this.$lis.not('.divider').not('.disabled').filter('.selected').filter(':visible').find('a').click();
893
- },
894
-
895
- keydown: function (e) {
896
- var $this = $(this),
897
- $parent = ($this.is('input')) ? $this.parent().parent() : $this.parent(),
898
- $items,
899
- that = $parent.data('this'),
900
- index,
901
- next,
902
- first,
903
- last,
904
- prev,
905
- nextPrev,
906
- prevIndex,
907
- isActive,
908
- keyCodeMap = {
909
- 32: ' ',
910
- 48: '0',
911
- 49: '1',
912
- 50: '2',
913
- 51: '3',
914
- 52: '4',
915
- 53: '5',
916
- 54: '6',
917
- 55: '7',
918
- 56: '8',
919
- 57: '9',
920
- 59: ';',
921
- 65: 'a',
922
- 66: 'b',
923
- 67: 'c',
924
- 68: 'd',
925
- 69: 'e',
926
- 70: 'f',
927
- 71: 'g',
928
- 72: 'h',
929
- 73: 'i',
930
- 74: 'j',
931
- 75: 'k',
932
- 76: 'l',
933
- 77: 'm',
934
- 78: 'n',
935
- 79: 'o',
936
- 80: 'p',
937
- 81: 'q',
938
- 82: 'r',
939
- 83: 's',
940
- 84: 't',
941
- 85: 'u',
942
- 86: 'v',
943
- 87: 'w',
944
- 88: 'x',
945
- 89: 'y',
946
- 90: 'z',
947
- 96: '0',
948
- 97: '1',
949
- 98: '2',
950
- 99: '3',
951
- 100: '4',
952
- 101: '5',
953
- 102: '6',
954
- 103: '7',
955
- 104: '8',
956
- 105: '9'
957
- };
958
-
959
- if (that.options.liveSearch) $parent = $this.parent().parent();
960
-
961
- if (that.options.container) $parent = that.$menu;
962
-
963
- $items = $('[role=menu] li a', $parent);
964
-
965
- isActive = that.$menu.parent().hasClass('open');
966
-
967
- if (!isActive && /([0-9]|[A-z])/.test(String.fromCharCode(e.keyCode))) {
968
- if (!that.options.container) {
969
- that.setSize();
970
- that.$menu.parent().addClass('open');
971
- isActive = true;
972
- } else {
973
- that.$newElement.trigger('click');
974
- }
975
- that.$searchbox.focus();
976
- }
977
-
978
- if (that.options.liveSearch) {
979
- if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && that.$menu.find('.active').length === 0) {
980
- e.preventDefault();
981
- that.$menu.parent().removeClass('open');
982
- that.$button.focus();
983
- }
984
- $items = $('[role=menu] li:not(.divider):not(.dropdown-header):visible', $parent);
985
- if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {
986
- if ($items.filter('.active').length === 0) {
987
- if (that.options.searchAccentInsensitive) {
988
- $items = that.$newElement.find('li').filter(':aicontains(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');
989
- } else {
990
- $items = that.$newElement.find('li').filter(':icontains(' + keyCodeMap[e.keyCode] + ')');
991
- }
992
- }
993
- }
994
- }
995
-
996
- if (!$items.length) return;
997
-
998
- if (/(38|40)/.test(e.keyCode.toString(10))) {
999
- index = $items.index($items.filter(':focus'));
1000
- first = $items.parent(':not(.disabled):visible').first().index();
1001
- last = $items.parent(':not(.disabled):visible').last().index();
1002
- next = $items.eq(index).parent().nextAll(':not(.disabled):visible').eq(0).index();
1003
- prev = $items.eq(index).parent().prevAll(':not(.disabled):visible').eq(0).index();
1004
- nextPrev = $items.eq(next).parent().prevAll(':not(.disabled):visible').eq(0).index();
1005
-
1006
- if (that.options.liveSearch) {
1007
- $items.each(function (i) {
1008
- if ($(this).is(':not(.disabled)')) {
1009
- $(this).data('index', i);
1010
- }
1011
- });
1012
- index = $items.index($items.filter('.active'));
1013
- first = $items.filter(':not(.disabled):visible').first().data('index');
1014
- last = $items.filter(':not(.disabled):visible').last().data('index');
1015
- next = $items.eq(index).nextAll(':not(.disabled):visible').eq(0).data('index');
1016
- prev = $items.eq(index).prevAll(':not(.disabled):visible').eq(0).data('index');
1017
- nextPrev = $items.eq(next).prevAll(':not(.disabled):visible').eq(0).data('index');
1018
- }
1019
-
1020
- prevIndex = $this.data('prevIndex');
1021
-
1022
- if (e.keyCode == 38) {
1023
- if (that.options.liveSearch) index -= 1;
1024
- if (index != nextPrev && index > prev) index = prev;
1025
- if (index < first) index = first;
1026
- if (index == prevIndex) index = last;
1027
- }
1028
-
1029
- if (e.keyCode == 40) {
1030
- if (that.options.liveSearch) index += 1;
1031
- if (index == -1) index = 0;
1032
- if (index != nextPrev && index < next) index = next;
1033
- if (index > last) index = last;
1034
- if (index == prevIndex) index = first;
1035
- }
1036
-
1037
- $this.data('prevIndex', index);
1038
-
1039
- if (!that.options.liveSearch) {
1040
- $items.eq(index).focus();
1041
- } else {
1042
- e.preventDefault();
1043
- if (!$this.is('.dropdown-toggle')) {
1044
- $items.removeClass('active');
1045
- $items.eq(index).addClass('active').find('a').focus();
1046
- $this.focus();
1047
- }
1048
- }
1049
-
1050
- } else if (!$this.is('input')) {
1051
- var keyIndex = [],
1052
- count,
1053
- prevKey;
1054
-
1055
- $items.each(function () {
1056
- if ($(this).parent().is(':not(.disabled)')) {
1057
- if ($.trim($(this).text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {
1058
- keyIndex.push($(this).parent().index());
1059
- }
1060
- }
1061
- });
1062
-
1063
- count = $(document).data('keycount');
1064
- count++;
1065
- $(document).data('keycount', count);
1066
-
1067
- prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);
1068
-
1069
- if (prevKey != keyCodeMap[e.keyCode]) {
1070
- count = 1;
1071
- $(document).data('keycount', count);
1072
- } else if (count >= keyIndex.length) {
1073
- $(document).data('keycount', 0);
1074
- if (count > keyIndex.length) count = 1;
1075
- }
1076
-
1077
- $items.eq(keyIndex[count - 1]).focus();
1078
- }
1079
-
1080
- // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu.
1081
- if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {
1082
- if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();
1083
- if (!that.options.liveSearch) {
1084
- $(':focus').click();
1085
- } else if (!/(32)/.test(e.keyCode.toString(10))) {
1086
- that.$menu.find('.active a').click();
1087
- $this.focus();
1088
- }
1089
- $(document).data('keycount', 0);
1090
- }
1091
-
1092
- if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {
1093
- that.$menu.parent().removeClass('open');
1094
- that.$button.focus();
1095
- }
1096
- },
1097
-
1098
- mobile: function () {
1099
- this.$element.addClass('mobile-device').appendTo(this.$newElement);
1100
- if (this.options.container) this.$menu.hide();
1101
- },
1102
-
1103
- refresh: function () {
1104
- this.$lis = null;
1105
- this.reloadLi();
1106
- this.render();
1107
- this.setWidth();
1108
- this.setStyle();
1109
- this.checkDisabled();
1110
- this.liHeight();
1111
- },
1112
-
1113
- update: function () {
1114
- this.reloadLi();
1115
- this.setWidth();
1116
- this.setStyle();
1117
- this.checkDisabled();
1118
- this.liHeight();
1119
- },
1120
-
1121
- hide: function () {
1122
- this.$newElement.hide();
1123
- },
1124
-
1125
- show: function () {
1126
- this.$newElement.show();
1127
- },
1128
-
1129
- remove: function () {
1130
- this.$newElement.remove();
1131
- this.$element.remove();
1132
- }
1133
- };
1134
-
1135
- // SELECTPICKER PLUGIN DEFINITION
1136
- // ==============================
1137
- function Plugin(option, event) {
1138
- // get the args of the outer function..
1139
- var args = arguments;
1140
- // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
1141
- // to get lost
1142
- //noinspection JSDuplicatedDeclaration
1143
- var _option = option,
1144
- option = args[0],
1145
- event = args[1];
1146
- [].shift.apply(args);
1147
-
1148
- // This fixes a bug in the js implementation on android 2.3 #715
1149
- if (typeof option == 'undefined') {
1150
- option = _option;
1151
- }
1152
-
1153
- var value;
1154
- var chain = this.each(function () {
1155
- var $this = $(this);
1156
- if ($this.is('select')) {
1157
- var data = $this.data('selectpicker'),
1158
- options = typeof option == 'object' && option;
1159
-
1160
- if (!data) {
1161
- var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);
1162
- $this.data('selectpicker', (data = new Selectpicker(this, config, event)));
1163
- } else if (options) {
1164
- for (var i in options) {
1165
- if (options.hasOwnProperty(i)) {
1166
- data.options[i] = options[i];
1167
- }
1168
- }
1169
- }
1170
-
1171
- if (typeof option == 'string') {
1172
- if (data[option] instanceof Function) {
1173
- value = data[option].apply(data, args);
1174
- } else {
1175
- value = data.options[option];
1176
- }
1177
- }
1178
- }
1
+ /*!
2
+ * Bootstrap-select v1.9.4 (http://silviomoreto.github.io/bootstrap-select)
3
+ *
4
+ * Copyright 2013-2016 bootstrap-select
5
+ * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
6
+ */
7
+
8
+ (function (root, factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ // AMD. Register as an anonymous module unless amdModuleId is set
11
+ define(["jquery"], function (a0) {
12
+ return (factory(a0));
1179
13
  });
1180
-
1181
- if (typeof value !== 'undefined') {
1182
- //noinspection JSUnusedAssignment
1183
- return value;
1184
- } else {
1185
- return chain;
1186
- }
14
+ } else if (typeof exports === 'object') {
15
+ // Node. Does not work with strict CommonJS, but
16
+ // only CommonJS-like environments that support module.exports,
17
+ // like Node.
18
+ module.exports = factory(require("jquery"));
19
+ } else {
20
+ factory(jQuery);
1187
21
  }
1188
-
1189
- var old = $.fn.selectpicker;
1190
- $.fn.selectpicker = Plugin;
1191
- $.fn.selectpicker.Constructor = Selectpicker;
1192
-
1193
- // SELECTPICKER NO CONFLICT
1194
- // ========================
1195
- $.fn.selectpicker.noConflict = function () {
1196
- $.fn.selectpicker = old;
1197
- return this;
1198
- };
1199
-
1200
- $(document)
1201
- .data('keycount', 0)
1202
- .on('keydown', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bs-searchbox input', Selectpicker.prototype.keydown)
1203
- .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bs-searchbox input', function (e) {
1204
- e.stopPropagation();
1205
- });
1206
-
1207
- // SELECTPICKER DATA-API
1208
- // =====================
1209
- $(window).on('load.bs.select.data-api', function () {
1210
- $('.selectpicker').each(function () {
1211
- var $selectpicker = $(this);
1212
- Plugin.call($selectpicker, $selectpicker.data());
1213
- })
1214
- });
1215
- })(jQuery);
22
+ }(this, function (jQuery) {
23
+
24
+ (function ($) {
25
+ 'use strict';
26
+
27
+ //<editor-fold desc="Shims">
28
+ if (!String.prototype.includes) {
29
+ (function () {
30
+ 'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
31
+ var toString = {}.toString;
32
+ var defineProperty = (function () {
33
+ // IE 8 only supports `Object.defineProperty` on DOM elements
34
+ try {
35
+ var object = {};
36
+ var $defineProperty = Object.defineProperty;
37
+ var result = $defineProperty(object, object, object) && $defineProperty;
38
+ } catch (error) {
39
+ }
40
+ return result;
41
+ }());
42
+ var indexOf = ''.indexOf;
43
+ var includes = function (search) {
44
+ if (this == null) {
45
+ throw new TypeError();
46
+ }
47
+ var string = String(this);
48
+ if (search && toString.call(search) == '[object RegExp]') {
49
+ throw new TypeError();
50
+ }
51
+ var stringLength = string.length;
52
+ var searchString = String(search);
53
+ var searchLength = searchString.length;
54
+ var position = arguments.length > 1 ? arguments[1] : undefined;
55
+ // `ToInteger`
56
+ var pos = position ? Number(position) : 0;
57
+ if (pos != pos) { // better `isNaN`
58
+ pos = 0;
59
+ }
60
+ var start = Math.min(Math.max(pos, 0), stringLength);
61
+ // Avoid the `indexOf` call if no match is possible
62
+ if (searchLength + start > stringLength) {
63
+ return false;
64
+ }
65
+ return indexOf.call(string, searchString, pos) != -1;
66
+ };
67
+ if (defineProperty) {
68
+ defineProperty(String.prototype, 'includes', {
69
+ 'value': includes,
70
+ 'configurable': true,
71
+ 'writable': true
72
+ });
73
+ } else {
74
+ String.prototype.includes = includes;
75
+ }
76
+ }());
77
+ }
78
+
79
+ if (!String.prototype.startsWith) {
80
+ (function () {
81
+ 'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
82
+ var defineProperty = (function () {
83
+ // IE 8 only supports `Object.defineProperty` on DOM elements
84
+ try {
85
+ var object = {};
86
+ var $defineProperty = Object.defineProperty;
87
+ var result = $defineProperty(object, object, object) && $defineProperty;
88
+ } catch (error) {
89
+ }
90
+ return result;
91
+ }());
92
+ var toString = {}.toString;
93
+ var startsWith = function (search) {
94
+ if (this == null) {
95
+ throw new TypeError();
96
+ }
97
+ var string = String(this);
98
+ if (search && toString.call(search) == '[object RegExp]') {
99
+ throw new TypeError();
100
+ }
101
+ var stringLength = string.length;
102
+ var searchString = String(search);
103
+ var searchLength = searchString.length;
104
+ var position = arguments.length > 1 ? arguments[1] : undefined;
105
+ // `ToInteger`
106
+ var pos = position ? Number(position) : 0;
107
+ if (pos != pos) { // better `isNaN`
108
+ pos = 0;
109
+ }
110
+ var start = Math.min(Math.max(pos, 0), stringLength);
111
+ // Avoid the `indexOf` call if no match is possible
112
+ if (searchLength + start > stringLength) {
113
+ return false;
114
+ }
115
+ var index = -1;
116
+ while (++index < searchLength) {
117
+ if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
118
+ return false;
119
+ }
120
+ }
121
+ return true;
122
+ };
123
+ if (defineProperty) {
124
+ defineProperty(String.prototype, 'startsWith', {
125
+ 'value': startsWith,
126
+ 'configurable': true,
127
+ 'writable': true
128
+ });
129
+ } else {
130
+ String.prototype.startsWith = startsWith;
131
+ }
132
+ }());
133
+ }
134
+
135
+ if (!Object.keys) {
136
+ Object.keys = function (
137
+ o, // object
138
+ k, // key
139
+ r // result array
140
+ ){
141
+ // initialize object and result
142
+ r=[];
143
+ // iterate over object keys
144
+ for (k in o)
145
+ // fill result array with non-prototypical keys
146
+ r.hasOwnProperty.call(o, k) && r.push(k);
147
+ // return result
148
+ return r;
149
+ };
150
+ }
151
+
152
+ $.fn.triggerNative = function (eventName) {
153
+ var el = this[0],
154
+ event;
155
+
156
+ if (el.dispatchEvent) {
157
+ if (typeof Event === 'function') {
158
+ // For modern browsers
159
+ event = new Event(eventName, {
160
+ bubbles: true
161
+ });
162
+ } else {
163
+ // For IE since it doesn't support Event constructor
164
+ event = document.createEvent('Event');
165
+ event.initEvent(eventName, true, false);
166
+ }
167
+
168
+ el.dispatchEvent(event);
169
+ } else {
170
+ if (el.fireEvent) {
171
+ event = document.createEventObject();
172
+ event.eventType = eventName;
173
+ el.fireEvent('on' + eventName, event);
174
+ }
175
+
176
+ this.trigger(eventName);
177
+ }
178
+ };
179
+ //</editor-fold>
180
+
181
+ // Case insensitive contains search
182
+ $.expr[':'].icontains = function (obj, index, meta) {
183
+ var $obj = $(obj);
184
+ var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();
185
+ return haystack.includes(meta[3].toUpperCase());
186
+ };
187
+
188
+ // Case insensitive begins search
189
+ $.expr[':'].ibegins = function (obj, index, meta) {
190
+ var $obj = $(obj);
191
+ var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();
192
+ return haystack.startsWith(meta[3].toUpperCase());
193
+ };
194
+
195
+ // Case and accent insensitive contains search
196
+ $.expr[':'].aicontains = function (obj, index, meta) {
197
+ var $obj = $(obj);
198
+ var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();
199
+ return haystack.includes(meta[3].toUpperCase());
200
+ };
201
+
202
+ // Case and accent insensitive begins search
203
+ $.expr[':'].aibegins = function (obj, index, meta) {
204
+ var $obj = $(obj);
205
+ var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();
206
+ return haystack.startsWith(meta[3].toUpperCase());
207
+ };
208
+
209
+ /**
210
+ * Remove all diatrics from the given text.
211
+ * @access private
212
+ * @param {String} text
213
+ * @returns {String}
214
+ */
215
+ function normalizeToBase(text) {
216
+ var rExps = [
217
+ {re: /[\xC0-\xC6]/g, ch: "A"},
218
+ {re: /[\xE0-\xE6]/g, ch: "a"},
219
+ {re: /[\xC8-\xCB]/g, ch: "E"},
220
+ {re: /[\xE8-\xEB]/g, ch: "e"},
221
+ {re: /[\xCC-\xCF]/g, ch: "I"},
222
+ {re: /[\xEC-\xEF]/g, ch: "i"},
223
+ {re: /[\xD2-\xD6]/g, ch: "O"},
224
+ {re: /[\xF2-\xF6]/g, ch: "o"},
225
+ {re: /[\xD9-\xDC]/g, ch: "U"},
226
+ {re: /[\xF9-\xFC]/g, ch: "u"},
227
+ {re: /[\xC7-\xE7]/g, ch: "c"},
228
+ {re: /[\xD1]/g, ch: "N"},
229
+ {re: /[\xF1]/g, ch: "n"}
230
+ ];
231
+ $.each(rExps, function () {
232
+ text = text.replace(this.re, this.ch);
233
+ });
234
+ return text;
235
+ }
236
+
237
+
238
+ function htmlEscape(html) {
239
+ var escapeMap = {
240
+ '&': '&amp;',
241
+ '<': '&lt;',
242
+ '>': '&gt;',
243
+ '"': '&quot;',
244
+ "'": '&#x27;',
245
+ '`': '&#x60;'
246
+ };
247
+ var source = '(?:' + Object.keys(escapeMap).join('|') + ')',
248
+ testRegexp = new RegExp(source),
249
+ replaceRegexp = new RegExp(source, 'g'),
250
+ string = html == null ? '' : '' + html;
251
+ return testRegexp.test(string) ? string.replace(replaceRegexp, function (match) {
252
+ return escapeMap[match];
253
+ }) : string;
254
+ }
255
+
256
+ var Selectpicker = function (element, options, e) {
257
+ if (e) {
258
+ e.stopPropagation();
259
+ e.preventDefault();
260
+ }
261
+
262
+ this.$element = $(element);
263
+ this.$newElement = null;
264
+ this.$button = null;
265
+ this.$menu = null;
266
+ this.$lis = null;
267
+ this.options = options;
268
+
269
+ // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a
270
+ // data-attribute)
271
+ if (this.options.title === null) {
272
+ this.options.title = this.$element.attr('title');
273
+ }
274
+
275
+ //Expose public methods
276
+ this.val = Selectpicker.prototype.val;
277
+ this.render = Selectpicker.prototype.render;
278
+ this.refresh = Selectpicker.prototype.refresh;
279
+ this.setStyle = Selectpicker.prototype.setStyle;
280
+ this.selectAll = Selectpicker.prototype.selectAll;
281
+ this.deselectAll = Selectpicker.prototype.deselectAll;
282
+ this.destroy = Selectpicker.prototype.destroy;
283
+ this.remove = Selectpicker.prototype.remove;
284
+ this.show = Selectpicker.prototype.show;
285
+ this.hide = Selectpicker.prototype.hide;
286
+
287
+ this.init();
288
+ };
289
+
290
+ Selectpicker.VERSION = '1.9.4';
291
+
292
+ // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.
293
+ Selectpicker.DEFAULTS = {
294
+ noneSelectedText: 'Nothing selected',
295
+ noneResultsText: 'No results matched {0}',
296
+ countSelectedText: function (numSelected, numTotal) {
297
+ return (numSelected == 1) ? "{0} item selected" : "{0} items selected";
298
+ },
299
+ maxOptionsText: function (numAll, numGroup) {
300
+ return [
301
+ (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',
302
+ (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'
303
+ ];
304
+ },
305
+ selectAllText: 'Select All',
306
+ deselectAllText: 'Deselect All',
307
+ doneButton: false,
308
+ doneButtonText: 'Close',
309
+ multipleSeparator: ', ',
310
+ styleBase: 'btn',
311
+ style: 'btn-default',
312
+ size: 'auto',
313
+ title: null,
314
+ selectedTextFormat: 'values',
315
+ width: false,
316
+ container: false,
317
+ hideDisabled: false,
318
+ showSubtext: false,
319
+ showIcon: true,
320
+ showContent: true,
321
+ dropupAuto: true,
322
+ header: false,
323
+ liveSearch: false,
324
+ liveSearchPlaceholder: null,
325
+ liveSearchNormalize: false,
326
+ liveSearchStyle: 'contains',
327
+ actionsBox: false,
328
+ iconBase: 'glyphicon',
329
+ tickIcon: 'glyphicon-ok',
330
+ template: {
331
+ caret: '<span class="caret"></span>'
332
+ },
333
+ maxOptions: false,
334
+ mobile: false,
335
+ selectOnTab: false,
336
+ dropdownAlignRight: false
337
+ };
338
+
339
+ Selectpicker.prototype = {
340
+
341
+ constructor: Selectpicker,
342
+
343
+ init: function () {
344
+ var that = this,
345
+ id = this.$element.attr('id');
346
+
347
+ // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility
348
+ // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index="' + index + '"]')
349
+ this.liObj = {};
350
+ this.multiple = this.$element.prop('multiple');
351
+ this.autofocus = this.$element.prop('autofocus');
352
+ this.$newElement = this.createView();
353
+ this.$element
354
+ .after(this.$newElement)
355
+ .appendTo(this.$newElement);
356
+ this.$button = this.$newElement.children('button');
357
+ this.$menu = this.$newElement.children('.dropdown-menu');
358
+ this.$menuInner = this.$menu.children('.inner');
359
+ this.$searchbox = this.$menu.find('input');
360
+
361
+ if (this.options.dropdownAlignRight)
362
+ this.$menu.addClass('dropdown-menu-right');
363
+
364
+ if (typeof id !== 'undefined') {
365
+ this.$button.attr('data-id', id);
366
+ $('label[for="' + id + '"]').click(function (e) {
367
+ e.preventDefault();
368
+ that.$button.focus();
369
+ });
370
+ }
371
+
372
+ this.checkDisabled();
373
+ this.clickListener();
374
+ if (this.options.liveSearch) this.liveSearchListener();
375
+ this.render();
376
+ this.setStyle();
377
+ this.setWidth();
378
+ if (this.options.container) this.selectPosition();
379
+ this.$menu.data('this', this);
380
+ this.$newElement.data('this', this);
381
+ if (this.options.mobile) this.mobile();
382
+
383
+ this.$newElement.on({
384
+ 'hide.bs.dropdown': function (e) {
385
+ that.$element.trigger('hide.bs.select', e);
386
+ },
387
+ 'hidden.bs.dropdown': function (e) {
388
+ that.$element.trigger('hidden.bs.select', e);
389
+ },
390
+ 'show.bs.dropdown': function (e) {
391
+ that.$element.trigger('show.bs.select', e);
392
+ },
393
+ 'shown.bs.dropdown': function (e) {
394
+ that.$element.trigger('shown.bs.select', e);
395
+ }
396
+ });
397
+
398
+ if (that.$element[0].hasAttribute('required')) {
399
+ this.$element.on('invalid', function () {
400
+ that.$button
401
+ .addClass('bs-invalid')
402
+ .focus();
403
+
404
+ that.$element.on({
405
+ 'focus.bs.select': function () {
406
+ that.$button.focus();
407
+ that.$element.off('focus.bs.select');
408
+ },
409
+ 'shown.bs.select': function () {
410
+ that.$element
411
+ .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened
412
+ .off('shown.bs.select');
413
+ },
414
+ 'rendered.bs.select': function () {
415
+ // if select is no longer invalid, remove the bs-invalid class
416
+ if (this.validity.valid) that.$button.removeClass('bs-invalid');
417
+ that.$element.off('rendered.bs.select');
418
+ }
419
+ });
420
+
421
+ });
422
+ }
423
+
424
+ setTimeout(function () {
425
+ that.$element.trigger('loaded.bs.select');
426
+ });
427
+ },
428
+
429
+ createDropdown: function () {
430
+ // Options
431
+ // If we are multiple, then add the show-tick class by default
432
+ var multiple = this.multiple ? ' show-tick' : '',
433
+ inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',
434
+ autofocus = this.autofocus ? ' autofocus' : '';
435
+ // Elements
436
+ var header = this.options.header ? '<div class="popover-title"><button type="button" class="close" aria-hidden="true">&times;</button>' + this.options.header + '</div>' : '';
437
+ var searchbox = this.options.liveSearch ?
438
+ '<div class="bs-searchbox">' +
439
+ '<input type="text" class="form-control" autocomplete="off"' +
440
+ (null === this.options.liveSearchPlaceholder ? '' : ' placeholder="' + htmlEscape(this.options.liveSearchPlaceholder) + '"') + '>' +
441
+ '</div>'
442
+ : '';
443
+ var actionsbox = this.multiple && this.options.actionsBox ?
444
+ '<div class="bs-actionsbox">' +
445
+ '<div class="btn-group btn-group-sm btn-block">' +
446
+ '<button type="button" class="actions-btn bs-select-all btn btn-default">' +
447
+ this.options.selectAllText +
448
+ '</button>' +
449
+ '<button type="button" class="actions-btn bs-deselect-all btn btn-default">' +
450
+ this.options.deselectAllText +
451
+ '</button>' +
452
+ '</div>' +
453
+ '</div>'
454
+ : '';
455
+ var donebutton = this.multiple && this.options.doneButton ?
456
+ '<div class="bs-donebutton">' +
457
+ '<div class="btn-group btn-block">' +
458
+ '<button type="button" class="btn btn-sm btn-default">' +
459
+ this.options.doneButtonText +
460
+ '</button>' +
461
+ '</div>' +
462
+ '</div>'
463
+ : '';
464
+ var drop =
465
+ '<div class="btn-group bootstrap-select' + multiple + inputGroup + '">' +
466
+ '<button type="button" class="' + this.options.styleBase + ' dropdown-toggle" data-toggle="dropdown"' + autofocus + '>' +
467
+ '<span class="filter-option pull-left"></span>&nbsp;' +
468
+ '<span class="bs-caret">' +
469
+ this.options.template.caret +
470
+ '</span>' +
471
+ '</button>' +
472
+ '<div class="dropdown-menu open">' +
473
+ header +
474
+ searchbox +
475
+ actionsbox +
476
+ '<ul class="dropdown-menu inner" role="menu">' +
477
+ '</ul>' +
478
+ donebutton +
479
+ '</div>' +
480
+ '</div>';
481
+
482
+ return $(drop);
483
+ },
484
+
485
+ createView: function () {
486
+ var $drop = this.createDropdown(),
487
+ li = this.createLi();
488
+
489
+ $drop.find('ul')[0].innerHTML = li;
490
+ return $drop;
491
+ },
492
+
493
+ reloadLi: function () {
494
+ //Remove all children.
495
+ this.destroyLi();
496
+ //Re build
497
+ var li = this.createLi();
498
+ this.$menuInner[0].innerHTML = li;
499
+ },
500
+
501
+ destroyLi: function () {
502
+ this.$menu.find('li').remove();
503
+ },
504
+
505
+ createLi: function () {
506
+ var that = this,
507
+ _li = [],
508
+ optID = 0,
509
+ titleOption = document.createElement('option'),
510
+ liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct
511
+
512
+ // Helper functions
513
+ /**
514
+ * @param content
515
+ * @param [index]
516
+ * @param [classes]
517
+ * @param [optgroup]
518
+ * @returns {string}
519
+ */
520
+ var generateLI = function (content, index, classes, optgroup) {
521
+ return '<li' +
522
+ ((typeof classes !== 'undefined' & '' !== classes) ? ' class="' + classes + '"' : '') +
523
+ ((typeof index !== 'undefined' & null !== index) ? ' data-original-index="' + index + '"' : '') +
524
+ ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup="' + optgroup + '"' : '') +
525
+ '>' + content + '</li>';
526
+ };
527
+
528
+ /**
529
+ * @param text
530
+ * @param [classes]
531
+ * @param [inline]
532
+ * @param [tokens]
533
+ * @returns {string}
534
+ */
535
+ var generateA = function (text, classes, inline, tokens) {
536
+ return '<a tabindex="0"' +
537
+ (typeof classes !== 'undefined' ? ' class="' + classes + '"' : '') +
538
+ (typeof inline !== 'undefined' ? ' style="' + inline + '"' : '') +
539
+ (that.options.liveSearchNormalize ? ' data-normalized-text="' + normalizeToBase(htmlEscape(text)) + '"' : '') +
540
+ (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens="' + tokens + '"' : '') +
541
+ '>' + text +
542
+ '<span class="' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark"></span>' +
543
+ '</a>';
544
+ };
545
+
546
+ if (this.options.title && !this.multiple) {
547
+ // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased
548
+ // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended
549
+ liIndex--;
550
+
551
+ if (!this.$element.find('.bs-title-option').length) {
552
+ // Use native JS to prepend option (faster)
553
+ var element = this.$element[0];
554
+ titleOption.className = 'bs-title-option';
555
+ titleOption.appendChild(document.createTextNode(this.options.title));
556
+ titleOption.value = '';
557
+ element.insertBefore(titleOption, element.firstChild);
558
+ // Check if selected attribute is already set on an option. If not, select the titleOption option.
559
+ if ($(element.options[element.selectedIndex]).attr('selected') === undefined) titleOption.selected = true;
560
+ }
561
+ }
562
+
563
+ this.$element.find('option').each(function (index) {
564
+ var $this = $(this);
565
+
566
+ liIndex++;
567
+
568
+ if ($this.hasClass('bs-title-option')) return;
569
+
570
+ // Get the class and text for the option
571
+ var optionClass = this.className || '',
572
+ inline = this.style.cssText,
573
+ text = $this.data('content') ? $this.data('content') : $this.html(),
574
+ tokens = $this.data('tokens') ? $this.data('tokens') : null,
575
+ subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class="text-muted">' + $this.data('subtext') + '</small>' : '',
576
+ icon = typeof $this.data('icon') !== 'undefined' ? '<span class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></span> ' : '',
577
+ isOptgroup = this.parentNode.tagName === 'OPTGROUP',
578
+ isDisabled = this.disabled || (isOptgroup && this.parentNode.disabled);
579
+
580
+ if (icon !== '' && isDisabled) {
581
+ icon = '<span>' + icon + '</span>';
582
+ }
583
+
584
+ if (that.options.hideDisabled && isDisabled && !isOptgroup) {
585
+ liIndex--;
586
+ return;
587
+ }
588
+
589
+ if (!$this.data('content')) {
590
+ // Prepend any icon and append any subtext to the main text.
591
+ text = icon + '<span class="text">' + text + subtext + '</span>';
592
+ }
593
+
594
+ if (isOptgroup && $this.data('divider') !== true) {
595
+ var optGroupClass = ' ' + this.parentNode.className || '';
596
+
597
+ if ($this.index() === 0) { // Is it the first option of the optgroup?
598
+ optID += 1;
599
+
600
+ // Get the opt group label
601
+ var label = this.parentNode.label,
602
+ labelSubtext = typeof $this.parent().data('subtext') !== 'undefined' ? '<small class="text-muted">' + $this.parent().data('subtext') + '</small>' : '',
603
+ labelIcon = $this.parent().data('icon') ? '<span class="' + that.options.iconBase + ' ' + $this.parent().data('icon') + '"></span> ' : '';
604
+
605
+ label = labelIcon + '<span class="text">' + label + labelSubtext + '</span>';
606
+
607
+ if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?
608
+ liIndex++;
609
+ _li.push(generateLI('', null, 'divider', optID + 'div'));
610
+ }
611
+ liIndex++;
612
+ _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));
613
+ }
614
+
615
+ if (that.options.hideDisabled && isDisabled) {
616
+ liIndex--;
617
+ return;
618
+ }
619
+
620
+ _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));
621
+ } else if ($this.data('divider') === true) {
622
+ _li.push(generateLI('', index, 'divider'));
623
+ } else if ($this.data('hidden') === true) {
624
+ _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));
625
+ } else {
626
+ if (this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP') {
627
+ liIndex++;
628
+ _li.push(generateLI('', null, 'divider', optID + 'div'));
629
+ }
630
+ _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));
631
+ }
632
+
633
+ that.liObj[index] = liIndex;
634
+ });
635
+
636
+ //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button
637
+ if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {
638
+ this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
639
+ }
640
+
641
+ return _li.join('');
642
+ },
643
+
644
+ findLis: function () {
645
+ if (this.$lis == null) this.$lis = this.$menu.find('li');
646
+ return this.$lis;
647
+ },
648
+
649
+ /**
650
+ * @param [updateLi] defaults to true
651
+ */
652
+ render: function (updateLi) {
653
+ var that = this,
654
+ notDisabled;
655
+
656
+ //Update the LI to match the SELECT
657
+ if (updateLi !== false) {
658
+ this.$element.find('option').each(function (index) {
659
+ var $lis = that.findLis().eq(that.liObj[index]);
660
+
661
+ that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);
662
+ that.setSelected(index, this.selected, $lis);
663
+ });
664
+ }
665
+
666
+ this.tabIndex();
667
+
668
+ var selectedItems = this.$element.find('option').map(function () {
669
+ if (this.selected) {
670
+ if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;
671
+
672
+ var $this = $(this),
673
+ icon = $this.data('icon') && that.options.showIcon ? '<i class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></i> ' : '',
674
+ subtext;
675
+
676
+ if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {
677
+ subtext = ' <small class="text-muted">' + $this.data('subtext') + '</small>';
678
+ } else {
679
+ subtext = '';
680
+ }
681
+ if (typeof $this.attr('title') !== 'undefined') {
682
+ return $this.attr('title');
683
+ } else if ($this.data('content') && that.options.showContent) {
684
+ return $this.data('content');
685
+ } else {
686
+ return icon + $this.html() + subtext;
687
+ }
688
+ }
689
+ }).toArray();
690
+
691
+ //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled
692
+ //Convert all the values into a comma delimited string
693
+ var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);
694
+
695
+ //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
696
+ if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {
697
+ var max = this.options.selectedTextFormat.split('>');
698
+ if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {
699
+ notDisabled = this.options.hideDisabled ? ', [disabled]' : '';
700
+ var totalCount = this.$element.find('option').not('[data-divider="true"], [data-hidden="true"]' + notDisabled).length,
701
+ tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;
702
+ title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());
703
+ }
704
+ }
705
+
706
+ if (this.options.title == undefined) {
707
+ this.options.title = this.$element.attr('title');
708
+ }
709
+
710
+ if (this.options.selectedTextFormat == 'static') {
711
+ title = this.options.title;
712
+ }
713
+
714
+ //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
715
+ if (!title) {
716
+ title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;
717
+ }
718
+
719
+ //strip all html-tags and trim the result
720
+ this.$button.attr('title', $.trim(title.replace(/<[^>]*>?/g, '')));
721
+ this.$button.children('.filter-option').html(title);
722
+
723
+ this.$element.trigger('rendered.bs.select');
724
+ },
725
+
726
+ /**
727
+ * @param [style]
728
+ * @param [status]
729
+ */
730
+ setStyle: function (style, status) {
731
+ if (this.$element.attr('class')) {
732
+ this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, ''));
733
+ }
734
+
735
+ var buttonClass = style ? style : this.options.style;
736
+
737
+ if (status == 'add') {
738
+ this.$button.addClass(buttonClass);
739
+ } else if (status == 'remove') {
740
+ this.$button.removeClass(buttonClass);
741
+ } else {
742
+ this.$button.removeClass(this.options.style);
743
+ this.$button.addClass(buttonClass);
744
+ }
745
+ },
746
+
747
+ liHeight: function (refresh) {
748
+ if (!refresh && (this.options.size === false || this.sizeInfo)) return;
749
+
750
+ var newElement = document.createElement('div'),
751
+ menu = document.createElement('div'),
752
+ menuInner = document.createElement('ul'),
753
+ divider = document.createElement('li'),
754
+ li = document.createElement('li'),
755
+ a = document.createElement('a'),
756
+ text = document.createElement('span'),
757
+ header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,
758
+ search = this.options.liveSearch ? document.createElement('div') : null,
759
+ actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,
760
+ doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;
761
+
762
+ text.className = 'text';
763
+ newElement.className = this.$menu[0].parentNode.className + ' open';
764
+ menu.className = 'dropdown-menu open';
765
+ menuInner.className = 'dropdown-menu inner';
766
+ divider.className = 'divider';
767
+
768
+ text.appendChild(document.createTextNode('Inner text'));
769
+ a.appendChild(text);
770
+ li.appendChild(a);
771
+ menuInner.appendChild(li);
772
+ menuInner.appendChild(divider);
773
+ if (header) menu.appendChild(header);
774
+ if (search) {
775
+ // create a span instead of input as creating an input element is slower
776
+ var input = document.createElement('span');
777
+ search.className = 'bs-searchbox';
778
+ input.className = 'form-control';
779
+ search.appendChild(input);
780
+ menu.appendChild(search);
781
+ }
782
+ if (actions) menu.appendChild(actions);
783
+ menu.appendChild(menuInner);
784
+ if (doneButton) menu.appendChild(doneButton);
785
+ newElement.appendChild(menu);
786
+
787
+ document.body.appendChild(newElement);
788
+
789
+ var liHeight = a.offsetHeight,
790
+ headerHeight = header ? header.offsetHeight : 0,
791
+ searchHeight = search ? search.offsetHeight : 0,
792
+ actionsHeight = actions ? actions.offsetHeight : 0,
793
+ doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,
794
+ dividerHeight = $(divider).outerHeight(true),
795
+ // fall back to jQuery if getComputedStyle is not supported
796
+ menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,
797
+ $menu = menuStyle ? null : $(menu),
798
+ menuPadding = parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +
799
+ parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +
800
+ parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +
801
+ parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),
802
+ menuExtras = menuPadding +
803
+ parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +
804
+ parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2;
805
+
806
+ document.body.removeChild(newElement);
807
+
808
+ this.sizeInfo = {
809
+ liHeight: liHeight,
810
+ headerHeight: headerHeight,
811
+ searchHeight: searchHeight,
812
+ actionsHeight: actionsHeight,
813
+ doneButtonHeight: doneButtonHeight,
814
+ dividerHeight: dividerHeight,
815
+ menuPadding: menuPadding,
816
+ menuExtras: menuExtras
817
+ };
818
+ },
819
+
820
+ setSize: function () {
821
+ this.findLis();
822
+ this.liHeight();
823
+
824
+ if (this.options.header) this.$menu.css('padding-top', 0);
825
+ if (this.options.size === false) return;
826
+
827
+ var that = this,
828
+ $menu = this.$menu,
829
+ $menuInner = this.$menuInner,
830
+ $window = $(window),
831
+ selectHeight = this.$newElement[0].offsetHeight,
832
+ liHeight = this.sizeInfo['liHeight'],
833
+ headerHeight = this.sizeInfo['headerHeight'],
834
+ searchHeight = this.sizeInfo['searchHeight'],
835
+ actionsHeight = this.sizeInfo['actionsHeight'],
836
+ doneButtonHeight = this.sizeInfo['doneButtonHeight'],
837
+ divHeight = this.sizeInfo['dividerHeight'],
838
+ menuPadding = this.sizeInfo['menuPadding'],
839
+ menuExtras = this.sizeInfo['menuExtras'],
840
+ notDisabled = this.options.hideDisabled ? '.disabled' : '',
841
+ menuHeight,
842
+ getHeight,
843
+ selectOffsetTop,
844
+ selectOffsetBot,
845
+ posVert = function () {
846
+ selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();
847
+ selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;
848
+ };
849
+
850
+ posVert();
851
+
852
+ if (this.options.size === 'auto') {
853
+ var getSize = function () {
854
+ var minHeight,
855
+ hasClass = function (className, include) {
856
+ return function (element) {
857
+ if (include) {
858
+ return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));
859
+ } else {
860
+ return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));
861
+ }
862
+ };
863
+ },
864
+ lis = that.$menuInner[0].getElementsByTagName('li'),
865
+ lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),
866
+ optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');
867
+
868
+ posVert();
869
+ menuHeight = selectOffsetBot - menuExtras;
870
+
871
+ if (that.options.container) {
872
+ if (!$menu.data('height')) $menu.data('height', $menu.height());
873
+ getHeight = $menu.data('height');
874
+ } else {
875
+ getHeight = $menu.height();
876
+ }
877
+
878
+ if (that.options.dropupAuto) {
879
+ that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);
880
+ }
881
+ if (that.$newElement.hasClass('dropup')) {
882
+ menuHeight = selectOffsetTop - menuExtras;
883
+ }
884
+
885
+ if ((lisVisible.length + optGroup.length) > 3) {
886
+ minHeight = liHeight * 3 + menuExtras - 2;
887
+ } else {
888
+ minHeight = 0;
889
+ }
890
+
891
+ $menu.css({
892
+ 'max-height': menuHeight + 'px',
893
+ 'overflow': 'hidden',
894
+ 'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'
895
+ });
896
+ $menuInner.css({
897
+ 'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding + 'px',
898
+ 'overflow-y': 'auto',
899
+ 'min-height': Math.max(minHeight - menuPadding, 0) + 'px'
900
+ });
901
+ };
902
+ getSize();
903
+ this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);
904
+ $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);
905
+ } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {
906
+ var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),
907
+ divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;
908
+ menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;
909
+
910
+ if (that.options.container) {
911
+ if (!$menu.data('height')) $menu.data('height', $menu.height());
912
+ getHeight = $menu.data('height');
913
+ } else {
914
+ getHeight = $menu.height();
915
+ }
916
+
917
+ if (that.options.dropupAuto) {
918
+ //noinspection JSUnusedAssignment
919
+ this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);
920
+ }
921
+ $menu.css({
922
+ 'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',
923
+ 'overflow': 'hidden',
924
+ 'min-height': ''
925
+ });
926
+ $menuInner.css({
927
+ 'max-height': menuHeight - menuPadding + 'px',
928
+ 'overflow-y': 'auto',
929
+ 'min-height': ''
930
+ });
931
+ }
932
+ },
933
+
934
+ setWidth: function () {
935
+ if (this.options.width === 'auto') {
936
+ this.$menu.css('min-width', '0');
937
+
938
+ // Get correct width if element is hidden
939
+ var $selectClone = this.$menu.parent().clone().appendTo('body'),
940
+ $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,
941
+ ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),
942
+ btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();
943
+
944
+ $selectClone.remove();
945
+ $selectClone2.remove();
946
+
947
+ // Set width to whatever's larger, button title or longest option
948
+ this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');
949
+ } else if (this.options.width === 'fit') {
950
+ // Remove inline min-width so width can be changed from 'auto'
951
+ this.$menu.css('min-width', '');
952
+ this.$newElement.css('width', '').addClass('fit-width');
953
+ } else if (this.options.width) {
954
+ // Remove inline min-width so width can be changed from 'auto'
955
+ this.$menu.css('min-width', '');
956
+ this.$newElement.css('width', this.options.width);
957
+ } else {
958
+ // Remove inline min-width/width so width can be changed
959
+ this.$menu.css('min-width', '');
960
+ this.$newElement.css('width', '');
961
+ }
962
+ // Remove fit-width class if width is changed programmatically
963
+ if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {
964
+ this.$newElement.removeClass('fit-width');
965
+ }
966
+ },
967
+
968
+ selectPosition: function () {
969
+ this.$bsContainer = $('<div class="bs-container" />');
970
+
971
+ var that = this,
972
+ pos,
973
+ actualHeight,
974
+ getPlacement = function ($element) {
975
+ that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));
976
+ pos = $element.offset();
977
+ actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;
978
+ that.$bsContainer.css({
979
+ 'top': pos.top + actualHeight,
980
+ 'left': pos.left,
981
+ 'width': $element[0].offsetWidth
982
+ });
983
+ };
984
+
985
+ this.$button.on('click', function () {
986
+ var $this = $(this);
987
+
988
+ if (that.isDisabled()) {
989
+ return;
990
+ }
991
+
992
+ getPlacement(that.$newElement);
993
+
994
+ that.$bsContainer
995
+ .appendTo(that.options.container)
996
+ .toggleClass('open', !$this.hasClass('open'))
997
+ .append(that.$menu);
998
+ });
999
+
1000
+ $(window).on('resize scroll', function () {
1001
+ getPlacement(that.$newElement);
1002
+ });
1003
+
1004
+ this.$element.on('hide.bs.select', function () {
1005
+ that.$menu.data('height', that.$menu.height());
1006
+ that.$bsContainer.detach();
1007
+ });
1008
+ },
1009
+
1010
+ setSelected: function (index, selected, $lis) {
1011
+ if (!$lis) {
1012
+ $lis = this.findLis().eq(this.liObj[index]);
1013
+ }
1014
+
1015
+ $lis.toggleClass('selected', selected);
1016
+ },
1017
+
1018
+ setDisabled: function (index, disabled, $lis) {
1019
+ if (!$lis) {
1020
+ $lis = this.findLis().eq(this.liObj[index]);
1021
+ }
1022
+
1023
+ if (disabled) {
1024
+ $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1);
1025
+ } else {
1026
+ $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0);
1027
+ }
1028
+ },
1029
+
1030
+ isDisabled: function () {
1031
+ return this.$element[0].disabled;
1032
+ },
1033
+
1034
+ checkDisabled: function () {
1035
+ var that = this;
1036
+
1037
+ if (this.isDisabled()) {
1038
+ this.$newElement.addClass('disabled');
1039
+ this.$button.addClass('disabled').attr('tabindex', -1);
1040
+ } else {
1041
+ if (this.$button.hasClass('disabled')) {
1042
+ this.$newElement.removeClass('disabled');
1043
+ this.$button.removeClass('disabled');
1044
+ }
1045
+
1046
+ if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {
1047
+ this.$button.removeAttr('tabindex');
1048
+ }
1049
+ }
1050
+
1051
+ this.$button.click(function () {
1052
+ return !that.isDisabled();
1053
+ });
1054
+ },
1055
+
1056
+ tabIndex: function () {
1057
+ if (this.$element.data('tabindex') !== this.$element.attr('tabindex') &&
1058
+ (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {
1059
+ this.$element.data('tabindex', this.$element.attr('tabindex'));
1060
+ this.$button.attr('tabindex', this.$element.data('tabindex'));
1061
+ }
1062
+
1063
+ this.$element.attr('tabindex', -98);
1064
+ },
1065
+
1066
+ clickListener: function () {
1067
+ var that = this,
1068
+ $document = $(document);
1069
+
1070
+ this.$newElement.on('touchstart.dropdown', '.dropdown-menu', function (e) {
1071
+ e.stopPropagation();
1072
+ });
1073
+
1074
+ $document.data('spaceSelect', false);
1075
+
1076
+ this.$button.on('keyup', function (e) {
1077
+ if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {
1078
+ e.preventDefault();
1079
+ $document.data('spaceSelect', false);
1080
+ }
1081
+ });
1082
+
1083
+ this.$button.on('click', function () {
1084
+ that.setSize();
1085
+ that.$element.on('shown.bs.select', function () {
1086
+ if (!that.options.liveSearch && !that.multiple) {
1087
+ that.$menuInner.find('.selected a').focus();
1088
+ } else if (!that.multiple) {
1089
+ var selectedIndex = that.liObj[that.$element[0].selectedIndex];
1090
+
1091
+ if (typeof selectedIndex !== 'number' || that.options.size === false) return;
1092
+
1093
+ // scroll to selected option
1094
+ var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;
1095
+ offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;
1096
+ that.$menuInner[0].scrollTop = offset;
1097
+ }
1098
+ });
1099
+ });
1100
+
1101
+ this.$menuInner.on('click', 'li a', function (e) {
1102
+ var $this = $(this),
1103
+ clickedIndex = $this.parent().data('originalIndex'),
1104
+ prevValue = that.$element.val(),
1105
+ prevIndex = that.$element.prop('selectedIndex');
1106
+
1107
+ // Don't close on multi choice menu
1108
+ if (that.multiple) {
1109
+ e.stopPropagation();
1110
+ }
1111
+
1112
+ e.preventDefault();
1113
+
1114
+ //Don't run if we have been disabled
1115
+ if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {
1116
+ var $options = that.$element.find('option'),
1117
+ $option = $options.eq(clickedIndex),
1118
+ state = $option.prop('selected'),
1119
+ $optgroup = $option.parent('optgroup'),
1120
+ maxOptions = that.options.maxOptions,
1121
+ maxOptionsGrp = $optgroup.data('maxOptions') || false;
1122
+
1123
+ if (!that.multiple) { // Deselect all others if not multi select box
1124
+ $options.prop('selected', false);
1125
+ $option.prop('selected', true);
1126
+ that.$menuInner.find('.selected').removeClass('selected');
1127
+ that.setSelected(clickedIndex, true);
1128
+ } else { // Toggle the one we have chosen if we are multi select.
1129
+ $option.prop('selected', !state);
1130
+ that.setSelected(clickedIndex, !state);
1131
+ $this.blur();
1132
+
1133
+ if (maxOptions !== false || maxOptionsGrp !== false) {
1134
+ var maxReached = maxOptions < $options.filter(':selected').length,
1135
+ maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;
1136
+
1137
+ if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {
1138
+ if (maxOptions && maxOptions == 1) {
1139
+ $options.prop('selected', false);
1140
+ $option.prop('selected', true);
1141
+ that.$menuInner.find('.selected').removeClass('selected');
1142
+ that.setSelected(clickedIndex, true);
1143
+ } else if (maxOptionsGrp && maxOptionsGrp == 1) {
1144
+ $optgroup.find('option:selected').prop('selected', false);
1145
+ $option.prop('selected', true);
1146
+ var optgroupID = $this.parent().data('optgroup');
1147
+ that.$menuInner.find('[data-optgroup="' + optgroupID + '"]').removeClass('selected');
1148
+ that.setSelected(clickedIndex, true);
1149
+ } else {
1150
+ var maxOptionsArr = (typeof that.options.maxOptionsText === 'function') ?
1151
+ that.options.maxOptionsText(maxOptions, maxOptionsGrp) : that.options.maxOptionsText,
1152
+ maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),
1153
+ maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),
1154
+ $notify = $('<div class="notify"></div>');
1155
+ // If {var} is set in array, replace it
1156
+ /** @deprecated */
1157
+ if (maxOptionsArr[2]) {
1158
+ maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);
1159
+ maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);
1160
+ }
1161
+
1162
+ $option.prop('selected', false);
1163
+
1164
+ that.$menu.append($notify);
1165
+
1166
+ if (maxOptions && maxReached) {
1167
+ $notify.append($('<div>' + maxTxt + '</div>'));
1168
+ that.$element.trigger('maxReached.bs.select');
1169
+ }
1170
+
1171
+ if (maxOptionsGrp && maxReachedGrp) {
1172
+ $notify.append($('<div>' + maxTxtGrp + '</div>'));
1173
+ that.$element.trigger('maxReachedGrp.bs.select');
1174
+ }
1175
+
1176
+ setTimeout(function () {
1177
+ that.setSelected(clickedIndex, false);
1178
+ }, 10);
1179
+
1180
+ $notify.delay(750).fadeOut(300, function () {
1181
+ $(this).remove();
1182
+ });
1183
+ }
1184
+ }
1185
+ }
1186
+ }
1187
+
1188
+ if (!that.multiple) {
1189
+ that.$button.focus();
1190
+ } else if (that.options.liveSearch) {
1191
+ that.$searchbox.focus();
1192
+ }
1193
+
1194
+ // Trigger select 'change'
1195
+ if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {
1196
+ that.$element.triggerNative('change');
1197
+ // $option.prop('selected') is current option state (selected/unselected). state is previous option state.
1198
+ that.$element.trigger('changed.bs.select', [clickedIndex, $option.prop('selected'), state]);
1199
+ }
1200
+ }
1201
+ });
1202
+
1203
+ this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {
1204
+ if (e.currentTarget == this) {
1205
+ e.preventDefault();
1206
+ e.stopPropagation();
1207
+ if (that.options.liveSearch && !$(e.target).hasClass('close')) {
1208
+ that.$searchbox.focus();
1209
+ } else {
1210
+ that.$button.focus();
1211
+ }
1212
+ }
1213
+ });
1214
+
1215
+ this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {
1216
+ e.preventDefault();
1217
+ e.stopPropagation();
1218
+ if (that.options.liveSearch) {
1219
+ that.$searchbox.focus();
1220
+ } else {
1221
+ that.$button.focus();
1222
+ }
1223
+ });
1224
+
1225
+ this.$menu.on('click', '.popover-title .close', function () {
1226
+ that.$button.click();
1227
+ });
1228
+
1229
+ this.$searchbox.on('click', function (e) {
1230
+ e.stopPropagation();
1231
+ });
1232
+
1233
+ this.$menu.on('click', '.actions-btn', function (e) {
1234
+ if (that.options.liveSearch) {
1235
+ that.$searchbox.focus();
1236
+ } else {
1237
+ that.$button.focus();
1238
+ }
1239
+
1240
+ e.preventDefault();
1241
+ e.stopPropagation();
1242
+
1243
+ if ($(this).hasClass('bs-select-all')) {
1244
+ that.selectAll();
1245
+ } else {
1246
+ that.deselectAll();
1247
+ }
1248
+ that.$element.triggerNative('change');
1249
+ });
1250
+
1251
+ this.$element.change(function () {
1252
+ that.render(false);
1253
+ });
1254
+ },
1255
+
1256
+ liveSearchListener: function () {
1257
+ var that = this,
1258
+ $no_results = $('<li class="no-results"></li>');
1259
+
1260
+ this.$button.on('click.dropdown.data-api touchstart.dropdown.data-api', function () {
1261
+ that.$menuInner.find('.active').removeClass('active');
1262
+ if (!!that.$searchbox.val()) {
1263
+ that.$searchbox.val('');
1264
+ that.$lis.not('.is-hidden').removeClass('hidden');
1265
+ if (!!$no_results.parent().length) $no_results.remove();
1266
+ }
1267
+ if (!that.multiple) that.$menuInner.find('.selected').addClass('active');
1268
+ setTimeout(function () {
1269
+ that.$searchbox.focus();
1270
+ }, 10);
1271
+ });
1272
+
1273
+ this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {
1274
+ e.stopPropagation();
1275
+ });
1276
+
1277
+ this.$searchbox.on('input propertychange', function () {
1278
+ if (that.$searchbox.val()) {
1279
+ var $searchBase = that.$lis.not('.is-hidden').removeClass('hidden').children('a');
1280
+ if (that.options.liveSearchNormalize) {
1281
+ $searchBase = $searchBase.not(':a' + that._searchStyle() + '("' + normalizeToBase(that.$searchbox.val()) + '")');
1282
+ } else {
1283
+ $searchBase = $searchBase.not(':' + that._searchStyle() + '("' + that.$searchbox.val() + '")');
1284
+ }
1285
+ $searchBase.parent().addClass('hidden');
1286
+
1287
+ that.$lis.filter('.dropdown-header').each(function () {
1288
+ var $this = $(this),
1289
+ optgroup = $this.data('optgroup');
1290
+
1291
+ if (that.$lis.filter('[data-optgroup=' + optgroup + ']').not($this).not('.hidden').length === 0) {
1292
+ $this.addClass('hidden');
1293
+ that.$lis.filter('[data-optgroup=' + optgroup + 'div]').addClass('hidden');
1294
+ }
1295
+ });
1296
+
1297
+ var $lisVisible = that.$lis.not('.hidden');
1298
+
1299
+ // hide divider if first or last visible, or if followed by another divider
1300
+ $lisVisible.each(function (index) {
1301
+ var $this = $(this);
1302
+
1303
+ if ($this.hasClass('divider') && (
1304
+ $this.index() === $lisVisible.first().index() ||
1305
+ $this.index() === $lisVisible.last().index() ||
1306
+ $lisVisible.eq(index + 1).hasClass('divider'))) {
1307
+ $this.addClass('hidden');
1308
+ }
1309
+ });
1310
+
1311
+ if (!that.$lis.not('.hidden, .no-results').length) {
1312
+ if (!!$no_results.parent().length) {
1313
+ $no_results.remove();
1314
+ }
1315
+ $no_results.html(that.options.noneResultsText.replace('{0}', '"' + htmlEscape(that.$searchbox.val()) + '"')).show();
1316
+ that.$menuInner.append($no_results);
1317
+ } else if (!!$no_results.parent().length) {
1318
+ $no_results.remove();
1319
+ }
1320
+ } else {
1321
+ that.$lis.not('.is-hidden').removeClass('hidden');
1322
+ if (!!$no_results.parent().length) {
1323
+ $no_results.remove();
1324
+ }
1325
+ }
1326
+
1327
+ that.$lis.filter('.active').removeClass('active');
1328
+ if (that.$searchbox.val()) that.$lis.not('.hidden, .divider, .dropdown-header').eq(0).addClass('active').children('a').focus();
1329
+ $(this).focus();
1330
+ });
1331
+ },
1332
+
1333
+ _searchStyle: function () {
1334
+ var styles = {
1335
+ begins: 'ibegins',
1336
+ startsWith: 'ibegins'
1337
+ };
1338
+
1339
+ return styles[this.options.liveSearchStyle] || 'icontains';
1340
+ },
1341
+
1342
+ val: function (value) {
1343
+ if (typeof value !== 'undefined') {
1344
+ this.$element.val(value);
1345
+ this.render();
1346
+
1347
+ return this.$element;
1348
+ } else {
1349
+ return this.$element.val();
1350
+ }
1351
+ },
1352
+
1353
+ changeAll: function (status) {
1354
+ if (typeof status === 'undefined') status = true;
1355
+
1356
+ this.findLis();
1357
+
1358
+ var $options = this.$element.find('option'),
1359
+ $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden').toggleClass('selected', status),
1360
+ lisVisLen = $lisVisible.length,
1361
+ selectedOptions = [];
1362
+
1363
+ for (var i = 0; i < lisVisLen; i++) {
1364
+ var origIndex = $lisVisible[i].getAttribute('data-original-index');
1365
+ selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];
1366
+ }
1367
+
1368
+ $(selectedOptions).prop('selected', status);
1369
+
1370
+ this.render(false);
1371
+ },
1372
+
1373
+ selectAll: function () {
1374
+ return this.changeAll(true);
1375
+ },
1376
+
1377
+ deselectAll: function () {
1378
+ return this.changeAll(false);
1379
+ },
1380
+
1381
+ keydown: function (e) {
1382
+ var $this = $(this),
1383
+ $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),
1384
+ $items,
1385
+ that = $parent.data('this'),
1386
+ index,
1387
+ next,
1388
+ first,
1389
+ last,
1390
+ prev,
1391
+ nextPrev,
1392
+ prevIndex,
1393
+ isActive,
1394
+ selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',
1395
+ keyCodeMap = {
1396
+ 32: ' ',
1397
+ 48: '0',
1398
+ 49: '1',
1399
+ 50: '2',
1400
+ 51: '3',
1401
+ 52: '4',
1402
+ 53: '5',
1403
+ 54: '6',
1404
+ 55: '7',
1405
+ 56: '8',
1406
+ 57: '9',
1407
+ 59: ';',
1408
+ 65: 'a',
1409
+ 66: 'b',
1410
+ 67: 'c',
1411
+ 68: 'd',
1412
+ 69: 'e',
1413
+ 70: 'f',
1414
+ 71: 'g',
1415
+ 72: 'h',
1416
+ 73: 'i',
1417
+ 74: 'j',
1418
+ 75: 'k',
1419
+ 76: 'l',
1420
+ 77: 'm',
1421
+ 78: 'n',
1422
+ 79: 'o',
1423
+ 80: 'p',
1424
+ 81: 'q',
1425
+ 82: 'r',
1426
+ 83: 's',
1427
+ 84: 't',
1428
+ 85: 'u',
1429
+ 86: 'v',
1430
+ 87: 'w',
1431
+ 88: 'x',
1432
+ 89: 'y',
1433
+ 90: 'z',
1434
+ 96: '0',
1435
+ 97: '1',
1436
+ 98: '2',
1437
+ 99: '3',
1438
+ 100: '4',
1439
+ 101: '5',
1440
+ 102: '6',
1441
+ 103: '7',
1442
+ 104: '8',
1443
+ 105: '9'
1444
+ };
1445
+
1446
+ if (that.options.liveSearch) $parent = $this.parent().parent();
1447
+
1448
+ if (that.options.container) $parent = that.$menu;
1449
+
1450
+ $items = $('[role=menu] li', $parent);
1451
+
1452
+ isActive = that.$newElement.hasClass('open');
1453
+
1454
+ if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {
1455
+ if (!that.options.container) {
1456
+ that.setSize();
1457
+ that.$menu.parent().addClass('open');
1458
+ isActive = true;
1459
+ } else {
1460
+ that.$button.trigger('click');
1461
+ }
1462
+ that.$searchbox.focus();
1463
+ }
1464
+
1465
+ if (that.options.liveSearch) {
1466
+ if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && that.$menu.find('.active').length === 0) {
1467
+ e.preventDefault();
1468
+ that.$menu.parent().removeClass('open');
1469
+ if (that.options.container) that.$newElement.removeClass('open');
1470
+ that.$button.focus();
1471
+ }
1472
+ // $items contains li elements when liveSearch is enabled
1473
+ $items = $('[role=menu] li' + selector, $parent);
1474
+ if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {
1475
+ if ($items.filter('.active').length === 0) {
1476
+ $items = that.$menuInner.find('li');
1477
+ if (that.options.liveSearchNormalize) {
1478
+ $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');
1479
+ } else {
1480
+ $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');
1481
+ }
1482
+ }
1483
+ }
1484
+ }
1485
+
1486
+ if (!$items.length) return;
1487
+
1488
+ if (/(38|40)/.test(e.keyCode.toString(10))) {
1489
+ index = $items.index($items.find('a').filter(':focus').parent());
1490
+ first = $items.filter(selector).first().index();
1491
+ last = $items.filter(selector).last().index();
1492
+ next = $items.eq(index).nextAll(selector).eq(0).index();
1493
+ prev = $items.eq(index).prevAll(selector).eq(0).index();
1494
+ nextPrev = $items.eq(next).prevAll(selector).eq(0).index();
1495
+
1496
+ if (that.options.liveSearch) {
1497
+ $items.each(function (i) {
1498
+ if (!$(this).hasClass('disabled')) {
1499
+ $(this).data('index', i);
1500
+ }
1501
+ });
1502
+ index = $items.index($items.filter('.active'));
1503
+ first = $items.first().data('index');
1504
+ last = $items.last().data('index');
1505
+ next = $items.eq(index).nextAll().eq(0).data('index');
1506
+ prev = $items.eq(index).prevAll().eq(0).data('index');
1507
+ nextPrev = $items.eq(next).prevAll().eq(0).data('index');
1508
+ }
1509
+
1510
+ prevIndex = $this.data('prevIndex');
1511
+
1512
+ if (e.keyCode == 38) {
1513
+ if (that.options.liveSearch) index--;
1514
+ if (index != nextPrev && index > prev) index = prev;
1515
+ if (index < first) index = first;
1516
+ if (index == prevIndex) index = last;
1517
+ } else if (e.keyCode == 40) {
1518
+ if (that.options.liveSearch) index++;
1519
+ if (index == -1) index = 0;
1520
+ if (index != nextPrev && index < next) index = next;
1521
+ if (index > last) index = last;
1522
+ if (index == prevIndex) index = first;
1523
+ }
1524
+
1525
+ $this.data('prevIndex', index);
1526
+
1527
+ if (!that.options.liveSearch) {
1528
+ $items.eq(index).children('a').focus();
1529
+ } else {
1530
+ e.preventDefault();
1531
+ if (!$this.hasClass('dropdown-toggle')) {
1532
+ $items.removeClass('active').eq(index).addClass('active').children('a').focus();
1533
+ $this.focus();
1534
+ }
1535
+ }
1536
+
1537
+ } else if (!$this.is('input')) {
1538
+ var keyIndex = [],
1539
+ count,
1540
+ prevKey;
1541
+
1542
+ $items.each(function () {
1543
+ if (!$(this).hasClass('disabled')) {
1544
+ if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {
1545
+ keyIndex.push($(this).index());
1546
+ }
1547
+ }
1548
+ });
1549
+
1550
+ count = $(document).data('keycount');
1551
+ count++;
1552
+ $(document).data('keycount', count);
1553
+
1554
+ prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);
1555
+
1556
+ if (prevKey != keyCodeMap[e.keyCode]) {
1557
+ count = 1;
1558
+ $(document).data('keycount', count);
1559
+ } else if (count >= keyIndex.length) {
1560
+ $(document).data('keycount', 0);
1561
+ if (count > keyIndex.length) count = 1;
1562
+ }
1563
+
1564
+ $items.eq(keyIndex[count - 1]).children('a').focus();
1565
+ }
1566
+
1567
+ // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu.
1568
+ if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {
1569
+ if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();
1570
+ if (!that.options.liveSearch) {
1571
+ var elem = $(':focus');
1572
+ elem.click();
1573
+ // Bring back focus for multiselects
1574
+ elem.focus();
1575
+ // Prevent screen from scrolling if the user hit the spacebar
1576
+ e.preventDefault();
1577
+ // Fixes spacebar selection of dropdown items in FF & IE
1578
+ $(document).data('spaceSelect', true);
1579
+ } else if (!/(32)/.test(e.keyCode.toString(10))) {
1580
+ that.$menuInner.find('.active a').click();
1581
+ $this.focus();
1582
+ }
1583
+ $(document).data('keycount', 0);
1584
+ }
1585
+
1586
+ if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {
1587
+ that.$menu.parent().removeClass('open');
1588
+ if (that.options.container) that.$newElement.removeClass('open');
1589
+ that.$button.focus();
1590
+ }
1591
+ },
1592
+
1593
+ mobile: function () {
1594
+ this.$element.addClass('mobile-device');
1595
+ },
1596
+
1597
+ refresh: function () {
1598
+ this.$lis = null;
1599
+ this.liObj = {};
1600
+ this.reloadLi();
1601
+ this.render();
1602
+ this.checkDisabled();
1603
+ this.liHeight(true);
1604
+ this.setStyle();
1605
+ this.setWidth();
1606
+ if (this.$lis) this.$searchbox.trigger('propertychange');
1607
+
1608
+ this.$element.trigger('refreshed.bs.select');
1609
+ },
1610
+
1611
+ hide: function () {
1612
+ this.$newElement.hide();
1613
+ },
1614
+
1615
+ show: function () {
1616
+ this.$newElement.show();
1617
+ },
1618
+
1619
+ remove: function () {
1620
+ this.$newElement.remove();
1621
+ this.$element.remove();
1622
+ },
1623
+
1624
+ destroy: function () {
1625
+ this.$newElement.before(this.$element).remove();
1626
+
1627
+ if (this.$bsContainer) {
1628
+ this.$bsContainer.remove();
1629
+ } else {
1630
+ this.$menu.remove();
1631
+ }
1632
+
1633
+ this.$element
1634
+ .off('.bs.select')
1635
+ .removeData('selectpicker')
1636
+ .removeClass('bs-select-hidden selectpicker');
1637
+ }
1638
+ };
1639
+
1640
+ // SELECTPICKER PLUGIN DEFINITION
1641
+ // ==============================
1642
+ function Plugin(option, event) {
1643
+ // get the args of the outer function..
1644
+ var args = arguments;
1645
+ // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
1646
+ // to get lost/corrupted in android 2.3 and IE9 #715 #775
1647
+ var _option = option,
1648
+ _event = event;
1649
+ [].shift.apply(args);
1650
+
1651
+ var value;
1652
+ var chain = this.each(function () {
1653
+ var $this = $(this);
1654
+ if ($this.is('select')) {
1655
+ var data = $this.data('selectpicker'),
1656
+ options = typeof _option == 'object' && _option;
1657
+
1658
+ if (!data) {
1659
+ var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);
1660
+ config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);
1661
+ $this.data('selectpicker', (data = new Selectpicker(this, config, _event)));
1662
+ } else if (options) {
1663
+ for (var i in options) {
1664
+ if (options.hasOwnProperty(i)) {
1665
+ data.options[i] = options[i];
1666
+ }
1667
+ }
1668
+ }
1669
+
1670
+ if (typeof _option == 'string') {
1671
+ if (data[_option] instanceof Function) {
1672
+ value = data[_option].apply(data, args);
1673
+ } else {
1674
+ value = data.options[_option];
1675
+ }
1676
+ }
1677
+ }
1678
+ });
1679
+
1680
+ if (typeof value !== 'undefined') {
1681
+ //noinspection JSUnusedAssignment
1682
+ return value;
1683
+ } else {
1684
+ return chain;
1685
+ }
1686
+ }
1687
+
1688
+ var old = $.fn.selectpicker;
1689
+ $.fn.selectpicker = Plugin;
1690
+ $.fn.selectpicker.Constructor = Selectpicker;
1691
+
1692
+ // SELECTPICKER NO CONFLICT
1693
+ // ========================
1694
+ $.fn.selectpicker.noConflict = function () {
1695
+ $.fn.selectpicker = old;
1696
+ return this;
1697
+ };
1698
+
1699
+ $(document)
1700
+ .data('keycount', 0)
1701
+ .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="menu"], .bs-searchbox input', Selectpicker.prototype.keydown)
1702
+ .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="menu"], .bs-searchbox input', function (e) {
1703
+ e.stopPropagation();
1704
+ });
1705
+
1706
+ // SELECTPICKER DATA-API
1707
+ // =====================
1708
+ $(window).on('load.bs.select.data-api', function () {
1709
+ $('.selectpicker').each(function () {
1710
+ var $selectpicker = $(this);
1711
+ Plugin.call($selectpicker, $selectpicker.data());
1712
+ })
1713
+ });
1714
+ })(jQuery);
1715
+
1716
+
1717
+ }));