Skip to content

Commit 5095871

Browse files
committed
Autocomplete: Added support for contenteditable elements. Fixes #6914 - Autocomplete: Support contenteditable.
1 parent ee34b0d commit 5095871

File tree

3 files changed

+59
-12
lines changed

3 files changed

+59
-12
lines changed

tests/unit/autocomplete/autocomplete.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ <h2 id="qunit-userAgent"></h2>
4040

4141
<div id="ac-wrap1" class="ac-wrap"></div>
4242
<div id="ac-wrap2" class="ac-wrap"><input id="autocomplete" class="foo" /></div>
43+
<div id="autocomplete-contenteditable" contenteditable="" tabindex=0></div>
4344
</div>
4445

4546
</body>

tests/unit/autocomplete/autocomplete_events.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,46 @@ test("all events", function() {
5151
}, 50);
5252
});
5353

54+
test("all events - contenteditable", function() {
55+
expect(12);
56+
var ac = $("#autocomplete-contenteditable").autocomplete({
57+
delay: 0,
58+
source: data,
59+
search: function(event) {
60+
same(event.type, "autocompletesearch");
61+
},
62+
open: function(event) {
63+
same(event.type, "autocompleteopen");
64+
},
65+
focus: function(event, ui) {
66+
same(event.type, "autocompletefocus");
67+
same(ui.item, {label:"java", value:"java"});
68+
},
69+
close: function(event) {
70+
same(event.type, "autocompleteclose");
71+
same( $(".ui-menu:visible").length, 0 );
72+
},
73+
select: function(event, ui) {
74+
same(event.type, "autocompleteselect");
75+
same(ui.item, {label:"java", value:"java"});
76+
},
77+
change: function(event, ui) {
78+
same(event.type, "autocompletechange");
79+
same(ui.item, {label:"java", value:"java"});
80+
same( $(".ui-menu:visible").length, 0 );
81+
start();
82+
}
83+
});
84+
stop();
85+
ac.focus().text("ja").keydown();
86+
setTimeout(function() {
87+
same( $(".ui-menu:visible").length, 1 );
88+
ac.simulate("keydown", { keyCode: $.ui.keyCode.DOWN });
89+
ac.simulate("keydown", { keyCode: $.ui.keyCode.ENTER });
90+
$.browser.msie ? ac.simulate("blur") : ac.blur();
91+
}, 50);
92+
});
93+
5494
test("change without selection", function() {
5595
expect(2);
5696
stop();

ui/jquery.ui.autocomplete.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ $.widget( "ui.autocomplete", {
3939
doc = this.element[ 0 ].ownerDocument,
4040
suppressKeyPress;
4141

42+
this.valueMethod = this.element[ this.element.is( "input" ) ? "val" : "text" ];
43+
4244
this.element
4345
.addClass( "ui-autocomplete-input" )
4446
.attr( "autocomplete", "off" )
@@ -89,15 +91,15 @@ $.widget( "ui.autocomplete", {
8991
self.menu.select( event );
9092
break;
9193
case keyCode.ESCAPE:
92-
self.element.val( self.term );
94+
self._value( self.term );
9395
self.close( event );
9496
break;
9597
default:
9698
// keypress is triggered before the input value is changed
9799
clearTimeout( self.searching );
98100
self.searching = setTimeout(function() {
99101
// only search if the value has changed
100-
if ( self.term != self.element.val() ) {
102+
if ( self.term != self._value() ) {
101103
self.selectedItem = null;
102104
self.search( null, event );
103105
}
@@ -117,7 +119,7 @@ $.widget( "ui.autocomplete", {
117119
}
118120

119121
self.selectedItem = null;
120-
self.previous = self.element.val();
122+
self.previous = self._value();
121123
})
122124
.bind( "blur.autocomplete", function( event ) {
123125
if ( self.options.disabled ) {
@@ -170,7 +172,7 @@ $.widget( "ui.autocomplete", {
170172
if ( false !== self._trigger( "focus", event, { item: item } ) ) {
171173
// use value to match what will end up in the input, if it was a key event
172174
if ( /^key/.test(event.originalEvent.type) ) {
173-
self.element.val( item.value );
175+
self._value( item.value );
174176
}
175177
}
176178
},
@@ -192,11 +194,11 @@ $.widget( "ui.autocomplete", {
192194
}
193195

194196
if ( false !== self._trigger( "select", event, { item: item } ) ) {
195-
self.element.val( item.value );
197+
self._value( item.value );
196198
}
197199
// reset the term after the select event
198200
// this allows custom select handling to work properly
199-
self.term = self.element.val();
201+
self.term = self._value();
200202

201203
self.close( event );
202204
self.selectedItem = item;
@@ -205,8 +207,8 @@ $.widget( "ui.autocomplete", {
205207
// don't set the value of the text field if it's already correct
206208
// this prevents moving the cursor unnecessarily
207209
if ( self.menu.element.is(":visible") &&
208-
( self.element.val() !== self.term ) ) {
209-
self.element.val( self.term );
210+
( self._value() !== self.term ) ) {
211+
self._value( self.term );
210212
}
211213
}
212214
})
@@ -279,10 +281,10 @@ $.widget( "ui.autocomplete", {
279281
},
280282

281283
search: function( value, event ) {
282-
value = value != null ? value : this.element.val();
284+
value = value != null ? value : this._value();
283285

284286
// always save the actual value, not the one passed as an argument
285-
this.term = this.element.val();
287+
this.term = this._value();
286288

287289
if ( value.length < this.options.minLength ) {
288290
return this.close( event );
@@ -327,7 +329,7 @@ $.widget( "ui.autocomplete", {
327329
},
328330

329331
_change: function( event ) {
330-
if ( this.previous !== this.element.val() ) {
332+
if ( this.previous !== this._value() ) {
331333
this._trigger( "change", event, { item: this.selectedItem } );
332334
}
333335
},
@@ -397,7 +399,7 @@ $.widget( "ui.autocomplete", {
397399
}
398400
if ( this.menu.first() && /^previous/.test(direction) ||
399401
this.menu.last() && /^next/.test(direction) ) {
400-
this.element.val( this.term );
402+
this._value( this.term );
401403
this.menu.deactivate();
402404
return;
403405
}
@@ -406,6 +408,10 @@ $.widget( "ui.autocomplete", {
406408

407409
widget: function() {
408410
return this.menu.element;
411+
},
412+
413+
_value: function( value ) {
414+
return this.valueMethod.apply( this.element, arguments );
409415
}
410416
});
411417

0 commit comments

Comments
 (0)