Skip to main content

Search and Top Navigation

#6666 closed enhancement (fixed)

Opened November 18, 2010 10:23AM UTC

Closed January 26, 2012 03:06PM UTC

Autocomplete: keyboard-autorepeat on Firefox and paste event

Reported by: brotherli Owned by:
Priority: minor Milestone: 1.8.13
Component: ui.autocomplete Version: 1.8.6
Keywords: Cc:
Blocked by: Blocking:
Description

Keyboard-autorepeat (when holding down a key) doesn't fire keydown events in Firefox. This is desirable when holding down the cursor (up/down) keys to quickly move through the suggestions list and when pressing backspace until the input field is empty. In the latter case Firefox doesn't hide the suggestions list.

To make the behavior of the autocomplete widget consistent on all browsers (at least) the cursor and the backspace keys should be processed in the keypress event handler on Mozilla browsers.

Also pasting content to the input field using the mouse or the context menu doesn't trigger an update of the autocompleter. An event listener to 'paste' events could be added.

Attachments (0)
Change History (8)

Changed November 18, 2010 10:26AM UTC by brotherli comment:1

Since I'm not familiar with Git I'm attaching a diff against version 1.8.6 to fix the above mentioned issues.

--- jquery.ui.autocomplete.js.1.8.6	2010-11-02 12:49:44.000000000 +0100
+++ jquery.ui.autocomplete.js	2010-11-18 11:09:52.000000000 +0100
@@ -55,12 +55,14 @@
 					self._move( "nextPage", event );
 					break;
 				case keyCode.UP:
-					self._move( "previous", event );
+					if (!$.browser.mozilla)
+						self._move( "previous", event );
 					// prevent moving cursor to beginning of text field in some browsers
 					event.preventDefault();
 					break;
 				case keyCode.DOWN:
-					self._move( "next", event );
+					if (!$.browser.mozilla)
+						self._move( "next", event );
 					// prevent moving cursor to end of text field in some browsers
 					event.preventDefault();
 					break;
@@ -85,15 +87,7 @@
 					self.close( event );
 					break;
 				default:
-					// keypress is triggered before the input value is changed
-					clearTimeout( self.searching );
-					self.searching = setTimeout(function() {
-						// only search if the value has changed
-						if ( self.term != self.element.val() ) {
-							self.selectedItem = null;
-							self.search( null, event );
-						}
-					}, self.options.delay );
+					self.triggerSearch( event );
 					break;
 				}
 			})
@@ -102,6 +96,24 @@
 					suppressKeyPress = false;
 					event.preventDefault();
 				}
