Autocomplete: Track input changes and fire change-event on blur, along with selected item, if available. Fix for #5490

This commit is contained in:
jzaefferer 2010-04-08 12:05:52 +02:00
parent 10ea61be56
commit c01b3baef9
2 changed files with 30 additions and 6 deletions

View File

@ -12,7 +12,7 @@ module("autocomplete: events", {
var data = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl"]; var data = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl"];
test("all events", function() { test("all events", function() {
expect(11); expect(12);
var ac = $("#autocomplete").autocomplete({ var ac = $("#autocomplete").autocomplete({
delay: 0, delay: 0,
source: data, source: data,
@ -34,21 +34,38 @@ test("all events", function() {
same(event.type, "autocompleteselect"); same(event.type, "autocompleteselect");
same(ui.item, {label:"java", value:"java"}); same(ui.item, {label:"java", value:"java"});
}, },
change: function(event) { change: function(event, ui) {
same(event.type, "autocompletechange"); same(event.type, "autocompletechange");
same(ui.item, {label:"java", value:"java"});
same( $(".ui-menu:visible").length, 0 ); same( $(".ui-menu:visible").length, 0 );
start();
} }
}); });
stop(); stop();
ac.val("ja").keydown(); ac.focus().val("ja").keydown();
setTimeout(function() { setTimeout(function() {
same( $(".ui-menu:visible").length, 1 ); same( $(".ui-menu:visible").length, 1 );
ac.simulate("keydown", { keyCode: $.ui.keyCode.DOWN }); ac.simulate("keydown", { keyCode: $.ui.keyCode.DOWN });
ac.simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); ac.simulate("keydown", { keyCode: $.ui.keyCode.ENTER });
start(); ac.blur();
}, 50); }, 50);
}); });
test("change without selection", function() {
expect(2);
stop();
var ac = $("#autocomplete").autocomplete({
delay: 0,
source: data,
change: function(event, ui) {
same(event.type, "autocompletechange");
same(ui.item, null);
start();
}
});
ac.focus().val("ja").blur();
});
test("cancel search", function() { test("cancel search", function() {
expect(6); expect(6);
var first = true; var first = true;

View File

@ -83,6 +83,7 @@ $.widget( "ui.autocomplete", {
} }
}) })
.bind( "focus.autocomplete", function() { .bind( "focus.autocomplete", function() {
self.selectedItem = null;
self.previous = self.element.val(); self.previous = self.element.val();
}) })
.bind( "blur.autocomplete", function( event ) { .bind( "blur.autocomplete", function( event ) {
@ -91,6 +92,7 @@ $.widget( "ui.autocomplete", {
// TODO try to implement this without a timeout, see clearTimeout in search() // TODO try to implement this without a timeout, see clearTimeout in search()
self.closing = setTimeout(function() { self.closing = setTimeout(function() {
self.close( event ); self.close( event );
self._change( event );
}, 150 ); }, 150 );
}); });
this._initSource(); this._initSource();
@ -116,11 +118,13 @@ $.widget( "ui.autocomplete", {
self.element.val( item.value ); self.element.val( item.value );
} }
self.close( event ); self.close( event );
self.previous = self.element.val();
// only trigger when focus was lost (click on menu) // only trigger when focus was lost (click on menu)
var previous = self.previous;
if ( self.element[0] !== doc.activeElement ) { if ( self.element[0] !== doc.activeElement ) {
self.element.focus(); self.element.focus();
self.previous = previous;
} }
self.selectedItem = item;
}, },
blur: function( event, ui ) { blur: function( event, ui ) {
if ( self.menu.element.is(":visible") ) { if ( self.menu.element.is(":visible") ) {
@ -219,8 +223,11 @@ $.widget( "ui.autocomplete", {
this.menu.element.hide(); this.menu.element.hide();
this.menu.deactivate(); this.menu.deactivate();
} }
},
_change: function( event ) {
if ( this.previous !== this.element.val() ) { if ( this.previous !== this.element.val() ) {
this._trigger( "change", event ); this._trigger( "change", event, { item: this.selectedItem } );
} }
}, },