Autocomplete: Added support for contenteditable elements. Fixes #6914 - Autocomplete: Support contenteditable.

This commit is contained in:
Scott González 2011-02-24 10:22:51 +01:00
parent ee34b0dabb
commit 50958718c2
3 changed files with 59 additions and 12 deletions

View File

@ -40,6 +40,7 @@
<div id="ac-wrap1" class="ac-wrap"></div> <div id="ac-wrap1" class="ac-wrap"></div>
<div id="ac-wrap2" class="ac-wrap"><input id="autocomplete" class="foo" /></div> <div id="ac-wrap2" class="ac-wrap"><input id="autocomplete" class="foo" /></div>
<div id="autocomplete-contenteditable" contenteditable="" tabindex=0></div>
</div> </div>
</body> </body>

View File

@ -51,6 +51,46 @@ test("all events", function() {
}, 50); }, 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() { test("change without selection", function() {
expect(2); expect(2);
stop(); stop();

View File

@ -39,6 +39,8 @@ $.widget( "ui.autocomplete", {
doc = this.element[ 0 ].ownerDocument, doc = this.element[ 0 ].ownerDocument,
suppressKeyPress; suppressKeyPress;
this.valueMethod = this.element[ this.element.is( "input" ) ? "val" : "text" ];
this.element this.element
.addClass( "ui-autocomplete-input" ) .addClass( "ui-autocomplete-input" )
.attr( "autocomplete", "off" ) .attr( "autocomplete", "off" )
@ -89,7 +91,7 @@ $.widget( "ui.autocomplete", {
self.menu.select( event ); self.menu.select( event );
break; break;
case keyCode.ESCAPE: case keyCode.ESCAPE:
self.element.val( self.term ); self._value( self.term );
self.close( event ); self.close( event );
break; break;
default: default:
@ -97,7 +99,7 @@ $.widget( "ui.autocomplete", {
clearTimeout( self.searching ); clearTimeout( self.searching );
self.searching = setTimeout(function() { self.searching = setTimeout(function() {
// only search if the value has changed // only search if the value has changed
if ( self.term != self.element.val() ) { if ( self.term != self._value() ) {
self.selectedItem = null; self.selectedItem = null;
self.search( null, event ); self.search( null, event );
} }
@ -117,7 +119,7 @@ $.widget( "ui.autocomplete", {
} }
self.selectedItem = null; self.selectedItem = null;
self.previous = self.element.val(); self.previous = self._value();
}) })
.bind( "blur.autocomplete", function( event ) { .bind( "blur.autocomplete", function( event ) {
if ( self.options.disabled ) { if ( self.options.disabled ) {
@ -170,7 +172,7 @@ $.widget( "ui.autocomplete", {
if ( false !== self._trigger( "focus", event, { item: item } ) ) { 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 // use value to match what will end up in the input, if it was a key event
if ( /^key/.test(event.originalEvent.type) ) { 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 } ) ) { if ( false !== self._trigger( "select", event, { item: item } ) ) {
self.element.val( item.value ); self._value( item.value );
} }
// reset the term after the select event // reset the term after the select event
// this allows custom select handling to work properly // this allows custom select handling to work properly
self.term = self.element.val(); self.term = self._value();
self.close( event ); self.close( event );
self.selectedItem = item; self.selectedItem = item;
@ -205,8 +207,8 @@ $.widget( "ui.autocomplete", {
// don't set the value of the text field if it's already correct // don't set the value of the text field if it's already correct
// this prevents moving the cursor unnecessarily // this prevents moving the cursor unnecessarily
if ( self.menu.element.is(":visible") && if ( self.menu.element.is(":visible") &&
( self.element.val() !== self.term ) ) { ( self._value() !== self.term ) ) {
self.element.val( self.term ); self._value( self.term );
} }
} }
}) })
@ -279,10 +281,10 @@ $.widget( "ui.autocomplete", {
}, },
search: function( value, event ) { 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 // 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 ) { if ( value.length < this.options.minLength ) {
return this.close( event ); return this.close( event );
@ -327,7 +329,7 @@ $.widget( "ui.autocomplete", {
}, },
_change: function( event ) { _change: function( event ) {
if ( this.previous !== this.element.val() ) { if ( this.previous !== this._value() ) {
this._trigger( "change", event, { item: this.selectedItem } ); this._trigger( "change", event, { item: this.selectedItem } );
} }
}, },
@ -397,7 +399,7 @@ $.widget( "ui.autocomplete", {
} }
if ( this.menu.first() && /^previous/.test(direction) || if ( this.menu.first() && /^previous/.test(direction) ||
this.menu.last() && /^next/.test(direction) ) { this.menu.last() && /^next/.test(direction) ) {
this.element.val( this.term ); this._value( this.term );
this.menu.deactivate(); this.menu.deactivate();
return; return;
} }
@ -406,6 +408,10 @@ $.widget( "ui.autocomplete", {
widget: function() { widget: function() {
return this.menu.element; return this.menu.element;
},
_value: function( value ) {
return this.valueMethod.apply( this.element, arguments );
} }
}); });