Skip to content

Commit f5b52a8

Browse files
committed
Autocomplete: Removed the timeout for the change event. Fixes #7550 - Autocomplete change event not triggered in time.
Thanks spekary for finding a workaround for IE.
1 parent 3d9f6b5 commit f5b52a8

File tree

3 files changed

+21
-52
lines changed

3 files changed

+21
-52
lines changed

tests/unit/autocomplete/autocomplete_core.js

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,6 @@
22

33
module( "autocomplete: core" );
44

5-
asyncTest( "close-on-blur is properly delayed", function() {
6-
expect( 3 );
7-
var element = $( "#autocomplete" )
8-
.autocomplete({
9-
source: [ "java", "javascript" ]
10-
})
11-
.val( "ja" )
12-
.autocomplete( "search" ),
13-
menu = element.autocomplete( "widget" );
14-
15-
ok( menu.is( ":visible" ) );
16-
element.blur();
17-
ok( menu.is( ":visible" ) );
18-
setTimeout(function() {
19-
ok( menu.is( ":hidden") );
20-
start();
21-
}, 200 );
22-
});
23-
24-
asyncTest( "close-on-blur is cancelled when starting a search", function() {
25-
expect( 3 );
26-
var element = $( "#autocomplete" )
27-
.autocomplete({
28-
source: [ "java", "javascript" ]
29-
})
30-
.val( "ja" )
31-
.autocomplete( "search" ),
32-
menu = element.autocomplete( "widget" );
33-
34-
ok( menu.is( ":visible" ) );
35-
element.blur();
36-
ok( menu.is( ":visible" ) );
37-
element.autocomplete( "search" );
38-
setTimeout(function() {
39-
ok( menu.is( ":visible" ) );
40-
start();
41-
}, 200 );
42-
});
43-
445
test( "prevent form submit on enter when menu is active", function() {
456
expect( 2 );
467
var event,

tests/unit/autocomplete/autocomplete_events.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ $.each([
6868
ok( menu.is( ":visible" ), "menu is visible after delay" );
6969
element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
7070
element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
71-
element.simulate( "blur" );
71+
// blur must be async for IE to handle it properly
72+
setTimeout(function() {
73+
element.simulate( "blur" );
74+
}, 1 );
7275
}, 50 );
7376
});
7477
});

ui/jquery.ui.autocomplete.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,14 @@ $.widget( "ui.autocomplete", {
176176
return;
177177
}
178178

179+
if ( self.cancelBlur ) {
180+
delete self.cancelBlur;
181+
return;
182+
}
183+
179184
clearTimeout( self.searching );
180-
self.cancelSearch = true;
181-
// clicks on the menu (or a button to trigger a search) will cause a blur event
182-
self.closing = setTimeout(function() {
183-
self.close( event );
184-
self._change( event );
185-
}, 150 );
185+
self.close( event );
186+
self._change( event );
186187
});
187188
this._initSource();
188189
this.response = function() {
@@ -193,6 +194,16 @@ $.widget( "ui.autocomplete", {
193194
.appendTo( this.document.find( this.options.appendTo || "body" )[0] )
194195
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
195196
.mousedown(function( event ) {
197+
// prevent moving focus out of the text field
198+
event.preventDefault();
199+
200+
// IE doesn't prevent moving focus even with event.preventDefault()
201+
// so we set a flag to know when we should ignore the blur event
202+
self.cancelBlur = true;
203+
setTimeout(function() {
204+
delete self.cancelBlur;
205+
}, 1 );
206+
196207
// clicking on the scrollbar causes focus to shift to the body
197208
// but we can't detect a mouseup or a click immediately afterward
198209
// so we have to track the next mousedown and close the menu if
@@ -209,11 +220,6 @@ $.widget( "ui.autocomplete", {
209220
});
210221
}, 1 );
211222
}
212-
213-
// use another timeout to make sure the blur-event-handler on the input was already triggered
214-
setTimeout(function() {
215-
clearTimeout( self.closing );
216-
}, 13);
217223
})
218224
.menu({
219225
// custom key handling for now
@@ -358,7 +364,6 @@ $.widget( "ui.autocomplete", {
358364
return this.close( event );
359365
}
360366

361-
clearTimeout( this.closing );
362367
if ( this._trigger( "search", event ) === false ) {
363368
return;
364369
}

0 commit comments

Comments
 (0)