selectize-rails 0.7.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -0
- data/lib/selectize-rails/version.rb +1 -1
- data/vendor/assets/javascripts/selectize.js +435 -183
- data/vendor/assets/stylesheets/selectize.bootstrap2.css +24 -6
- data/vendor/assets/stylesheets/selectize.bootstrap3.css +21 -4
- data/vendor/assets/stylesheets/selectize.css +21 -4
- data/vendor/assets/stylesheets/selectize.default.css +30 -5
- data/vendor/assets/stylesheets/selectize.legacy.css +21 -4
- metadata +2 -2
data/README.md
CHANGED
@@ -41,6 +41,7 @@ See the [demo page of Brian Reavis](http://brianreavis.github.io/selectize.js/)
|
|
41
41
|
|
42
42
|
| Version | Notes |
|
43
43
|
| -------:| ----------------------------------------------------------- |
|
44
|
+
| 0.8.0 | Update to v0.8.0 of selectize.js |
|
44
45
|
| 0.7.7 | Update to v0.7.7 of selectize.js |
|
45
46
|
| 0.7.6 | Update to v0.7.6 of selectize.js |
|
46
47
|
| 0.7.5 | Update to v0.7.5 of selectize.js |
|
@@ -176,12 +176,120 @@
|
|
176
176
|
return scoreObject(tokens[0], data);
|
177
177
|
};
|
178
178
|
}
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
179
|
+
|
180
|
+
if (search.options.conjunction === 'and') {
|
181
|
+
return function(data) {
|
182
|
+
var score;
|
183
|
+
for (var i = 0, sum = 0; i < token_count; i++) {
|
184
|
+
score = scoreObject(tokens[i], data);
|
185
|
+
if (score <= 0) return 0;
|
186
|
+
sum += score;
|
187
|
+
}
|
188
|
+
return sum / token_count;
|
189
|
+
};
|
190
|
+
} else {
|
191
|
+
return function(data) {
|
192
|
+
for (var i = 0, sum = 0; i < token_count; i++) {
|
193
|
+
sum += scoreObject(tokens[i], data);
|
194
|
+
}
|
195
|
+
return sum / token_count;
|
196
|
+
};
|
197
|
+
}
|
198
|
+
};
|
199
|
+
|
200
|
+
/**
|
201
|
+
* Returns a function that can be used to compare two
|
202
|
+
* results, for sorting purposes. If no sorting should
|
203
|
+
* be performed, `null` will be returned.
|
204
|
+
*
|
205
|
+
* @param {string|object} search
|
206
|
+
* @param {object} options
|
207
|
+
* @return function(a,b)
|
208
|
+
*/
|
209
|
+
Sifter.prototype.getSortFunction = function(search, options) {
|
210
|
+
var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort;
|
211
|
+
|
212
|
+
self = this;
|
213
|
+
search = self.prepareSearch(search, options);
|
214
|
+
sort = (!search.query && options.sort_empty) || options.sort;
|
215
|
+
|
216
|
+
/**
|
217
|
+
* Fetches the specified sort field value
|
218
|
+
* from a search result item.
|
219
|
+
*
|
220
|
+
* @param {string} name
|
221
|
+
* @param {object} result
|
222
|
+
* @return {mixed}
|
223
|
+
*/
|
224
|
+
get_field = function(name, result) {
|
225
|
+
if (name === '$score') return result.score;
|
226
|
+
return self.items[result.id][name];
|
184
227
|
};
|
228
|
+
|
229
|
+
// parse options
|
230
|
+
fields = [];
|
231
|
+
if (sort) {
|
232
|
+
for (i = 0, n = sort.length; i < n; i++) {
|
233
|
+
if (search.query || sort[i].field !== '$score') {
|
234
|
+
fields.push(sort[i]);
|
235
|
+
}
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
// the "$score" field is implied to be the primary
|
240
|
+
// sort field, unless it's manually specified
|
241
|
+
if (search.query) {
|
242
|
+
implicit_score = true;
|
243
|
+
for (i = 0, n = fields.length; i < n; i++) {
|
244
|
+
if (fields[i].field === '$score') {
|
245
|
+
implicit_score = false;
|
246
|
+
break;
|
247
|
+
}
|
248
|
+
}
|
249
|
+
if (implicit_score) {
|
250
|
+
fields.unshift({field: '$score', direction: 'desc'});
|
251
|
+
}
|
252
|
+
} else {
|
253
|
+
for (i = 0, n = fields.length; i < n; i++) {
|
254
|
+
if (fields[i].field === '$score') {
|
255
|
+
fields.splice(i, 1);
|
256
|
+
break;
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
multipliers = [];
|
262
|
+
for (i = 0, n = fields.length; i < n; i++) {
|
263
|
+
multipliers.push(fields[i].direction === 'desc' ? -1 : 1);
|
264
|
+
}
|
265
|
+
|
266
|
+
// build function
|
267
|
+
fields_count = fields.length;
|
268
|
+
if (!fields_count) {
|
269
|
+
return null;
|
270
|
+
} else if (fields_count === 1) {
|
271
|
+
field = fields[0].field;
|
272
|
+
multiplier = multipliers[0];
|
273
|
+
return function(a, b) {
|
274
|
+
return multiplier * cmp(
|
275
|
+
get_field(field, a),
|
276
|
+
get_field(field, b)
|
277
|
+
);
|
278
|
+
};
|
279
|
+
} else {
|
280
|
+
return function(a, b) {
|
281
|
+
var i, result, a_value, b_value, field;
|
282
|
+
for (i = 0; i < fields_count; i++) {
|
283
|
+
field = fields[i].field;
|
284
|
+
result = multipliers[i] * cmp(
|
285
|
+
get_field(field, a),
|
286
|
+
get_field(field, b)
|
287
|
+
);
|
288
|
+
if (result) return result;
|
289
|
+
}
|
290
|
+
return 0;
|
291
|
+
};
|
292
|
+
}
|
185
293
|
};
|
186
294
|
|
187
295
|
/**
|
@@ -195,8 +303,19 @@
|
|
195
303
|
*/
|
196
304
|
Sifter.prototype.prepareSearch = function(query, options) {
|
197
305
|
if (typeof query === 'object') return query;
|
306
|
+
|
307
|
+
options = extend({}, options);
|
308
|
+
|
309
|
+
var option_fields = options.fields;
|
310
|
+
var option_sort = options.sort;
|
311
|
+
var option_sort_empty = options.sort_empty;
|
312
|
+
|
313
|
+
if (option_fields && !is_array(option_fields)) options.fields = [option_fields];
|
314
|
+
if (option_sort && !is_array(option_sort)) options.sort = [option_sort];
|
315
|
+
if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty];
|
316
|
+
|
198
317
|
return {
|
199
|
-
options :
|
318
|
+
options : options,
|
200
319
|
query : String(query || '').toLowerCase(),
|
201
320
|
tokens : this.tokenize(query),
|
202
321
|
total : 0,
|
@@ -210,9 +329,9 @@
|
|
210
329
|
* The `options` parameter can contain:
|
211
330
|
*
|
212
331
|
* - fields {string|array}
|
213
|
-
* - sort {
|
214
|
-
* - direction {string}
|
332
|
+
* - sort {array}
|
215
333
|
* - score {function}
|
334
|
+
* - filter {bool}
|
216
335
|
* - limit {integer}
|
217
336
|
*
|
218
337
|
* Returns an object containing:
|
@@ -229,41 +348,33 @@
|
|
229
348
|
*/
|
230
349
|
Sifter.prototype.search = function(query, options) {
|
231
350
|
var self = this, value, score, search, calculateScore;
|
351
|
+
var fn_sort;
|
352
|
+
var fn_score;
|
232
353
|
|
233
354
|
search = this.prepareSearch(query, options);
|
234
355
|
options = search.options;
|
235
356
|
query = search.query;
|
236
357
|
|
237
358
|
// generate result scoring function
|
238
|
-
|
239
|
-
calculateScore = options.score || self.getScoreFunction(search);
|
359
|
+
fn_score = options.score || self.getScoreFunction(search);
|
240
360
|
|
241
361
|
// perform search and sort
|
242
362
|
if (query.length) {
|
243
363
|
self.iterator(self.items, function(item, id) {
|
244
|
-
score =
|
245
|
-
if (score > 0) {
|
364
|
+
score = fn_score(item);
|
365
|
+
if (options.filter === false || score > 0) {
|
246
366
|
search.items.push({'score': score, 'id': id});
|
247
367
|
}
|
248
368
|
});
|
249
|
-
search.items.sort(function(a, b) {
|
250
|
-
return b.score - a.score;
|
251
|
-
});
|
252
369
|
} else {
|
253
370
|
self.iterator(self.items, function(item, id) {
|
254
371
|
search.items.push({'score': 1, 'id': id});
|
255
372
|
});
|
256
|
-
if (options.sort) {
|
257
|
-
search.items.sort((function() {
|
258
|
-
var field = options.sort;
|
259
|
-
var multiplier = options.direction === 'desc' ? -1 : 1;
|
260
|
-
return function(a, b) {
|
261
|
-
return cmp(self.items[a.id][field], self.items[b.id][field]) * multiplier;
|
262
|
-
};
|
263
|
-
})());
|
264
|
-
}
|
265
373
|
}
|
266
374
|
|
375
|
+
fn_sort = self.getSortFunction(search, options);
|
376
|
+
if (fn_sort) search.items.sort(fn_sort);
|
377
|
+
|
267
378
|
// apply limits
|
268
379
|
search.total = search.items.length;
|
269
380
|
if (typeof options.limit === 'number') {
|
@@ -315,7 +426,8 @@
|
|
315
426
|
|
316
427
|
var DIACRITICS = {
|
317
428
|
'a': '[aÀÁÂÃÄÅàáâãäå]',
|
318
|
-
'c': '[
|
429
|
+
'c': '[cÇçćĆčČ]',
|
430
|
+
'd': '[dđĐ]',
|
319
431
|
'e': '[eÈÉÊËèéêë]',
|
320
432
|
'i': '[iÌÍÎÏìíîï]',
|
321
433
|
'n': '[nÑñ]',
|
@@ -330,9 +442,10 @@
|
|
330
442
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
331
443
|
|
332
444
|
return Sifter;
|
333
|
-
|
334
445
|
}));
|
335
446
|
|
447
|
+
|
448
|
+
|
336
449
|
/**
|
337
450
|
* microplugin.js
|
338
451
|
* Copyright (c) 2013 Brian Reavis & contributors
|
@@ -470,7 +583,7 @@
|
|
470
583
|
}));
|
471
584
|
|
472
585
|
/**
|
473
|
-
* selectize.js (v0.
|
586
|
+
* selectize.js (v0.8.0)
|
474
587
|
* Copyright (c) 2013 Brian Reavis & contributors
|
475
588
|
*
|
476
589
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
@@ -830,7 +943,7 @@
|
|
830
943
|
left: -99999,
|
831
944
|
width: 'auto',
|
832
945
|
padding: 0,
|
833
|
-
whiteSpace: '
|
946
|
+
whiteSpace: 'pre'
|
834
947
|
}).text(str).appendTo('body');
|
835
948
|
|
836
949
|
transferStyles($parent, $test, [
|
@@ -910,22 +1023,29 @@
|
|
910
1023
|
};
|
911
1024
|
|
912
1025
|
var Selectize = function($input, settings) {
|
913
|
-
var key, i, n, self = this;
|
914
|
-
$input[0]
|
1026
|
+
var key, i, n, dir, input, self = this;
|
1027
|
+
input = $input[0];
|
1028
|
+
input.selectize = self;
|
1029
|
+
|
1030
|
+
// detect rtl environment
|
1031
|
+
dir = window.getComputedStyle ? window.getComputedStyle(input, null).getPropertyValue('direction') : input.currentStyle && input.currentStyle.direction;
|
1032
|
+
dir = dir || $input.parents('[dir]:first').attr('dir') || '';
|
915
1033
|
|
916
1034
|
// setup default state
|
917
1035
|
$.extend(self, {
|
918
1036
|
settings : settings,
|
919
1037
|
$input : $input,
|
920
|
-
tagType :
|
1038
|
+
tagType : input.tagName.toLowerCase() === 'select' ? TAG_SELECT : TAG_INPUT,
|
1039
|
+
rtl : /rtl/i.test(dir),
|
921
1040
|
|
922
1041
|
eventNS : '.selectize' + (++Selectize.count),
|
923
1042
|
highlightedValue : null,
|
924
1043
|
isOpen : false,
|
925
1044
|
isDisabled : false,
|
1045
|
+
isRequired : $input.is(':required'),
|
1046
|
+
isInvalid : false,
|
926
1047
|
isLocked : false,
|
927
1048
|
isFocused : false,
|
928
|
-
isInputFocused : false,
|
929
1049
|
isInputHidden : false,
|
930
1050
|
isSetup : false,
|
931
1051
|
isShiftDown : false,
|
@@ -1014,7 +1134,7 @@
|
|
1014
1134
|
|
1015
1135
|
$wrapper = $('<div>').addClass(settings.wrapperClass).addClass(classes).addClass(inputMode);
|
1016
1136
|
$control = $('<div>').addClass(settings.inputClass).addClass('items').appendTo($wrapper);
|
1017
|
-
$control_input = $('<input type="text">').appendTo($control).attr('tabindex', tab_index);
|
1137
|
+
$control_input = $('<input type="text" autocomplete="off">').appendTo($control).attr('tabindex', tab_index);
|
1018
1138
|
$dropdown_parent = $(settings.dropdownParent || $wrapper);
|
1019
1139
|
$dropdown = $('<div>').addClass(settings.dropdownClass).addClass(classes).addClass(inputMode).hide().appendTo($dropdown_parent);
|
1020
1140
|
$dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);
|
@@ -1043,27 +1163,16 @@
|
|
1043
1163
|
self.$dropdown = $dropdown;
|
1044
1164
|
self.$dropdown_content = $dropdown_content;
|
1045
1165
|
|
1046
|
-
$control.on('mousedown', function(e) {
|
1047
|
-
if (!e.isDefaultPrevented()) {
|
1048
|
-
window.setTimeout(function() {
|
1049
|
-
self.focus(true);
|
1050
|
-
}, 0);
|
1051
|
-
}
|
1052
|
-
});
|
1053
|
-
|
1054
|
-
// necessary for mobile webkit devices (manual focus triggering
|
1055
|
-
// is ignored unless invoked within a click event)
|
1056
|
-
$control.on('click', function(e) {
|
1057
|
-
if (!self.isInputFocused) {
|
1058
|
-
self.focus(true);
|
1059
|
-
}
|
1060
|
-
});
|
1061
|
-
|
1062
1166
|
$dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); });
|
1063
1167
|
$dropdown.on('mousedown', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); });
|
1064
1168
|
watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); });
|
1065
1169
|
autoGrow($control_input);
|
1066
1170
|
|
1171
|
+
$control.on({
|
1172
|
+
mousedown : function() { return self.onMouseDown.apply(self, arguments); },
|
1173
|
+
click : function() { return self.onClick.apply(self, arguments); }
|
1174
|
+
});
|
1175
|
+
|
1067
1176
|
$control_input.on({
|
1068
1177
|
mousedown : function(e) { e.stopPropagation(); },
|
1069
1178
|
keydown : function() { return self.onKeyDown.apply(self, arguments); },
|
@@ -1090,13 +1199,7 @@
|
|
1090
1199
|
if (self.isFocused) {
|
1091
1200
|
// prevent events on the dropdown scrollbar from causing the control to blur
|
1092
1201
|
if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) {
|
1093
|
-
|
1094
|
-
self.ignoreFocus = true;
|
1095
|
-
window.setTimeout(function() {
|
1096
|
-
self.ignoreFocus = ignoreFocus;
|
1097
|
-
self.focus(false);
|
1098
|
-
}, 0);
|
1099
|
-
return;
|
1202
|
+
return false;
|
1100
1203
|
}
|
1101
1204
|
// blur on click outside
|
1102
1205
|
if (!self.$control.has(e.target).length && e.target !== self.$control[0]) {
|
@@ -1114,16 +1217,25 @@
|
|
1114
1217
|
self.ignoreHover = false;
|
1115
1218
|
});
|
1116
1219
|
|
1117
|
-
self.$input.attr('tabindex'
|
1220
|
+
self.$input.attr('tabindex', -1).hide().after(self.$wrapper);
|
1118
1221
|
|
1119
1222
|
if ($.isArray(settings.items)) {
|
1120
1223
|
self.setValue(settings.items);
|
1121
1224
|
delete settings.items;
|
1122
1225
|
}
|
1123
1226
|
|
1227
|
+
// feature detect for the validation API
|
1228
|
+
if (self.$input[0].validity) {
|
1229
|
+
self.$input.on('invalid' + eventNS, function(e) {
|
1230
|
+
e.preventDefault();
|
1231
|
+
self.isInvalid = true;
|
1232
|
+
self.refreshState();
|
1233
|
+
});
|
1234
|
+
}
|
1235
|
+
|
1124
1236
|
self.updateOriginalInput();
|
1125
1237
|
self.refreshItems();
|
1126
|
-
self.
|
1238
|
+
self.refreshState();
|
1127
1239
|
self.updatePlaceholder();
|
1128
1240
|
self.isSetup = true;
|
1129
1241
|
|
@@ -1163,7 +1275,7 @@
|
|
1163
1275
|
},
|
1164
1276
|
'option_create': function(data, escape) {
|
1165
1277
|
return '<div class="create">Add <strong>' + escape(data.input) + '</strong>…</div>';
|
1166
|
-
}
|
1278
|
+
}
|
1167
1279
|
};
|
1168
1280
|
|
1169
1281
|
self.settings.render = $.extend({}, templates, self.settings.render);
|
@@ -1196,6 +1308,59 @@
|
|
1196
1308
|
}
|
1197
1309
|
},
|
1198
1310
|
|
1311
|
+
/**
|
1312
|
+
* Triggered when the main control element
|
1313
|
+
* has a click event.
|
1314
|
+
*
|
1315
|
+
* @param {object} e
|
1316
|
+
* @return {boolean}
|
1317
|
+
*/
|
1318
|
+
onClick: function(e) {
|
1319
|
+
var self = this;
|
1320
|
+
|
1321
|
+
// necessary for mobile webkit devices (manual focus triggering
|
1322
|
+
// is ignored unless invoked within a click event)
|
1323
|
+
if (!self.isFocused) {
|
1324
|
+
self.focus();
|
1325
|
+
e.preventDefault();
|
1326
|
+
}
|
1327
|
+
},
|
1328
|
+
|
1329
|
+
/**
|
1330
|
+
* Triggered when the main control element
|
1331
|
+
* has a mouse down event.
|
1332
|
+
*
|
1333
|
+
* @param {object} e
|
1334
|
+
* @return {boolean}
|
1335
|
+
*/
|
1336
|
+
onMouseDown: function(e) {
|
1337
|
+
var self = this;
|
1338
|
+
var defaultPrevented = e.isDefaultPrevented();
|
1339
|
+
var $target = $(e.target);
|
1340
|
+
|
1341
|
+
if (self.isFocused) {
|
1342
|
+
// retain focus by preventing native handling. if the
|
1343
|
+
// event target is the input it should not be modified.
|
1344
|
+
// otherwise, text selection within the input won't work.
|
1345
|
+
if (e.target !== self.$control_input[0]) {
|
1346
|
+
if (self.settings.mode === 'single') {
|
1347
|
+
// toggle dropdown
|
1348
|
+
self.isOpen ? self.close() : self.open();
|
1349
|
+
} else if (!defaultPrevented) {
|
1350
|
+
self.setActiveItem(null);
|
1351
|
+
}
|
1352
|
+
return false;
|
1353
|
+
}
|
1354
|
+
} else {
|
1355
|
+
// give control focus
|
1356
|
+
if (!defaultPrevented) {
|
1357
|
+
window.setTimeout(function() {
|
1358
|
+
self.focus();
|
1359
|
+
}, 0);
|
1360
|
+
}
|
1361
|
+
}
|
1362
|
+
},
|
1363
|
+
|
1199
1364
|
/**
|
1200
1365
|
* Triggered when the value of the control has been changed.
|
1201
1366
|
* This should propagate the event to the original DOM
|
@@ -1267,7 +1432,7 @@
|
|
1267
1432
|
e.preventDefault();
|
1268
1433
|
return;
|
1269
1434
|
case KEY_RETURN:
|
1270
|
-
if (self.$activeOption) {
|
1435
|
+
if (self.isOpen && self.$activeOption) {
|
1271
1436
|
self.onOptionSelect({currentTarget: self.$activeOption});
|
1272
1437
|
}
|
1273
1438
|
e.preventDefault();
|
@@ -1342,7 +1507,6 @@
|
|
1342
1507
|
onFocus: function(e) {
|
1343
1508
|
var self = this;
|
1344
1509
|
|
1345
|
-
self.isInputFocused = true;
|
1346
1510
|
self.isFocused = true;
|
1347
1511
|
if (self.isDisabled) {
|
1348
1512
|
self.blur();
|
@@ -1353,10 +1517,13 @@
|
|
1353
1517
|
if (self.ignoreFocus) return;
|
1354
1518
|
if (self.settings.preload === 'focus') self.onSearchChange('');
|
1355
1519
|
|
1356
|
-
self.
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1520
|
+
if (!self.$activeItems.length) {
|
1521
|
+
self.showInput();
|
1522
|
+
self.setActiveItem(null);
|
1523
|
+
self.refreshOptions(!!self.settings.openOnFocus);
|
1524
|
+
}
|
1525
|
+
|
1526
|
+
self.refreshState();
|
1360
1527
|
},
|
1361
1528
|
|
1362
1529
|
/**
|
@@ -1367,7 +1534,7 @@
|
|
1367
1534
|
*/
|
1368
1535
|
onBlur: function(e) {
|
1369
1536
|
var self = this;
|
1370
|
-
self.
|
1537
|
+
self.isFocused = false;
|
1371
1538
|
if (self.ignoreFocus) return;
|
1372
1539
|
|
1373
1540
|
self.close();
|
@@ -1375,8 +1542,7 @@
|
|
1375
1542
|
self.setActiveItem(null);
|
1376
1543
|
self.setActiveOption(null);
|
1377
1544
|
self.setCaret(self.items.length);
|
1378
|
-
self.
|
1379
|
-
self.refreshClasses();
|
1545
|
+
self.refreshState();
|
1380
1546
|
},
|
1381
1547
|
|
1382
1548
|
/**
|
@@ -1401,9 +1567,10 @@
|
|
1401
1567
|
onOptionSelect: function(e) {
|
1402
1568
|
var value, $target, $option, self = this;
|
1403
1569
|
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1570
|
+
if (e.preventDefault) {
|
1571
|
+
e.preventDefault();
|
1572
|
+
e.stopPropagation();
|
1573
|
+
}
|
1407
1574
|
|
1408
1575
|
$target = $(e.currentTarget);
|
1409
1576
|
if ($target.hasClass('create')) {
|
@@ -1430,11 +1597,10 @@
|
|
1430
1597
|
onItemSelect: function(e) {
|
1431
1598
|
var self = this;
|
1432
1599
|
|
1600
|
+
if (self.isLocked) return;
|
1433
1601
|
if (self.settings.mode === 'multi') {
|
1434
1602
|
e.preventDefault();
|
1435
1603
|
self.setActiveItem(e.currentTarget, e);
|
1436
|
-
self.focus(false);
|
1437
|
-
self.hideInput();
|
1438
1604
|
}
|
1439
1605
|
},
|
1440
1606
|
|
@@ -1454,8 +1620,7 @@
|
|
1454
1620
|
self.loading = Math.max(self.loading - 1, 0);
|
1455
1621
|
if (results && results.length) {
|
1456
1622
|
self.addOption(results);
|
1457
|
-
self.refreshOptions(
|
1458
|
-
if (self.isInputFocused) self.open();
|
1623
|
+
self.refreshOptions(self.isFocused && !self.isInputHidden);
|
1459
1624
|
}
|
1460
1625
|
if (!self.loading) {
|
1461
1626
|
$wrapper.removeClass('loading');
|
@@ -1517,13 +1682,16 @@
|
|
1517
1682
|
var i, idx, begin, end, item, swap;
|
1518
1683
|
var $last;
|
1519
1684
|
|
1685
|
+
if (self.settings.mode === 'single') return;
|
1520
1686
|
$item = $($item);
|
1521
1687
|
|
1522
1688
|
// clear the active selection
|
1523
1689
|
if (!$item.length) {
|
1524
1690
|
$(self.$activeItems).removeClass('active');
|
1525
1691
|
self.$activeItems = [];
|
1526
|
-
self.isFocused
|
1692
|
+
if (self.isFocused) {
|
1693
|
+
self.showInput();
|
1694
|
+
}
|
1527
1695
|
return;
|
1528
1696
|
}
|
1529
1697
|
|
@@ -1560,7 +1728,11 @@
|
|
1560
1728
|
self.$activeItems = [$item.addClass('active')[0]];
|
1561
1729
|
}
|
1562
1730
|
|
1563
|
-
|
1731
|
+
// ensure control has focus
|
1732
|
+
self.hideInput();
|
1733
|
+
if (!this.isFocused) {
|
1734
|
+
self.focus();
|
1735
|
+
}
|
1564
1736
|
},
|
1565
1737
|
|
1566
1738
|
/**
|
@@ -1607,8 +1779,11 @@
|
|
1607
1779
|
*/
|
1608
1780
|
selectAll: function() {
|
1609
1781
|
this.$activeItems = Array.prototype.slice.apply(this.$control.children(':not(input)').addClass('active'));
|
1610
|
-
this.
|
1611
|
-
|
1782
|
+
if (this.$activeItems.length) {
|
1783
|
+
this.hideInput();
|
1784
|
+
this.close();
|
1785
|
+
}
|
1786
|
+
this.focus();
|
1612
1787
|
},
|
1613
1788
|
|
1614
1789
|
/**
|
@@ -1618,9 +1793,8 @@
|
|
1618
1793
|
hideInput: function() {
|
1619
1794
|
var self = this;
|
1620
1795
|
|
1621
|
-
self.close();
|
1622
1796
|
self.setTextboxValue('');
|
1623
|
-
self.$control_input.css({opacity: 0, position: 'absolute', left: -10000});
|
1797
|
+
self.$control_input.css({opacity: 0, position: 'absolute', left: self.rtl ? 10000 : -10000});
|
1624
1798
|
self.isInputHidden = true;
|
1625
1799
|
},
|
1626
1800
|
|
@@ -1639,16 +1813,15 @@
|
|
1639
1813
|
*
|
1640
1814
|
* @param {boolean} trigger
|
1641
1815
|
*/
|
1642
|
-
focus: function(
|
1816
|
+
focus: function() {
|
1643
1817
|
var self = this;
|
1644
|
-
|
1645
1818
|
if (self.isDisabled) return;
|
1819
|
+
|
1646
1820
|
self.ignoreFocus = true;
|
1647
1821
|
self.$control_input[0].focus();
|
1648
|
-
self.isInputFocused = true;
|
1649
1822
|
window.setTimeout(function() {
|
1650
1823
|
self.ignoreFocus = false;
|
1651
|
-
|
1824
|
+
self.onFocus();
|
1652
1825
|
}, 0);
|
1653
1826
|
},
|
1654
1827
|
|
@@ -1681,12 +1854,15 @@
|
|
1681
1854
|
*/
|
1682
1855
|
getSearchOptions: function() {
|
1683
1856
|
var settings = this.settings;
|
1684
|
-
var
|
1857
|
+
var sort = settings.sortField;
|
1858
|
+
if (typeof sort === 'string') {
|
1859
|
+
sort = {field: sort};
|
1860
|
+
}
|
1685
1861
|
|
1686
1862
|
return {
|
1687
|
-
fields
|
1688
|
-
|
1689
|
-
|
1863
|
+
fields : settings.searchField,
|
1864
|
+
conjunction : settings.searchConjunction,
|
1865
|
+
sort : sort
|
1690
1866
|
};
|
1691
1867
|
},
|
1692
1868
|
|
@@ -1746,17 +1922,18 @@
|
|
1746
1922
|
* @param {boolean} triggerDropdown
|
1747
1923
|
*/
|
1748
1924
|
refreshOptions: function(triggerDropdown) {
|
1925
|
+
var i, j, k, n, groups, groups_order, option, option_html, optgroup, optgroups, html, html_children, has_create_option;
|
1926
|
+
var $active, $active_before, $create;
|
1927
|
+
|
1749
1928
|
if (typeof triggerDropdown === 'undefined') {
|
1750
1929
|
triggerDropdown = true;
|
1751
1930
|
}
|
1752
1931
|
|
1753
|
-
var self
|
1754
|
-
var
|
1755
|
-
var
|
1756
|
-
var query = self.$control_input.val();
|
1757
|
-
var results = self.search(query);
|
1758
|
-
var $active, $create;
|
1932
|
+
var self = this;
|
1933
|
+
var query = self.$control_input.val();
|
1934
|
+
var results = self.search(query);
|
1759
1935
|
var $dropdown_content = self.$dropdown_content;
|
1936
|
+
var active_before = self.$activeOption && hash_key(self.$activeOption.attr('data-value'));
|
1760
1937
|
|
1761
1938
|
// build markup
|
1762
1939
|
n = results.items.length;
|
@@ -1777,16 +1954,22 @@
|
|
1777
1954
|
}
|
1778
1955
|
|
1779
1956
|
for (i = 0; i < n; i++) {
|
1780
|
-
option
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1957
|
+
option = self.options[results.items[i].id];
|
1958
|
+
option_html = self.render('option', option);
|
1959
|
+
optgroup = option[self.settings.optgroupField] || '';
|
1960
|
+
optgroups = $.isArray(optgroup) ? optgroup : [optgroup];
|
1961
|
+
|
1962
|
+
for (j = 0, k = optgroups && optgroups.length; j < k; j++) {
|
1963
|
+
optgroup = optgroups[j];
|
1964
|
+
if (!self.optgroups.hasOwnProperty(optgroup)) {
|
1965
|
+
optgroup = '';
|
1966
|
+
}
|
1967
|
+
if (!groups.hasOwnProperty(optgroup)) {
|
1968
|
+
groups[optgroup] = [];
|
1969
|
+
groups_order.push(optgroup);
|
1970
|
+
}
|
1971
|
+
groups[optgroup].push(option_html);
|
1788
1972
|
}
|
1789
|
-
groups[optgroup].push(self.render('option', option));
|
1790
1973
|
}
|
1791
1974
|
|
1792
1975
|
// render optgroup headers & join groups
|
@@ -1823,20 +2006,28 @@
|
|
1823
2006
|
}
|
1824
2007
|
|
1825
2008
|
// add create option
|
1826
|
-
|
1827
|
-
if (
|
2009
|
+
has_create_option = self.settings.create && results.query.length;
|
2010
|
+
if (has_create_option) {
|
1828
2011
|
$dropdown_content.prepend(self.render('option_create', {input: query}));
|
1829
2012
|
$create = $($dropdown_content[0].childNodes[0]);
|
1830
2013
|
}
|
1831
2014
|
|
1832
2015
|
// activate
|
1833
|
-
self.hasOptions = results.items.length > 0 ||
|
2016
|
+
self.hasOptions = results.items.length > 0 || has_create_option;
|
1834
2017
|
if (self.hasOptions) {
|
1835
2018
|
if (results.items.length > 0) {
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
2019
|
+
$active_before = active_before && self.getOption(active_before);
|
2020
|
+
if ($active_before && $active_before.length) {
|
2021
|
+
$active = $active_before;
|
2022
|
+
} else if (self.settings.mode === 'single' && self.items.length) {
|
2023
|
+
$active = self.getOption(self.items[0]);
|
2024
|
+
}
|
2025
|
+
if (!$active || !$active.length) {
|
2026
|
+
if ($create && !self.settings.addPrecedence) {
|
2027
|
+
$active = self.getAdjacentOption($create, 1);
|
2028
|
+
} else {
|
2029
|
+
$active = $dropdown_content.find('[data-selectable]:first');
|
2030
|
+
}
|
1840
2031
|
}
|
1841
2032
|
} else {
|
1842
2033
|
$active = $create;
|
@@ -2060,7 +2251,7 @@
|
|
2060
2251
|
$item = $(self.render('item', self.options[value]));
|
2061
2252
|
self.items.splice(self.caretPos, 0, value);
|
2062
2253
|
self.insertAtCaret($item);
|
2063
|
-
self.
|
2254
|
+
self.refreshState();
|
2064
2255
|
|
2065
2256
|
if (self.isSetup) {
|
2066
2257
|
options = self.$dropdown_content.find('[data-selectable]');
|
@@ -2080,19 +2271,6 @@
|
|
2080
2271
|
self.positionDropdown();
|
2081
2272
|
}
|
2082
2273
|
|
2083
|
-
// restore focus to input
|
2084
|
-
if (self.isFocused) {
|
2085
|
-
window.setTimeout(function() {
|
2086
|
-
if (inputMode === 'single') {
|
2087
|
-
self.blur();
|
2088
|
-
self.focus(false);
|
2089
|
-
self.hideInput();
|
2090
|
-
} else {
|
2091
|
-
self.focus(false);
|
2092
|
-
}
|
2093
|
-
}, 0);
|
2094
|
-
}
|
2095
|
-
|
2096
2274
|
self.updatePlaceholder();
|
2097
2275
|
self.trigger('item_add', value, $item);
|
2098
2276
|
self.updateOriginalInput();
|
@@ -2131,7 +2309,7 @@
|
|
2131
2309
|
self.setCaret(self.caretPos - 1);
|
2132
2310
|
}
|
2133
2311
|
|
2134
|
-
self.
|
2312
|
+
self.refreshState();
|
2135
2313
|
self.updatePlaceholder();
|
2136
2314
|
self.updateOriginalInput();
|
2137
2315
|
self.positionDropdown();
|
@@ -2163,7 +2341,6 @@
|
|
2163
2341
|
|
2164
2342
|
var create = once(function(data) {
|
2165
2343
|
self.unlock();
|
2166
|
-
self.focus(false);
|
2167
2344
|
|
2168
2345
|
if (!data || typeof data !== 'object') return;
|
2169
2346
|
var value = hash_key(data[self.settings.valueField]);
|
@@ -2174,7 +2351,6 @@
|
|
2174
2351
|
self.setCaret(caret);
|
2175
2352
|
self.addItem(value);
|
2176
2353
|
self.refreshOptions(self.settings.mode !== 'single');
|
2177
|
-
self.focus(false);
|
2178
2354
|
});
|
2179
2355
|
|
2180
2356
|
var output = setup.apply(this, [input, create]);
|
@@ -2195,25 +2371,45 @@
|
|
2195
2371
|
}
|
2196
2372
|
}
|
2197
2373
|
|
2198
|
-
this.
|
2374
|
+
this.refreshState();
|
2199
2375
|
this.updateOriginalInput();
|
2200
2376
|
},
|
2201
2377
|
|
2378
|
+
/**
|
2379
|
+
* Updates all state-dependent attributes
|
2380
|
+
* and CSS classes.
|
2381
|
+
*/
|
2382
|
+
refreshState: function() {
|
2383
|
+
var self = this;
|
2384
|
+
var invalid = self.isRequired && !self.items.length;
|
2385
|
+
if (!invalid) self.isInvalid = false;
|
2386
|
+
self.$control_input.prop('required', invalid);
|
2387
|
+
self.refreshClasses();
|
2388
|
+
},
|
2389
|
+
|
2202
2390
|
/**
|
2203
2391
|
* Updates all state-dependent CSS classes.
|
2204
2392
|
*/
|
2205
2393
|
refreshClasses: function() {
|
2206
|
-
var self
|
2207
|
-
var isFull
|
2394
|
+
var self = this;
|
2395
|
+
var isFull = self.isFull();
|
2208
2396
|
var isLocked = self.isLocked;
|
2397
|
+
|
2398
|
+
this.$wrapper
|
2399
|
+
.toggleClass('rtl', self.rtl);
|
2400
|
+
|
2209
2401
|
this.$control
|
2210
2402
|
.toggleClass('focus', self.isFocused)
|
2211
2403
|
.toggleClass('disabled', self.isDisabled)
|
2404
|
+
.toggleClass('required', self.isRequired)
|
2405
|
+
.toggleClass('invalid', self.isInvalid)
|
2212
2406
|
.toggleClass('locked', isLocked)
|
2213
2407
|
.toggleClass('full', isFull).toggleClass('not-full', !isFull)
|
2408
|
+
.toggleClass('input-active', self.isFocused && !self.isInputHidden)
|
2214
2409
|
.toggleClass('dropdown-active', self.isOpen)
|
2215
2410
|
.toggleClass('has-options', !$.isEmptyObject(self.options))
|
2216
2411
|
.toggleClass('has-items', self.items.length > 0);
|
2412
|
+
|
2217
2413
|
this.$control_input.data('grow', !isFull && !isLocked);
|
2218
2414
|
},
|
2219
2415
|
|
@@ -2276,9 +2472,9 @@
|
|
2276
2472
|
var self = this;
|
2277
2473
|
|
2278
2474
|
if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return;
|
2279
|
-
self.focus(
|
2475
|
+
self.focus();
|
2280
2476
|
self.isOpen = true;
|
2281
|
-
self.
|
2477
|
+
self.refreshState();
|
2282
2478
|
self.$dropdown.css({visibility: 'hidden', display: 'block'});
|
2283
2479
|
self.positionDropdown();
|
2284
2480
|
self.$dropdown.css({visibility: 'visible'});
|
@@ -2290,13 +2486,18 @@
|
|
2290
2486
|
*/
|
2291
2487
|
close: function() {
|
2292
2488
|
var self = this;
|
2489
|
+
var trigger = self.isOpen;
|
2293
2490
|
|
2294
|
-
if (
|
2491
|
+
if (self.settings.mode === 'single' && this.items.length) {
|
2492
|
+
self.hideInput();
|
2493
|
+
}
|
2494
|
+
|
2495
|
+
self.isOpen = false;
|
2295
2496
|
self.$dropdown.hide();
|
2296
2497
|
self.setActiveOption(null);
|
2297
|
-
self.
|
2298
|
-
|
2299
|
-
self.trigger('dropdown_close', self.$dropdown);
|
2498
|
+
self.refreshState();
|
2499
|
+
|
2500
|
+
if (trigger) self.trigger('dropdown_close', self.$dropdown);
|
2300
2501
|
},
|
2301
2502
|
|
2302
2503
|
/**
|
@@ -2328,7 +2529,7 @@
|
|
2328
2529
|
self.setCaret(0);
|
2329
2530
|
self.updatePlaceholder();
|
2330
2531
|
self.updateOriginalInput();
|
2331
|
-
self.
|
2532
|
+
self.refreshState();
|
2332
2533
|
self.showInput();
|
2333
2534
|
self.trigger('clear');
|
2334
2535
|
},
|
@@ -2431,11 +2632,12 @@
|
|
2431
2632
|
var self = this;
|
2432
2633
|
|
2433
2634
|
if (direction === 0) return;
|
2635
|
+
if (self.rtl) direction *= -1;
|
2434
2636
|
|
2435
2637
|
tail = direction > 0 ? 'last' : 'first';
|
2436
2638
|
selection = getSelection(self.$control_input[0]);
|
2437
2639
|
|
2438
|
-
if (self.
|
2640
|
+
if (self.isFocused && !self.isInputHidden) {
|
2439
2641
|
valueLength = self.$control_input.val().length;
|
2440
2642
|
cursorAtEdge = direction < 0
|
2441
2643
|
? selection.start === 0 && selection.length === 0
|
@@ -2450,7 +2652,6 @@
|
|
2450
2652
|
idx = self.$control.children(':not(input)').index($tail);
|
2451
2653
|
self.setActiveItem(null);
|
2452
2654
|
self.setCaret(direction > 0 ? idx + 1 : idx);
|
2453
|
-
self.showInput();
|
2454
2655
|
}
|
2455
2656
|
}
|
2456
2657
|
},
|
@@ -2462,11 +2663,13 @@
|
|
2462
2663
|
* @param {object} e (optional)
|
2463
2664
|
*/
|
2464
2665
|
advanceCaret: function(direction, e) {
|
2666
|
+
var self = this, fn, $adj;
|
2667
|
+
|
2465
2668
|
if (direction === 0) return;
|
2466
|
-
|
2467
|
-
|
2669
|
+
|
2670
|
+
fn = direction > 0 ? 'next' : 'prev';
|
2468
2671
|
if (self.isShiftDown) {
|
2469
|
-
|
2672
|
+
$adj = self.$control_input[fn]();
|
2470
2673
|
if ($adj.length) {
|
2471
2674
|
self.hideInput();
|
2472
2675
|
self.setActiveItem($adj);
|
@@ -2515,7 +2718,7 @@
|
|
2515
2718
|
lock: function() {
|
2516
2719
|
this.close();
|
2517
2720
|
this.isLocked = true;
|
2518
|
-
this.
|
2721
|
+
this.refreshState();
|
2519
2722
|
},
|
2520
2723
|
|
2521
2724
|
/**
|
@@ -2523,7 +2726,7 @@
|
|
2523
2726
|
*/
|
2524
2727
|
unlock: function() {
|
2525
2728
|
this.isLocked = false;
|
2526
|
-
this.
|
2729
|
+
this.refreshState();
|
2527
2730
|
},
|
2528
2731
|
|
2529
2732
|
/**
|
@@ -2637,6 +2840,7 @@
|
|
2637
2840
|
maxOptions: 1000,
|
2638
2841
|
maxItems: null,
|
2639
2842
|
hideSelected: null,
|
2843
|
+
addPrecedence: false,
|
2640
2844
|
preload: false,
|
2641
2845
|
|
2642
2846
|
scrollDuration: 60,
|
@@ -2644,14 +2848,15 @@
|
|
2644
2848
|
|
2645
2849
|
dataAttr: 'data-data',
|
2646
2850
|
optgroupField: 'optgroup',
|
2647
|
-
sortField: '$order',
|
2648
|
-
sortDirection: 'asc',
|
2649
2851
|
valueField: 'value',
|
2650
2852
|
labelField: 'text',
|
2651
2853
|
optgroupLabelField: 'label',
|
2652
2854
|
optgroupValueField: 'value',
|
2653
2855
|
optgroupOrder: null,
|
2856
|
+
|
2857
|
+
sortField: '$order',
|
2654
2858
|
searchField: ['text'],
|
2859
|
+
searchConjunction: 'and',
|
2655
2860
|
|
2656
2861
|
mode: null,
|
2657
2862
|
wrapperClass: 'selectize-control',
|
@@ -2689,28 +2894,33 @@
|
|
2689
2894
|
}
|
2690
2895
|
};
|
2691
2896
|
|
2692
|
-
$.fn.selectize = function(
|
2693
|
-
|
2694
|
-
|
2695
|
-
var
|
2696
|
-
var
|
2897
|
+
$.fn.selectize = function(settings_user) {
|
2898
|
+
var defaults = $.fn.selectize.defaults;
|
2899
|
+
var settings = $.extend({}, defaults, settings_user);
|
2900
|
+
var attr_data = settings.dataAttr;
|
2901
|
+
var field_label = settings.labelField;
|
2902
|
+
var field_value = settings.valueField;
|
2903
|
+
var field_optgroup = settings.optgroupField;
|
2904
|
+
var field_optgroup_label = settings.optgroupLabelField;
|
2905
|
+
var field_optgroup_value = settings.optgroupValueField;
|
2697
2906
|
|
2698
2907
|
/**
|
2699
2908
|
* Initializes selectize from a <input type="text"> element.
|
2700
2909
|
*
|
2701
2910
|
* @param {object} $input
|
2702
|
-
* @param {object}
|
2911
|
+
* @param {object} settings_element
|
2703
2912
|
*/
|
2704
2913
|
var init_textbox = function($input, settings_element) {
|
2705
|
-
var i, n, values, value = $.trim($input.val() || '');
|
2914
|
+
var i, n, values, option, value = $.trim($input.val() || '');
|
2706
2915
|
if (!value.length) return;
|
2707
2916
|
|
2708
|
-
values = value.split(settings.delimiter
|
2917
|
+
values = value.split(settings.delimiter);
|
2709
2918
|
for (i = 0, n = values.length; i < n; i++) {
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2919
|
+
option = {};
|
2920
|
+
option[field_label] = values[i];
|
2921
|
+
option[field_value] = values[i];
|
2922
|
+
|
2923
|
+
settings_element.options[values[i]] = option;
|
2714
2924
|
}
|
2715
2925
|
|
2716
2926
|
settings_element.items = values;
|
@@ -2720,16 +2930,14 @@
|
|
2720
2930
|
* Initializes selectize from a <select> element.
|
2721
2931
|
*
|
2722
2932
|
* @param {object} $input
|
2723
|
-
* @param {object}
|
2933
|
+
* @param {object} settings_element
|
2724
2934
|
*/
|
2725
2935
|
var init_select = function($input, settings_element) {
|
2726
|
-
var i, n, tagName;
|
2727
|
-
var
|
2728
|
-
var order = 0;
|
2729
|
-
settings_element.maxItems = !!$input.attr('multiple') ? null : 1;
|
2936
|
+
var i, n, tagName, $children, order = 0;
|
2937
|
+
var options = settings_element.options;
|
2730
2938
|
|
2731
2939
|
var readData = function($el) {
|
2732
|
-
var data =
|
2940
|
+
var data = attr_data && $el.attr(attr_data);
|
2733
2941
|
if (typeof data === 'string' && data.length) {
|
2734
2942
|
return JSON.parse(data);
|
2735
2943
|
}
|
@@ -2744,14 +2952,30 @@
|
|
2744
2952
|
value = $option.attr('value') || '';
|
2745
2953
|
if (!value.length) return;
|
2746
2954
|
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2955
|
+
// if the option already exists, it's probably been
|
2956
|
+
// duplicated in another optgroup. in this case, push
|
2957
|
+
// the current group to the "optgroup" property on the
|
2958
|
+
// existing option so that it's rendered in both places.
|
2959
|
+
if (options.hasOwnProperty(value)) {
|
2960
|
+
if (group) {
|
2961
|
+
if (!options[value].optgroup) {
|
2962
|
+
options[value].optgroup = group;
|
2963
|
+
} else if (!$.isArray(options[value].optgroup)) {
|
2964
|
+
options[value].optgroup = [options[value].optgroup, group];
|
2965
|
+
} else {
|
2966
|
+
options[value].optgroup.push(group);
|
2967
|
+
}
|
2968
|
+
}
|
2969
|
+
return;
|
2970
|
+
}
|
2971
|
+
|
2972
|
+
option = readData($option) || {};
|
2973
|
+
option[field_label] = option[field_label] || $option.text();
|
2974
|
+
option[field_value] = option[field_value] || value;
|
2975
|
+
option[field_optgroup] = option[field_optgroup] || group;
|
2752
2976
|
|
2753
2977
|
option.$order = ++order;
|
2754
|
-
|
2978
|
+
options[value] = option;
|
2755
2979
|
|
2756
2980
|
if ($option.is(':selected')) {
|
2757
2981
|
settings_element.items.push(value);
|
@@ -2759,21 +2983,26 @@
|
|
2759
2983
|
};
|
2760
2984
|
|
2761
2985
|
var addGroup = function($optgroup) {
|
2762
|
-
var i, n,
|
2986
|
+
var i, n, id, optgroup, $options;
|
2987
|
+
|
2763
2988
|
$optgroup = $($optgroup);
|
2989
|
+
id = $optgroup.attr('label');
|
2764
2990
|
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2991
|
+
if (id) {
|
2992
|
+
optgroup = readData($optgroup) || {};
|
2993
|
+
optgroup[field_optgroup_label] = id;
|
2994
|
+
optgroup[field_optgroup_value] = id;
|
2995
|
+
settings_element.optgroups[id] = optgroup;
|
2770
2996
|
}
|
2771
2997
|
|
2998
|
+
$options = $('option', $optgroup);
|
2772
2999
|
for (i = 0, n = $options.length; i < n; i++) {
|
2773
3000
|
addOption($options[i], id);
|
2774
3001
|
}
|
2775
3002
|
};
|
2776
3003
|
|
3004
|
+
settings_element.maxItems = $input.attr('multiple') ? null : 1;
|
3005
|
+
|
2777
3006
|
$children = $input.children();
|
2778
3007
|
for (i = 0, n = $children.length; i < n; i++) {
|
2779
3008
|
tagName = $children[i].tagName.toLowerCase();
|
@@ -2786,9 +3015,11 @@
|
|
2786
3015
|
};
|
2787
3016
|
|
2788
3017
|
return this.each(function() {
|
3018
|
+
if (this.selectize) return;
|
3019
|
+
|
2789
3020
|
var instance;
|
2790
3021
|
var $input = $(this);
|
2791
|
-
var tag_name =
|
3022
|
+
var tag_name = this.tagName.toLowerCase();
|
2792
3023
|
var settings_element = {
|
2793
3024
|
'placeholder' : $input.children('option[value=""]').text() || $input.attr('placeholder'),
|
2794
3025
|
'options' : {},
|
@@ -2802,7 +3033,7 @@
|
|
2802
3033
|
init_textbox($input, settings_element);
|
2803
3034
|
}
|
2804
3035
|
|
2805
|
-
instance = new Selectize($input, $.extend(true, {}, defaults, settings_element,
|
3036
|
+
instance = new Selectize($input, $.extend(true, {}, defaults, settings_element, settings_user));
|
2806
3037
|
$input.data('selectize', instance);
|
2807
3038
|
$input.addClass('selectized');
|
2808
3039
|
});
|
@@ -2815,21 +3046,40 @@
|
|
2815
3046
|
if (this.settings.mode !== 'multi') return;
|
2816
3047
|
var self = this;
|
2817
3048
|
|
2818
|
-
|
3049
|
+
self.lock = (function() {
|
3050
|
+
var original = self.lock;
|
3051
|
+
return function() {
|
3052
|
+
var sortable = self.$control.data('sortable');
|
3053
|
+
if (sortable) sortable.disable();
|
3054
|
+
return original.apply(self, arguments);
|
3055
|
+
};
|
3056
|
+
})();
|
3057
|
+
|
3058
|
+
self.unlock = (function() {
|
3059
|
+
var original = self.unlock;
|
3060
|
+
return function() {
|
3061
|
+
var sortable = self.$control.data('sortable');
|
3062
|
+
if (sortable) sortable.enable();
|
3063
|
+
return original.apply(self, arguments);
|
3064
|
+
};
|
3065
|
+
})();
|
3066
|
+
|
3067
|
+
self.setup = (function() {
|
2819
3068
|
var original = self.setup;
|
2820
3069
|
return function() {
|
2821
3070
|
original.apply(this, arguments);
|
2822
3071
|
|
2823
|
-
var $control =
|
3072
|
+
var $control = self.$control.sortable({
|
2824
3073
|
items: '[data-value]',
|
2825
3074
|
forcePlaceholderSize: true,
|
3075
|
+
disabled: self.isLocked,
|
2826
3076
|
start: function(e, ui) {
|
2827
3077
|
ui.placeholder.css('width', ui.helper.css('width'));
|
2828
3078
|
$control.css({overflow: 'visible'});
|
2829
3079
|
},
|
2830
3080
|
stop: function() {
|
2831
3081
|
$control.css({overflow: 'hidden'});
|
2832
|
-
var active =
|
3082
|
+
var active = self.$activeItems ? self.$activeItems.slice() : null;
|
2833
3083
|
var values = [];
|
2834
3084
|
$control.children('[data-value]').each(function() {
|
2835
3085
|
values.push($(this).attr('data-value'));
|
@@ -2960,7 +3210,7 @@
|
|
2960
3210
|
label : '×',
|
2961
3211
|
title : 'Remove',
|
2962
3212
|
className : 'remove',
|
2963
|
-
append : true
|
3213
|
+
append : true
|
2964
3214
|
}, options);
|
2965
3215
|
|
2966
3216
|
var self = this;
|
@@ -2994,6 +3244,8 @@
|
|
2994
3244
|
// add event listener
|
2995
3245
|
this.$control.on('click', '.' + options.className, function(e) {
|
2996
3246
|
e.preventDefault();
|
3247
|
+
if (self.isLocked) return;
|
3248
|
+
|
2997
3249
|
var $item = $(e.target).parent();
|
2998
3250
|
self.setActiveItem($item);
|
2999
3251
|
if (self.deleteSelection()) {
|