selectize-rails 0.7.7 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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()) {
|