When using the jquery autocomplete plugin, what do you do when the user does not select an item in the list, but instead types a valid value and tabs away?
eg when the auto complete list contains:
Cat
Dog
Fish
And the user types cat
, but does not select Cat
from the autocomplete's dropdown list and instead tabs away. Because they did not select any item from the list, the autocomplete select event does not fire, and we lose the chance to respond to it:
$('#Animal').autocomplete({
source: url,
minlength: 1,
select: function (event, ui) {
$("#Animal").val(ui.item.value);
changeUsersAnimal(ui.item.id);
}
});
How do I handle this case?
You're probably looking for Scott González' autoSelect
extension. Just including this extension on the page will allow the select
event to fire if the user enters a valid value and should require no changes on your end:
/*
* jQuery UI Autocomplete Auto Select Extension
*
* Copyright 2010, Scott González (http://scottgonzalez.com)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*/
(function( $ ) {
$.ui.autocomplete.prototype.options.autoSelect = true;
$( ".ui-autocomplete-input" ).live( "blur", function( event ) {
var autocomplete = $( this ).data( "autocomplete" );
if ( !autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" );
autocomplete.widget().children( ".ui-menu-item" ).each(function() {
var item = $( this ).data( "item.autocomplete" );
if ( matcher.test( item.label || item.value || item ) ) {
autocomplete.selectedItem = item;
return false;
}
});
if ( autocomplete.selectedItem ) {
autocomplete._trigger( "select", event, { item: autocomplete.selectedItem } );
}
});
}( jQuery ));
Here's an example using the extension: http://jsfiddle.net/vFWUt/226/
With jQuery version >= 1.8.11 use the autoFocus option set to true
$( ".selector" ).autocomplete({ autoFocus: true });
That has the additional advantage of automatically selecting the first item in the list so the user can just press Enter or Tab to select it without having to type all the name.
Add a custom event of onchange
$('#Animal').change(function(){
var selectedValue = this.value;
// Do what you want here:
...
});
Or use the built-in change
event of the widget:
$('#Animal').autocomplete({
source: url,
minlength: 1,
select: function (event, ui) {
$("#Animal").val(ui.item.value);
changeUsersAnimal(ui.item.id);
}
change: function(event, ui) { // <=======
// ...
// ...
}
});
For jQuery UI 1.9.2 I had to change a bit Scott González' autoSelect extension in Andrew Whitaker's answer:
var item = $( this ).data( "item.autocomplete" );
to be
var item = $( this ).data( "uiAutocompleteItem" );
and then it works perfectly.
You can use like this
$("#inputbox").autocomplete({
source : reuesturl,
minLength : 1,
select : function(event, ui) {
$("#inputbox").attr('rel',ui.item.label);
},
open : function() {
$("#inputbox").attr('rel', 0);
},
close : function() {
if ($("#inputbox").attr('rel')=='0')
$("#inputbox").val('');
}
});
For jQuery UI - v1.11.0
I had to change a bit Scott González' autoSelect extension as below.
/*
* jQuery UI Autocomplete Auto Select Extension
*
* Copyright 2010, Scott González (http://scottgonzalez.com)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*/
$().ready(function () {
$.ui.autocomplete.prototype.options.autoSelect = true;
$(".ui-autocomplete-input").change(function (event) {
var autocomplete = $(this).data("uiAutocomplete");
if (!autocomplete.options.autoSelect || autocomplete.selectedItem) { return; }
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i");
autocomplete.widget().children(".ui-menu-item").each(function () {
var item = $(this).data("uiAutocompleteItem");
if (matcher.test(item.label || item.value || item)) {
autocomplete.selectedItem = item;
return false;
}
});
if (autocomplete.selectedItem) {
autocomplete._trigger("select", event, { item: autocomplete.selectedItem });
}
});
});
And had to apply extended autocomplete option autoSelect: true
in my autocomplete definition.
I took a bit of code from these answers.
EDIT
Here's my autocomplete definition, in case someone is interested.
$("your selector").autocomplete({
// Below filter looks for the values that start with the passed in string
source: function (request, response) {
var matches = $.map(yourSourceArray, function (acItem) {
if (acItem.toUpperCase().indexOf(request.term.toUpperCase()) === 0) {
return acItem;
}
});
response(matches);
},
// one can directly pass the source array instead like,
// source: yourSourceArray
autoSelect: true,
autoFocus: true,
minLength: 3,
change: function (event, ui) {
if (ui.item) {
// do whatever you want to when the item is found
}
else {
// do whatever you want to when the item is not found
}
}
})
The following code is a little tweak on Scott's extension to work with jquery ui 1.10.3 version, I have tested the below code with 1.10.3 version only.
(function($) {
$.ui.autocomplete.prototype.options.autoSelect = true;
$( ".ui-autocomplete-input" ).live( "blur", function( event ) {
var autocomplete = $( this ).data( "ui-autocomplete" );
if ( ! autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" );
autocomplete.widget().children( ".ui-menu-item" ).each(function() {
var item = $( this ).data( "ui-autocomplete-item" );
if ( matcher.test( item.label || item.value || item ) ) {
autocomplete.selectedItem = item;
return false;
}
});
if ( autocomplete.selectedItem ) {
autocomplete._trigger( "select", event, { item: autocomplete.selectedItem } );
}
});
}(jQuery));
This code only autoselects once. All others after that do nothing. Any ideas?
Edit: I commented out this line and it now works. Don't know why.
if ( !autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }
I was having trouble with this function in a page using jquery 1.9.1 and jquery-ui 1.10.3. Based on the Scott Gonzalez' code and the suggestions here and a few hours of thrashing, I came up with the following. Note, I wanted a solution where the user is only allowed to enter one of the values suggested by the autocomplete -- but I wanted to allow the case where the user just types in one of the allowed values without selecting it from the drop down:
/*
* jQuery UI Autocomplete Auto Select Extension
*
* v 1.10
* Jomo Frodo (jomofrodo@gmail.com)
*
* This version requires an autoSelect parameter to be set on the autocomplete widget
*
* e.g.,
* $("#autoCompleteID").autocomplete({
source:url,
minLength:1,
autoSelect: true
});
*
* Based on an extension by Scott González (http://scottgonzalez.com)
* http://blog.jqueryui.com/2010/08/extensible-autocomplete/
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*/
$(window).load(
function() {
//$.ui.autocomplete.prototype.options.autoSelect = true;
// Doesn't appear to work in ui 1.10.3
// Must set the 'autoSelect' param on the autocomplete widget to get this to work.
$(".ui-autocomplete-input").bind('autocompleteresponse',
function(event, ui) {
$(this).data('menuItems', ui.content);
});
$(".ui-autocomplete-input").on(
"blur",
null,
function(event) {
var autocomplete = $(this).data("uiAutocomplete");
if (!autocomplete.options.autoSelect
|| autocomplete.selectedItem) {
return;
}
var matcher = new RegExp("^"
+ $.ui.autocomplete.escapeRegex($(this).val())
+ "$", "i");
var menuItems = $(this).data('menuItems');
for (idx in menuItems) {
var item = menuItems[idx];
if (matcher.test(item.value)) {
autocomplete.selectedItem = item;
break;
// return false;
}
}
if (autocomplete.selectedItem) {
autocomplete._trigger("select", event, {
item : autocomplete.selectedItem
});
} else {
this.value = '';
}
});
});
use autoFocus: true
$('#Animal').autocomplete({
source: url,
**autoFocus: true,**
minlength: 1,
select: function (event, ui) {
$("#Animal").val(ui.item.value);
changeUsersAnimal(ui.item.id);
}
});
Updated Scott Gonzalez' code to work with Jquery-UI 1.12
(function($) {
$.ui.autocomplete.prototype.options.autoSelect = true;
$('body').on('blur', '.ui-autocomplete-input', function(event) {
var autocomplete = $(this).data('ui-autocomplete');
if (!autocomplete.options.autoSelect || autocomplete.selectedItem) { return; }
var matcher = new RegExp($.ui.autocomplete.escapeRegex($(this).val()), 'i');
autocomplete.widget().children('.ui-menu-item').each(function(index, item) {
var item = $( this ).data('uiAutocompleteItem');
if (matcher.test(item.label || item.value || item)) {
autocomplete.selectedItem = item;
return false;
}
});
if (autocomplete.selectedItem) {
autocomplete
._trigger('select', event, {item: autocomplete.selectedItem});
}
});
}(jQuery));
来源:https://stackoverflow.com/questions/10405932/jquery-ui-autocomplete-when-user-does-not-select-an-option-from-the-dropdown