Skip to content

Commit c1d04de

Browse files
committed
Autocomplete demo (Combobox): Split code into smaller functions.
1 parent 5546e76 commit c1d04de

File tree

1 file changed

+81
-64
lines changed

1 file changed

+81
-64
lines changed

demos/autocomplete/combobox.html

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -37,79 +37,52 @@
3737
(function( $ ) {
3838
$.widget( "ui.combobox", {
3939
_create: function() {
40-
var input,
41-
that = this,
42-
wasOpen = false,
43-
select = this.element.hide(),
44-
selected = select.children( ":selected" ),
45-
value = selected.val() ? selected.text() : "",
46-
wrapper = this.wrapper = $( "<span>" )
47-
.addClass( "ui-combobox" )
48-
.insertAfter( select );
49-
50-
function removeIfInvalid( element ) {
51-
var value = $( element ).val().toLowerCase(),
52-
valid = false;
53-
select.children( "option" ).each(function() {
54-
if ( $( this ).text().toLowerCase() === value ) {
55-
this.selected = valid = true;
56-
return false;
57-
}
58-
});
40+
this.wrapper = $( "<span>" )
41+
.addClass( "ui-combobox" )
42+
.insertAfter( this.element );
5943

60-
if ( !valid ) {
61-
// remove invalid value, as it didn't match anything
62-
$( element )
63-
.val( "" )
64-
.attr( "title", value + " didn't match any item" )
65-
.tooltip( "open" );
66-
select.val( "" );
67-
setTimeout(function() {
68-
input.tooltip( "close" ).attr( "title", "" );
69-
}, 2500 );
70-
input.data( "ui-autocomplete" ).term = "";
71-
}
72-
}
44+
this._createAutocomplete();
45+
this._createShowAllButton();
46+
},
47+
48+
_createAutocomplete: function() {
49+
var selected = this.element.children( ":selected" ),
50+
value = selected.val() ? selected.text() : "";
7351

74-
input = $( "<input>" )
75-
.appendTo( wrapper )
52+
this.input = $( "<input>" )
53+
.appendTo( this.wrapper )
7654
.val( value )
7755
.attr( "title", "" )
78-
.addClass( "ui-state-default ui-combobox-input" )
56+
.addClass( "ui-state-default ui-combobox-input ui-widget ui-widget-content ui-corner-left" )
7957
.autocomplete({
8058
delay: 0,
8159
minLength: 0,
82-
source: function( request, response ) {
83-
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
84-
response( select.children( "option" ).map(function() {
85-
var text = $( this ).text();
86-
if ( this.value && ( !request.term || matcher.test(text) ) )
87-
return {
88-
label: text,
89-
value: text,
90-
option: this
91-
};
92-
}) );
93-
},
94-
select: function( event, ui ) {
95-
ui.item.option.selected = true;
96-
that._trigger( "select", event, {
97-
item: ui.item.option
98-
});
99-
},
100-
change: function( event, ui ) {
101-
if ( !ui.item ) {
102-
removeIfInvalid( this );
103-
}
104-
}
60+
source: $.proxy( this, "_source" )
10561
})
106-
.addClass( "ui-widget ui-widget-content ui-corner-left" );
62+
.tooltip({
63+
tooltipClass: "ui-state-highlight"
64+
});
65+
66+
this._on( this.input, {
67+
autocompleteselect: function( event, ui ) {
68+
ui.item.option.selected = true;
69+
this._trigger( "select", event, {
70+
item: ui.item.option
71+
});
72+
},
73+
74+
autocompletechange: "_removeIfInvalid"
75+
});
76+
},
77+
78+
_createShowAllButton: function() {
79+
var wasOpen = false;
10780

10881
$( "<a>" )
10982
.attr( "tabIndex", -1 )
11083
.attr( "title", "Show All Items" )
11184
.tooltip()
112-
.appendTo( wrapper )
85+
.appendTo( this.wrapper )
11386
.button({
11487
icons: {
11588
primary: "ui-icon-triangle-1-s"
@@ -124,18 +97,62 @@
12497
.click(function() {
12598
input.focus();
12699

127-
// close if already visible
100+
// Close if already visible
128101
if ( wasOpen ) {
129102
return;
130103
}
131104

132-
// pass empty string as value to search for, displaying all results
105+
// Pass empty string as value to search for, displaying all results
133106
input.autocomplete( "search", "" );
134107
});
108+
},
109+
110+
_source: function( request, response ) {
111+
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
112+
response( this.element.children( "option" ).map(function() {
113+
var text = $( this ).text();
114+
if ( this.value && ( !request.term || matcher.test(text) ) )
115+
return {
116+
label: text,
117+
value: text,
118+
option: this
119+
};
120+
}) );
121+
},
122+
123+
_removeIfInvalid: function( event, ui ) {
135124

136-
input.tooltip({
137-
tooltipClass: "ui-state-highlight"
125+
// Selected an item, nothing to do
126+
if ( ui.item ) {
127+
return;
128+
}
129+
130+
// Search for a match (case-insensitive)
131+
var value = this.input.val(),
132+
valueLowerCase = value.toLowerCase(),
133+
valid = false;
134+
this.element.children( "option" ).each(function() {
135+
if ( $( this ).text().toLowerCase() === valueLowerCase ) {
136+
this.selected = valid = true;
137+
return false;
138+
}
138139
});
140+
141+
// Found a match, nothing to do
142+
if ( valid ) {
143+
return;
144+
}
145+
146+
// Remove invalid value
147+
this.input
148+
.val( "" )
149+
.attr( "title", value + " didn't match any item" )
150+
.tooltip( "open" );
151+
this.element.val( "" );
152+
this._delay(function() {
153+
this.input.tooltip( "close" ).attr( "title", "" );
154+
}, 2500 );
155+
this.input.data( "ui-autocomplete" ).term = "";
139156
},
140157

141158
_destroy: function() {

0 commit comments

Comments
 (0)