|
1 | 1 | /**
|
2 |
| - * selectize.js (v0.12.2) |
| 2 | + * selectize.js (v0.12.3) |
3 | 3 | * Copyright (c) 2013–2015 Brian Reavis & contributors
|
4 | 4 | *
|
5 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
60 | 60 | });
|
61 | 61 | };
|
62 | 62 |
|
| 63 | + /** |
| 64 | + * removeHighlight fn copied from highlight v5 and |
| 65 | + * edited to remove with() and pass js strict mode |
| 66 | + */ |
| 67 | + jQuery.fn.removeHighlight = function() { |
| 68 | + return this.find("span.highlight").each(function() { |
| 69 | + this.parentNode.firstChild.nodeName; |
| 70 | + var parent = this.parentNode; |
| 71 | + parent.replaceChild(this.firstChild, this); |
| 72 | + parent.normalize(); |
| 73 | + }).end(); |
| 74 | + }; |
| 75 | + |
| 76 | + |
63 | 77 | var MicroEvent = function() {};
|
64 | 78 | MicroEvent.prototype = {
|
65 | 79 | on: function(event, fct){
|
|
122 | 136 | var TAG_INPUT = 2;
|
123 | 137 |
|
124 | 138 | // for now, android support in general is too spotty to support validity
|
125 |
| - var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('form').validity; |
| 139 | + var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('input').validity; |
| 140 | + |
126 | 141 |
|
127 | 142 | var isset = function(object) {
|
128 | 143 | return typeof object !== 'undefined';
|
|
452 | 467 | return tmp.innerHTML;
|
453 | 468 | };
|
454 | 469 |
|
| 470 | + var logError = function(message, options){ |
| 471 | + if(!options) options = {}; |
| 472 | + var component = "Selectize"; |
| 473 | + |
| 474 | + console.error(component + ": " + message) |
| 475 | + |
| 476 | + if(options.explanation){ |
| 477 | + // console.group is undefined in <IE11 |
| 478 | + if(console.group) console.group(); |
| 479 | + console.error(options.explanation); |
| 480 | + if(console.group) console.groupEnd(); |
| 481 | + } |
| 482 | + } |
| 483 | + |
455 | 484 |
|
456 | 485 | var Selectize = function($input, settings) {
|
457 | 486 | var key, i, n, dir, input, self = this;
|
|
541 | 570 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
542 | 571 |
|
543 | 572 | MicroEvent.mixin(Selectize);
|
544 |
| - MicroPlugin.mixin(Selectize); |
| 573 | + |
| 574 | + if(typeof MicroPlugin !== "undefined"){ |
| 575 | + MicroPlugin.mixin(Selectize); |
| 576 | + }else{ |
| 577 | + logError("Dependency MicroPlugin is missing", |
| 578 | + {explanation: |
| 579 | + "Make sure you either: (1) are using the \"standalone\" "+ |
| 580 | + "version of Selectize, or (2) require MicroPlugin before you "+ |
| 581 | + "load Selectize."} |
| 582 | + ); |
| 583 | + } |
| 584 | + |
545 | 585 |
|
546 | 586 | // methods
|
547 | 587 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
570 | 610 | var timeout_focus;
|
571 | 611 | var classes;
|
572 | 612 | var classes_plugins;
|
| 613 | + var inputId; |
573 | 614 |
|
574 | 615 | inputMode = self.settings.mode;
|
575 | 616 | classes = $input.attr('class') || '';
|
|
581 | 622 | $dropdown = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent);
|
582 | 623 | $dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);
|
583 | 624 |
|
| 625 | + if(inputId = $input.attr('id')) { |
| 626 | + $control_input.attr('id', inputId + '-selectized'); |
| 627 | + $("label[for='"+inputId+"']").attr('for', inputId + '-selectized'); |
| 628 | + } |
| 629 | + |
584 | 630 | if(self.settings.copyClassesToDropdown) {
|
585 | 631 | $dropdown.addClass(classes);
|
586 | 632 | }
|
|
856 | 902 | */
|
857 | 903 | onPaste: function(e) {
|
858 | 904 | var self = this;
|
| 905 | + |
859 | 906 | if (self.isFull() || self.isInputHidden || self.isLocked) {
|
860 | 907 | e.preventDefault();
|
861 |
| - } else { |
862 |
| - // If a regex or string is included, this will split the pasted |
863 |
| - // input and create Items for each separate value |
864 |
| - if (self.settings.splitOn) { |
865 |
| - setTimeout(function() { |
866 |
| - var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); |
867 |
| - for (var i = 0, n = splitInput.length; i < n; i++) { |
868 |
| - self.createItem(splitInput[i]); |
869 |
| - } |
870 |
| - }, 0); |
871 |
| - } |
| 908 | + return; |
| 909 | + } |
| 910 | + |
| 911 | + // If a regex or string is included, this will split the pasted |
| 912 | + // input and create Items for each separate value |
| 913 | + if (self.settings.splitOn) { |
| 914 | + |
| 915 | + // Wait for pasted text to be recognized in value |
| 916 | + setTimeout(function() { |
| 917 | + var pastedText = self.$control_input.val(); |
| 918 | + if(!pastedText.match(self.settings.splitOn)){ return } |
| 919 | + |
| 920 | + var splitInput = $.trim(pastedText).split(self.settings.splitOn); |
| 921 | + for (var i = 0, n = splitInput.length; i < n; i++) { |
| 922 | + self.createItem(splitInput[i]); |
| 923 | + } |
| 924 | + }, 0); |
872 | 925 | }
|
873 | 926 | },
|
874 | 927 |
|
|
1555 | 1608 |
|
1556 | 1609 | // highlight matching terms inline
|
1557 | 1610 | if (self.settings.highlight && results.query.length && results.tokens.length) {
|
| 1611 | + $dropdown_content.removeHighlight(); |
1558 | 1612 | for (i = 0, n = results.tokens.length; i < n; i++) {
|
1559 | 1613 | highlight($dropdown_content, results.tokens[i].regex);
|
1560 | 1614 | }
|
|
2052 | 2106 | * and CSS classes.
|
2053 | 2107 | */
|
2054 | 2108 | refreshState: function() {
|
2055 |
| - var invalid, self = this; |
2056 |
| - if (self.isRequired) { |
2057 |
| - if (self.items.length) self.isInvalid = false; |
2058 |
| - self.$control_input.prop('required', invalid); |
2059 |
| - } |
2060 |
| - self.refreshClasses(); |
| 2109 | + this.refreshValidityState(); |
| 2110 | + this.refreshClasses(); |
| 2111 | + }, |
| 2112 | + |
| 2113 | + /** |
| 2114 | + * Update the `required` attribute of both input and control input. |
| 2115 | + * |
| 2116 | + * The `required` property needs to be activated on the control input |
| 2117 | + * for the error to be displayed at the right place. `required` also |
| 2118 | + * needs to be temporarily deactivated on the input since the input is |
| 2119 | + * hidden and can't show errors. |
| 2120 | + */ |
| 2121 | + refreshValidityState: function() { |
| 2122 | + if (!this.isRequired) return false; |
| 2123 | + |
| 2124 | + var invalid = !this.items.length; |
| 2125 | + |
| 2126 | + this.isInvalid = invalid; |
| 2127 | + this.$control_input.prop('required', invalid); |
| 2128 | + this.$input.prop('required', !invalid); |
2061 | 2129 | },
|
2062 | 2130 |
|
2063 | 2131 | /**
|
|
2168 | 2236 |
|
2169 | 2237 | if (self.settings.mode === 'single' && self.items.length) {
|
2170 | 2238 | self.hideInput();
|
| 2239 | + self.$control_input.blur(); // close keyboard on iOS |
2171 | 2240 | }
|
2172 | 2241 |
|
2173 | 2242 | self.isOpen = false;
|
|
0 commit comments