1 2$( function() { 3 $.widget( "custom.combobox", { 4 _create: function() { 5 this.wrapper = $( "<span>" ) 6 .addClass( "custom-combobox" ) 7 .insertAfter( this.element ); 8 9 this.element.hide(); 10 this._createAutocomplete(); 11 this._createShowAllButton(); 12 }, 13 14 _createAutocomplete: function() { 15 var selected = this.element.children( ":selected" ), 16 value = selected.val() ? selected.text() : ""; 17 18 this.input = $( "<input placeholder='"+value+"'>" ) 19 .appendTo( this.wrapper ) 20 .attr( "title", "" ) 21 .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" ) 22 .autocomplete({ 23 delay: 0, 24 minLength: 0, 25 source: $.proxy( this, "_source" ) 26 }) 27 .tooltip({ 28 classes: { 29 "ui-tooltip": "ui-state-highlight" 30 } 31 }) 32 33 34 this._on( this.input, { 35 autocompleteselect: function( event, ui ) { 36 ui.item.option.selected = true; 37 38 this._trigger( "select", event, { 39 item: ui.item.option 40 }); 41 42 this.element.trigger('change'); 43 }, 44 45 autocompletechange: "_removeIfInvalid" 46 }); 47 }, 48 49 _createShowAllButton: function() { 50 var input = this.input, 51 wasOpen = false; 52 input.on( "click", function() { 53 input.trigger( "focus" ); 54 55 56 if ( wasOpen ) { 57 return; 58 } 59 60 // Pass empty string as value to search for, displaying all results 61 input.autocomplete( "search", "" ); 62 }); 63 64 }, 65 66 _source: function( request, response ) { 67 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ); 68 response( this.element.children( "option" ).map(function() { 69 var text = $( this ).text(); 70 if ( this.value && ( !request.term || matcher.test(text) ) ) 71 return { 72 label: text, 73 value: text, 74 option: this 75 }; 76 }) ); 77 }, 78 79 _removeIfInvalid: function( event, ui ) { 80 81 // Selected an item, nothing to do 82 if ( ui.item ) { 83 return; 84 } 85 86 // Search for a match (case-insensitive) 87 var value = this.input.val(), 88 valueLowerCase = value.toLowerCase(), 89 valid = false; 90 this.element.children( "option" ).each(function() { 91 if ( $( this ).text().toLowerCase() === valueLowerCase ) { 92 this.selected = valid = true; 93 return false; 94 95 } 96 }); 97 98 // Found a match, nothing to do 99 if ( valid ) { 100 return; 101 } 102 103 // Remove invalid value 104 this.input 105 .val( "" ) 106 .attr( "title", value + " ×× × ×צ×× ×¢×¨××" ) 107 .tooltip( "open" ); 108 this.element.val( "" ); 109 this._delay(function() { 110 this.input.tooltip( "close" ).attr( "title", "" ); 111 }, 2500 ); 112 this.input.autocomplete( "instance" ).term = ""; 113 }, 114 115 _destroy: function() { 116 this.wrapper.remove(); 117 this.element.show(); 118 } 119 }); 120 121 122 123 124 125 });
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.