From 50958718c22aab5a4f5061c313531259761648c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Thu, 24 Feb 2011 10:22:51 +0100 Subject: [PATCH] Autocomplete: Added support for contenteditable elements. Fixes #6914 - Autocomplete: Support contenteditable. --- tests/unit/autocomplete/autocomplete.html | 1 + .../unit/autocomplete/autocomplete_events.js | 40 +++++++++++++++++++ ui/jquery.ui.autocomplete.js | 30 ++++++++------ 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/tests/unit/autocomplete/autocomplete.html b/tests/unit/autocomplete/autocomplete.html index ef9d64baf..c4c3d8745 100644 --- a/tests/unit/autocomplete/autocomplete.html +++ b/tests/unit/autocomplete/autocomplete.html @@ -40,6 +40,7 @@
+
diff --git a/tests/unit/autocomplete/autocomplete_events.js b/tests/unit/autocomplete/autocomplete_events.js index 95a86425c..b0ee1acb4 100644 --- a/tests/unit/autocomplete/autocomplete_events.js +++ b/tests/unit/autocomplete/autocomplete_events.js @@ -51,6 +51,46 @@ test("all events", function() { }, 50); }); +test("all events - contenteditable", function() { + expect(12); + var ac = $("#autocomplete-contenteditable").autocomplete({ + delay: 0, + source: data, + search: function(event) { + same(event.type, "autocompletesearch"); + }, + open: function(event) { + same(event.type, "autocompleteopen"); + }, + focus: function(event, ui) { + same(event.type, "autocompletefocus"); + same(ui.item, {label:"java", value:"java"}); + }, + close: function(event) { + same(event.type, "autocompleteclose"); + same( $(".ui-menu:visible").length, 0 ); + }, + select: function(event, ui) { + same(event.type, "autocompleteselect"); + same(ui.item, {label:"java", value:"java"}); + }, + change: function(event, ui) { + same(event.type, "autocompletechange"); + same(ui.item, {label:"java", value:"java"}); + same( $(".ui-menu:visible").length, 0 ); + start(); + } + }); + stop(); + ac.focus().text("ja").keydown(); + setTimeout(function() { + same( $(".ui-menu:visible").length, 1 ); + ac.simulate("keydown", { keyCode: $.ui.keyCode.DOWN }); + ac.simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); + $.browser.msie ? ac.simulate("blur") : ac.blur(); + }, 50); +}); + test("change without selection", function() { expect(2); stop(); diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index c35d8180c..32959b3c5 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -39,6 +39,8 @@ $.widget( "ui.autocomplete", { doc = this.element[ 0 ].ownerDocument, suppressKeyPress; + this.valueMethod = this.element[ this.element.is( "input" ) ? "val" : "text" ]; + this.element .addClass( "ui-autocomplete-input" ) .attr( "autocomplete", "off" ) @@ -89,7 +91,7 @@ $.widget( "ui.autocomplete", { self.menu.select( event ); break; case keyCode.ESCAPE: - self.element.val( self.term ); + self._value( self.term ); self.close( event ); break; default: @@ -97,7 +99,7 @@ $.widget( "ui.autocomplete", { clearTimeout( self.searching ); self.searching = setTimeout(function() { // only search if the value has changed - if ( self.term != self.element.val() ) { + if ( self.term != self._value() ) { self.selectedItem = null; self.search( null, event ); } @@ -117,7 +119,7 @@ $.widget( "ui.autocomplete", { } self.selectedItem = null; - self.previous = self.element.val(); + self.previous = self._value(); }) .bind( "blur.autocomplete", function( event ) { if ( self.options.disabled ) { @@ -170,7 +172,7 @@ $.widget( "ui.autocomplete", { if ( false !== self._trigger( "focus", event, { item: item } ) ) { // use value to match what will end up in the input, if it was a key event if ( /^key/.test(event.originalEvent.type) ) { - self.element.val( item.value ); + self._value( item.value ); } } }, @@ -192,11 +194,11 @@ $.widget( "ui.autocomplete", { } if ( false !== self._trigger( "select", event, { item: item } ) ) { - self.element.val( item.value ); + self._value( item.value ); } // reset the term after the select event // this allows custom select handling to work properly - self.term = self.element.val(); + self.term = self._value(); self.close( event ); self.selectedItem = item; @@ -205,8 +207,8 @@ $.widget( "ui.autocomplete", { // don't set the value of the text field if it's already correct // this prevents moving the cursor unnecessarily if ( self.menu.element.is(":visible") && - ( self.element.val() !== self.term ) ) { - self.element.val( self.term ); + ( self._value() !== self.term ) ) { + self._value( self.term ); } } }) @@ -279,10 +281,10 @@ $.widget( "ui.autocomplete", { }, search: function( value, event ) { - value = value != null ? value : this.element.val(); + value = value != null ? value : this._value(); // always save the actual value, not the one passed as an argument - this.term = this.element.val(); + this.term = this._value(); if ( value.length < this.options.minLength ) { return this.close( event ); @@ -327,7 +329,7 @@ $.widget( "ui.autocomplete", { }, _change: function( event ) { - if ( this.previous !== this.element.val() ) { + if ( this.previous !== this._value() ) { this._trigger( "change", event, { item: this.selectedItem } ); } }, @@ -397,7 +399,7 @@ $.widget( "ui.autocomplete", { } if ( this.menu.first() && /^previous/.test(direction) || this.menu.last() && /^next/.test(direction) ) { - this.element.val( this.term ); + this._value( this.term ); this.menu.deactivate(); return; } @@ -406,6 +408,10 @@ $.widget( "ui.autocomplete", { widget: function() { return this.menu.element; + }, + + _value: function( value ) { + return this.valueMethod.apply( this.element, arguments ); } });