1(function( $ ) { 2 $.widget( "custom.combobox", { 3 _create: function() { 4 this.wrapper = $( "<span>" ) 5 .addClass( "custom-combobox" ) 6 .insertAfter( this.element ); 7 8 this.element.hide(); 9 this._createAutocomplete(); 10 // this._createShowAllButton(); 11 }, 12 13 _createAutocomplete: function() { 14 var selected = this.element.children( ":selected" ), 15 value = selected.val() ? selected.text() : ""; 16 17 this.input = $( "<input>" ) 18 .appendTo( this.wrapper ) 19 .val( value ) 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: 1, 25 source: $.proxy( this, "_source" ) 26 }) 27 // .tooltip({ 28 // tooltipClass: "ui-state-highlight" 29 //}); 30 .click(function() { 31 $(this) 32 .val( "" ) 33 .attr( "title", "" ) 34 //.tooltip( "open" ); 35 this.element.val( "0" ); 36 this._delay(function() { 37 //this.input.tooltip( "close" ).attr( "title", "" ); 38 }, 2500 ); 39 $(this).data( "ui-autocomplete" ).term = ""; 40 41 }); 42 43 this._on( this.input, { 44 autocompleteselect: function( event, ui ) { 45 ui.item.option.selected = true; 46 this._trigger( "select", event, { 47 item: ui.item.option 48 }); 49 }, 50 51 autocompletechange: "_removeIfInvalid" 52 }); 53 }, 54 55 56 57 _createShowAllButton: function() { 58 // var input = this.input, 59 wasOpen = false; 60 61 $( "<a>" ) 62 .attr( "tabIndex", -1 ) 63 // .attr( "title", "Show All Items" ) 64 //.tooltip() 65 //.appendTo( this.wrapper ) 66 //.button({ 67 //icons: { 68 // primary: "ui-icon-triangle-1-s" 69 //}, 70 //text: false 71 // }) 72 .removeClass( "ui-corner-all" ) 73 .addClass( "custom-combobox-toggle ui-corner-right" ) 74 .mousedown(function() { 75 wasOpen = input.autocomplete( "widget" ).is( ":visible" ); 76 }) 77 .click(function() { 78 input.focus(); 79 80 // Close if already visible 81 if ( wasOpen ) { 82 return; 83 } 84 85 // Pass empty string as value to search for, displaying all results 86 // input.autocomplete( "search", "" ); 87 }); 88 }, 89 90 _source: function( request, response ) { 91 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ); 92 response( this.element.children( "option" ).map(function() { 93 var text = $( this ).text(); 94 if ( this.value && ( !request.term || matcher.test(text) ) ) 95 return { 96 label: text, 97 value: text, 98 option: this 99 }; 100 }) ); 101 }, 102 103 _removeIfInvalid: function( event, ui ) { 104 105 // Selected an item, nothing to do 106 if ( ui.item ) { 107 return; 108 } 109 110 // Search for a match (case-insensitive) 111 var value = this.input.val(), 112 valueLowerCase = value.toLowerCase(), 113 valid = false; 114 this.element.children( "option" ).each(function() { 115 if ( $( this ).text().toLowerCase() === valueLowerCase ) { 116 this.selected = valid = true; 117 return false; 118 } 119 }); 120 121 // Found a match, nothing to do 122 if ( valid ) { 123 return; 124 } 125 126 // Remove invalid value 127 this.input 128 .val( "" ) 129 //.attr( "title", value + " didn't match any item" ) 130 //.tooltip( "open" ); 131 this.element.val( "" ); 132 this._delay(function() { 133 this.input.tooltip( "close" ).attr( "title", "" ); 134 }, 2500 ); 135 this.input.autocomplete( "instance" ).term = ""; 136 }, 137 138 _destroy: function() { 139 this.wrapper.remove(); 140 this.element.show(); 141 } 142 }); 143 })( jQuery );
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.