|
1 | 1 | /** |
2 | | - * selectize.js (v0.8.5) |
| 2 | + * selectize.js (v0.9.0) |
3 | 3 | * Copyright (c) 2013 Brian Reavis & contributors |
4 | 4 | * |
5 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this |
|
20 | 20 | (function(root, factory) { |
21 | 21 | if (typeof define === 'function' && define.amd) { |
22 | 22 | define(['jquery','sifter','microplugin'], factory); |
| 23 | + } else if (typeof exports === 'object') { |
| 24 | + module.exports = factory(require('jquery'), require('sifter'), require('microplugin')); |
23 | 25 | } else { |
24 | 26 | root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin); |
25 | 27 | } |
|
105 | 107 | var KEY_ESC = 27; |
106 | 108 | var KEY_LEFT = 37; |
107 | 109 | var KEY_UP = 38; |
| 110 | + var KEY_P = 80; |
108 | 111 | var KEY_RIGHT = 39; |
109 | 112 | var KEY_DOWN = 40; |
| 113 | + var KEY_N = 78; |
110 | 114 | var KEY_BACKSPACE = 8; |
111 | 115 | var KEY_DELETE = 46; |
112 | 116 | var KEY_SHIFT = 16; |
|
117 | 121 | var TAG_SELECT = 1; |
118 | 122 | var TAG_INPUT = 2; |
119 | 123 |
|
| 124 | + |
120 | 125 | var isset = function(object) { |
121 | 126 | return typeof object !== 'undefined'; |
122 | 127 | }; |
|
363 | 368 | * @returns {int} |
364 | 369 | */ |
365 | 370 | var measureString = function(str, $parent) { |
| 371 | + if (!str) { |
| 372 | + return 0; |
| 373 | + } |
| 374 | + |
366 | 375 | var $test = $('<test>').css({ |
367 | 376 | position: 'absolute', |
368 | 377 | top: -99999, |
|
396 | 405 | * @param {object} $input |
397 | 406 | */ |
398 | 407 | var autoGrow = function($input) { |
| 408 | + var currentWidth = null; |
| 409 | + |
399 | 410 | var update = function(e) { |
400 | 411 | var value, keyCode, printable, placeholder, width; |
401 | 412 | var shift, character, selection; |
|
438 | 449 | } |
439 | 450 |
|
440 | 451 | width = measureString(value, $input) + 4; |
441 | | - if (width !== $input.width()) { |
| 452 | + if (width !== currentWidth) { |
| 453 | + currentWidth = width; |
442 | 454 | $input.width(width); |
443 | 455 | $input.triggerHandler('resize'); |
444 | 456 | } |
|
560 | 572 |
|
561 | 573 | $wrapper = $('<div>').addClass(settings.wrapperClass).addClass(classes).addClass(inputMode); |
562 | 574 | $control = $('<div>').addClass(settings.inputClass).addClass('items').appendTo($wrapper); |
563 | | - $control_input = $('<input type="text" autocomplete="off">').appendTo($control).attr('tabindex', tab_index); |
| 575 | + $control_input = $('<input type="text" autocomplete="off" />').appendTo($control).attr('tabindex', tab_index); |
564 | 576 | $dropdown_parent = $(settings.dropdownParent || $wrapper); |
565 | 577 | $dropdown = $('<div>').addClass(settings.dropdownClass).addClass(classes).addClass(inputMode).hide().appendTo($dropdown_parent); |
566 | 578 | $dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown); |
|
680 | 692 | self.trigger('initialize'); |
681 | 693 |
|
682 | 694 | // preload options |
683 | | - if (settings.preload) { |
| 695 | + if (settings.preload === true) { |
684 | 696 | self.onSearchChange(''); |
685 | 697 | } |
686 | 698 | }, |
|
846 | 858 | case KEY_ESC: |
847 | 859 | self.close(); |
848 | 860 | return; |
| 861 | + case KEY_N: |
| 862 | + if (!e.ctrlKey) break; |
849 | 863 | case KEY_DOWN: |
850 | 864 | if (!self.isOpen && self.hasOptions) { |
851 | 865 | self.open(); |
|
856 | 870 | } |
857 | 871 | e.preventDefault(); |
858 | 872 | return; |
| 873 | + case KEY_P: |
| 874 | + if (!e.ctrlKey) break; |
859 | 875 | case KEY_UP: |
860 | 876 | if (self.$activeOption) { |
861 | 877 | self.ignoreHover = true; |
|
877 | 893 | self.advanceSelection(1, e); |
878 | 894 | return; |
879 | 895 | case KEY_TAB: |
| 896 | + if (self.isOpen && self.$activeOption) { |
| 897 | + self.onOptionSelect({currentTarget: self.$activeOption}); |
| 898 | + } |
880 | 899 | if (self.settings.create && self.createItem()) { |
881 | 900 | e.preventDefault(); |
882 | 901 | } |
|
970 | 989 | if (self.ignoreFocus) return; |
971 | 990 |
|
972 | 991 | if (self.settings.create && self.settings.createOnBlur) { |
973 | | - self.createItem(); |
| 992 | + self.createItem(false); |
974 | 993 | } |
975 | 994 |
|
976 | 995 | self.close(); |
|
1100 | 1119 | setValue: function(value) { |
1101 | 1120 | debounce_events(this, ['change'], function() { |
1102 | 1121 | this.clear(); |
1103 | | - var items = $.isArray(value) ? value : [value]; |
1104 | | - for (var i = 0, n = items.length; i < n; i++) { |
1105 | | - this.addItem(items[i]); |
1106 | | - } |
| 1122 | + this.addItems(value); |
1107 | 1123 | }); |
1108 | 1124 | }, |
1109 | 1125 |
|
|
1669 | 1685 | return this.getElementWithValue(value, this.$control.children()); |
1670 | 1686 | }, |
1671 | 1687 |
|
| 1688 | + /** |
| 1689 | + * "Selects" multiple items at once. Adds them to the list |
| 1690 | + * at the current caret position. |
| 1691 | + * |
| 1692 | + * @param {string} value |
| 1693 | + */ |
| 1694 | + addItems: function(values) { |
| 1695 | + var items = $.isArray(values) ? values : [values]; |
| 1696 | + for (var i = 0, n = items.length; i < n; i++) { |
| 1697 | + this.isPending = (i < n - 1); |
| 1698 | + this.addItem(items[i]); |
| 1699 | + } |
| 1700 | + }, |
| 1701 | + |
1672 | 1702 | /** |
1673 | 1703 | * "Selects" an item. Adds it to the list |
1674 | 1704 | * at the current caret position. |
|
1677 | 1707 | */ |
1678 | 1708 | addItem: function(value) { |
1679 | 1709 | debounce_events(this, ['change'], function() { |
1680 | | - var $item, $option; |
| 1710 | + var $item, $option, $options; |
1681 | 1711 | var self = this; |
1682 | 1712 | var inputMode = self.settings.mode; |
1683 | | - var i, active, options, value_next; |
| 1713 | + var i, active, value_next; |
1684 | 1714 | value = hash_key(value); |
1685 | 1715 |
|
1686 | 1716 | if (self.items.indexOf(value) !== -1) { |
|
1698 | 1728 | self.refreshState(); |
1699 | 1729 |
|
1700 | 1730 | if (self.isSetup) { |
1701 | | - options = self.$dropdown_content.find('[data-selectable]'); |
1702 | | - |
1703 | | - // update menu / remove the option |
1704 | | - $option = self.getOption(value); |
1705 | | - value_next = self.getAdjacentOption($option, 1).attr('data-value'); |
1706 | | - self.refreshOptions(self.isFocused && inputMode !== 'single'); |
1707 | | - if (value_next) { |
1708 | | - self.setActiveOption(self.getOption(value_next)); |
| 1731 | + $options = self.$dropdown_content.find('[data-selectable]'); |
| 1732 | + |
| 1733 | + // update menu / remove the option (if this is not one item being added as part of series) |
| 1734 | + if (!this.isPending) { |
| 1735 | + $option = self.getOption(value); |
| 1736 | + value_next = self.getAdjacentOption($option, 1).attr('data-value'); |
| 1737 | + self.refreshOptions(self.isFocused && inputMode !== 'single'); |
| 1738 | + if (value_next) { |
| 1739 | + self.setActiveOption(self.getOption(value_next)); |
| 1740 | + } |
1709 | 1741 | } |
1710 | 1742 |
|
1711 | 1743 | // hide the menu if the maximum number of items have been selected or no options are left |
1712 | | - if (!options.length || (self.settings.maxItems !== null && self.items.length >= self.settings.maxItems)) { |
| 1744 | + if (!$options.length || (self.settings.maxItems !== null && self.items.length >= self.settings.maxItems)) { |
1713 | 1745 | self.close(); |
1714 | 1746 | } else { |
1715 | 1747 | self.positionDropdown(); |
|
1771 | 1803 | * |
1772 | 1804 | * @return {boolean} |
1773 | 1805 | */ |
1774 | | - createItem: function() { |
| 1806 | + createItem: function(triggerDropdown) { |
1775 | 1807 | var self = this; |
1776 | 1808 | var input = $.trim(self.$control_input.val() || ''); |
1777 | 1809 | var caret = self.caretPos; |
1778 | 1810 | if (!input.length) return false; |
1779 | 1811 | self.lock(); |
1780 | 1812 |
|
| 1813 | + if (typeof triggerDropdown === 'undefined') { |
| 1814 | + triggerDropdown = true; |
| 1815 | + } |
| 1816 | + |
1781 | 1817 | var setup = (typeof self.settings.create === 'function') ? this.settings.create : function(input) { |
1782 | 1818 | var data = {}; |
1783 | 1819 | data[self.settings.labelField] = input; |
|
1796 | 1832 | self.addOption(data); |
1797 | 1833 | self.setCaret(caret); |
1798 | 1834 | self.addItem(value); |
1799 | | - self.refreshOptions(self.settings.mode !== 'single'); |
| 1835 | + self.refreshOptions(triggerDropdown && self.settings.mode !== 'single'); |
1800 | 1836 | }); |
1801 | 1837 |
|
1802 | 1838 | var output = setup.apply(this, [input, create]); |
|
2704 | 2740 | e.preventDefault(); |
2705 | 2741 | if (self.isLocked) return; |
2706 | 2742 |
|
2707 | | - var $item = $(e.target).parent(); |
| 2743 | + var $item = $(e.currentTarget).parent(); |
2708 | 2744 | self.setActiveItem($item); |
2709 | 2745 | if (self.deleteSelection()) { |
2710 | 2746 | self.setCaret(self.items.length); |
|
0 commit comments