web-dev-qa-db-fra.com

jQuery ui autocomplete lorsque l'utilisateur ne sélectionne pas d'option dans le menu déroulant

Lorsque vous utilisez le plug-in jquery autocomplete , que faites-vous lorsque l’utilisateur ne sélectionne pas d’élément dans la liste, mais saisit plutôt une valeur valide et quitte l’onglet?

par exemple, lorsque la liste de saisie semi-automatique contient:

Cat
Dog
Fish 

Et l'utilisateur saisit cat, mais ne sélectionne pas Cat dans la liste déroulante de la saisie semi-automatique et élimine les tabulations. Parce qu'ils n'ont sélectionné aucun élément de la liste, l'événement select de saisie semi-automatique ne se déclenche pas et nous perdons la possibilité de répondre:

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

Comment gérer ce cas?

26
JK.

Vous recherchez probablement extension autoSelect de Scott González . Le simple fait d'inclure cette extension sur la page permettra à l'événement select de se déclencher si l'utilisateur entre une valeur valide et ne nécessite aucune modification de votre côté:

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

Voici un exemple utilisant l'extension: http://jsfiddle.net/vFWUt/226/

15
Andrew Whitaker

Avec la version jQuery> = 1.8.11, utilisez l'option autoFocus définie sur true

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

Cela présente l’avantage supplémentaire de sélectionner automatiquement le premier élément de la liste afin que l’utilisateur puisse simplement appuyer sur Entrée ou sur la touche de tabulation pour le sélectionner sans avoir à saisir tout le nom. 

16
Marques

Ajouter un événement personnalisé onchange

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

Ou utilisez l'événement change intégré du widget:

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

la source

7
gdoron

Pour jQuery UI 1.9.2, j'ai dû modifier un peu l'extension autoSelect de Scott González dans la réponse d'Andrew Whitaker:

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

être

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

et puis cela fonctionne parfaitement.

6
trushkevich

Vous pouvez utiliser comme ça

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

Pour jQuery UI - v1.11.0 j'ai dû changer un peu l'extension autoSelect de Scott González as ci-dessous.

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

Et il a fallu appliquer l'option __complete_auto complète complète autoSelect: true dans ma définition.

J'ai pris un peu de code de ces réponses.

  1. trushkevich
  2. gdoron et
  3. Cagatay Kalan

MODIFIER

Voici ma définition autocomplete, au cas où quelqu'un serait intéressé.

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

Le code suivant est un petit Tweak sur l’extension de Scott permettant de travailler avec la version 1.10.3 de jquery ui.

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

Mise à jour du code de Scott Gonzalez pour fonctionner avec 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));
0

J'avais des problèmes avec cette fonction dans une page utilisant jquery 1.9.1 et jquery-ui 1.10.3. Sur la base du code de Scott Gonzalez et des suggestions présentées ici, ainsi que de quelques heures de bagarre, je propose ce qui suit. Remarque: je voulais une solution dans laquelle l'utilisateur ne peut entrer qu'une des valeurs suggérées par la saisie semi-automatique - mais je voulais autoriser le cas où l'utilisateur saisit simplement l'une des valeurs autorisées sans la sélectionner dans le menu déroulant: 

/*
 * jQuery UI Autocomplete Auto Select Extension
 *
 * v 1.10
 * Jomo Frodo ([email protected])
 * 
 * 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 = '';
                        }
                    });

        });
0
jomofrodo

utiliser autoFocus: true

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

Ce code ne se sélectionne qu'une fois. Tous les autres après cela ne font rien. Des idées?

Edit: J'ai commenté cette ligne et cela fonctionne maintenant. Je ne sais pas pourquoi.

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