当用户没有从下拉列表中选择一个选项时,jQuery ui自动完成

时间:2012-05-01 23:51:37

标签: jquery jquery-ui jquery-ui-autocomplete

使用jquery autocomplete plugin时,当用户未选择列表中的项目,而是键入有效值和标签时,您会怎么做?

例如,当自动完成列表包含:

Cat
Dog
Fish 

用户输入cat,但不会从自动填充的下拉列表中选择Cat,而是选择标签。因为他们没有从列表中选择任何项目,所以自动完成选择事件不会触发,我们也没有机会回复它:

$('#Animal').autocomplete({
    source: url,
    minlength: 1,
    select: function (event, ui) {
        $("#Animal").val(ui.item.value);
        changeUsersAnimal(ui.item.id);
    }
});

我该如何处理这个案子?

13 个答案:

答案 0 :(得分:16)

使用jQuery版本> = 1.8.11使用autoFocus选项设置为true

$( ".selector" ).autocomplete({ autoFocus: true });

这具有自动选择列表中第一项的附加优势,因此用户只需按Enter或Tab即可选择它而无需键入所有名称。

答案 1 :(得分:15)

你可能正在寻找Scott González' autoSelect extension。只要在页面上包含此扩展程序,就可以在用户输入有效值时激活select事件,并且不需要更改结果:

/*
 * 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 ));

以下是使用扩展程序http://jsfiddle.net/vFWUt/226/

的示例

答案 2 :(得分:7)

添加onchange的自定义事件

$('#Animal').change(function(){
    var selectedValue = this.value;
    // Do what you want here:
    ...
});

或使用小部件的内置change事件:

$('#Animal').autocomplete({
    source: url,
    minlength: 1,
    select: function (event, ui) {
        $("#Animal").val(ui.item.value);
        changeUsersAnimal(ui.item.id);
    }
   change: function(event, ui) { // <=======
       // ... 
       // ...
   }
});

source

答案 3 :(得分:6)

对于jQuery UI 1.9.2,我不得不在Andrew Whitaker的回答中更改ScottGonzález的autoSelect扩展名:

var item = $( this ).data( "item.autocomplete" );

var item = $( this ).data( "uiAutocompleteItem" );

然后它完美无缺。

答案 4 :(得分:3)

你可以这样使用

$("#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('');
    }
});

答案 5 :(得分:2)

对于jQuery UI - v1.11.0,我必须更改Scott González' autoSelect extension,如下所示。

/*
 * 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 });
        }
    });
});

并且必须在我的自动填充定义中应用扩展自动填充选项autoSelect: true

我从这些答案中提取了一些代码。

  1. trushkevich
  2. gdoron
  3. Cagatay Kalan
  4. 修改

    这是我的自动完成定义,以防有人感兴趣。

    $("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
            }
        }
    })
    

答案 6 :(得分:1)

下面的代码是对Scott使用jquery ui 1.10.3版本扩展的一点调整,我已经用1.10.3版本测试了下面的代码。

(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));

答案 7 :(得分:1)

另一个简单的技巧是使用 .autocomplete({ focus: and change: })。 在 focus 上将数据放入元素数据属性中,在 change 上取:

return $(element).autocomplete({
            source: get_db_cities,
            select: function (event, ui) {
                $(this).attr('tz',ui.item.tz);
            },
            autoFocus: true,
            focus: function (event, ui) {
                $(this).attr('tz',ui.item.tz);
                $(this).attr('label',ui.item.label); // put data in attribute
            },
            change: function () {
                $(this).val($(this).attr('label')); // take from attribute and insert as value
            }
});

答案 8 :(得分:0)

此代码仅自动选择一次。之后的所有其他人什么都不做。有什么想法吗?

编辑:我注释掉了这一行,它现在有效。不知道为什么。

if ( !autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }

答案 9 :(得分:0)

我在使用jquery 1.9.1和jquery-ui 1.10.3的页面中遇到此函数的问题。根据Scott Gonzalez的代码和这里的建议以及几个小时的颠簸,我想出了以下内容。注意,我想要一个解决方案,其中只允许用户输入自动完成建议的值之一 - 但我想允许用户只键入其中一个允许值而不从下拉列表中选择它的情况:

/*
 * 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 = '';
                        }
                    });

        });

答案 10 :(得分:0)

使用autoFocus: true

$('#Animal').autocomplete({
    source: url,
    **autoFocus: true,**
    minlength: 1,
    select: function (event, ui) {
        $("#Animal").val(ui.item.value);
        changeUsersAnimal(ui.item.id);
    }
});

答案 11 :(得分:0)

更新了Scott Gonzalez的代码以与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));

答案 12 :(得分:0)

我已经尝试了所有这些响应,并且如果引入的值不在列表中,那么对我来说,最终的解决方案是将select设为空:

            $( "#input" ).autocomplete({
                source: source,
                minLength: 0,
                change: function(event, ui) {
                    if(!ui.item) {
                        $(this).val("")
                    }
                }
            }).focus(function(){            
                $(this).data("uiAutocomplete").search($(this).val());
            });