+				// handle certain keys here because keyboard-autorepeat doesn't fire keydown events on Mozilla browsers
+				else if ($.browser.mozilla) {
+					var keyCode = $.ui.keyCode;
+					switch( event.keyCode ) {
+					case keyCode.UP:
+						self._move( "previous", event );
+						break;
+					case keyCode.DOWN:
+						self._move( "next", event );
+						break;
+					case keyCode.BACKSPACE:
+						self.triggerSearch( event );
+						break;
+					}
+				}
+			})
+			.bind( "paste.autocomplete", function ( event ) {
+				self.triggerSearch( event );
 			})
 			.bind( "focus.autocomplete", function() {
 				if ( self.options.disabled ) {
@@ -257,6 +269,19 @@
 		}
 	},
 
+	triggerSearch: function( event ) {
+		// keypress is triggered before th einput value is changed
+		var self = this;
+		clearTimeout( this.searching );
+		this.searching = setTimeout(function() {
+			// only search if the value has changed
+			if ( self.term != self.element.val() ) {
+				self.selectedItem = null;
+				self.search( null, event );
+			}
+		}, this.options.delay );
+	},
+
 	search: function( value, event ) {
 		value = value != null ? value : this.element.val();

Changed November 18, 2010 12:56PM UTC by scottgonzalez comment:2

milestone: TBD1.9
status: newopen

Sorry, but we can't accept any patches that contain browser checks.

Changed November 18, 2010 12:59PM UTC by brotherli comment:3

So what's the preferred solution to get around behavioral differences between browsers? Ignore them?

Changed November 18, 2010 01:04PM UTC by scottgonzalez comment:4

_comment0: Either find something that works in all browsers or find a way to detect that you're going to have a problem. If you need more help, please use the [http://forum.jquery.com forums].1290085474156720

Either find something that works in all browsers or find a way to detect that you're going to have a problem. You can check out jQuery.support for a slew of detection code. If you need more help, please use the forums.

Changed November 18, 2010 01:18PM UTC by brotherli comment:5

OK, here's a revised version of my patch without browser detection. Feel free to find a better solution, I just thought this might help...

--- jquery.ui.autocomplete.js.1.8.6	2010-11-02 12:49:44.000000000 +0100
+++ jquery.ui.autocomplete.js	2010-11-18 14:13:38.000000000 +0100
@@ -50,17 +50,21 @@
 				switch( event.keyCode ) {
 				case keyCode.PAGE_UP:
 					self._move( "previousPage", event );
+					suppressKeyPress = true;
 					break;
 				case keyCode.PAGE_DOWN:
 					self._move( "nextPage", event );
+					suppressKeyPress = true;
 					break;
 				case keyCode.UP:
 					self._move( "previous", event );
+					suppressKeyPress = true;
 					// prevent moving cursor to beginning of text field in some browsers
 					event.preventDefault();
 					break;
 				case keyCode.DOWN:
 					self._move( "next", event );
+					suppressKeyPress = true;
 					// prevent moving cursor to end of text field in some browsers
 					event.preventDefault();
 					break;
@@ -85,15 +89,7 @@
 					self.close( event );
 					break;
 				default:
-					// keypress is triggered before the input value is changed
-					clearTimeout( self.searching );
-					self.searching = setTimeout(function() {
-						// only search if the value has changed
-						if ( self.term != self.element.val() ) {
-							self.selectedItem = null;
-							self.search( null, event );
-						}
-					}, self.options.delay );
+					self.triggerSearch( event );
 					break;
 				}
 			})
@@ -101,8 +97,32 @@
 				if ( suppressKeyPress ) {
 					suppressKeyPress = false;
 					event.preventDefault();
+					return;
+				}
+
+				// handle certain keys here because keyboard-autorepeat doesn't fire keydown events on all browsers
+				var keyCode = $.ui.keyCode;
+				switch( event.keyCode ) {
+				case keyCode.PAGE_UP:
+					self._move( "previousPage", event );
+					break;
+				case keyCode.PAGE_DOWN:
+					self._move( "nextPage", event );
+					break;
+				case keyCode.UP:
+					self._move( "previous", event );
+					break;
+				case keyCode.DOWN:
+					self._move( "next", event );
+					break;
+				case keyCode.BACKSPACE:
+					self.triggerSearch( event );
+					break;
 				}
 			})
+			.bind( "paste.autocomplete", function ( event ) {
+				self.triggerSearch( event );
+			})
 			.bind( "focus.autocomplete", function() {
 				if ( self.options.disabled ) {
 					return;
@@ -257,6 +277,19 @@
 		}
 	},
 
+	triggerSearch: function( event ) {
+		// keypress is triggered before the input value is changed
+		var self = this;
+		clearTimeout( this.searching );
+		this.searching = setTimeout(function() {
+			// only search if the value has changed
+			if ( self.term != self.element.val() ) {
+				self.selectedItem = null;
+				self.search( null, event );
+			}
+		}, this.options.delay );
+	},
+
 	search: function( value, event ) {
 		value = value != null ? value : this.element.val();

Changed May 10, 2011 03:46PM UTC by jzaefferer comment:6

Related to #7269 - that one fixes the up/down/page_up/page_down repeating, but doesn't handle repeating backspace or paste event.

Changed May 26, 2011 02:06AM UTC by trey comment:7

Changed January 26, 2012 03:06PM UTC by scottgonzalez comment:8

milestone: 1.91.8.13
resolution: → fixed
status: openclosed

Closing fixed for the key repeating. Paste will be handled separately (they're unrelated). See #8062.