web-dev-qa-db-fra.com

complétion automatique de l'interface utilisateur jQuery: n'autorise que les valeurs sélectionnées dans la liste proposée

J'implémente jQuery UI Autocomplete et je me demande s'il existe un moyen d'autoriser uniquement une sélection à partir des résultats suggérés renvoyés plutôt que de permettre à une valeur d'être entrée dans la zone de texte.

J'utilise ceci pour un système de marquage très similaire à celui utilisé sur ce site. Je souhaite donc uniquement autoriser les utilisateurs à sélectionner des tags dans une liste préremplie renvoyée au plugin autocomplete.

40
stephen776

J'ai eu le même problème avec sélectionné ne pas être défini. Vous avez une solution de contournement et ajouté la fonction toLowerCase, juste pour être sûr.

$('#' + specificInput).autocomplete({ 
  create: function () {
    $(this).data('ui-autocomplete')._renderItem = function (ul, item) {
      $(ul).addClass('for_' + specificInput); //usefull for multiple autocomplete fields
      return $('<li data-id = "' + item.id + '">' + item.value + '</li>').appendTo(ul); 
    };
  }, 
  change:
    function( event, ui ){
      var selfInput = $(this); //stores the input field
      if ( !ui.item ) { 
        var writtenItem = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val().toLowerCase()) + "$", "i"), valid = false;

        $('ul.for_' + specificInput).children("li").each(function() {
          if($(this).text().toLowerCase().match(writtenItem)) {
            this.selected = valid = true;
            selfInput.val($(this).text()); // shows the item's name from the autocomplete
            selfInput.next('span').text('(Existing)');
            selfInput.data('id', $(this).data('id'));
            return false;
          }
        });

        if (!valid) { 
          selfInput.next('span').text('(New)');
          selfInput.data('id', -1); 
        }
    }
}
15
Victor

Vous pouvez aussi utiliser ceci:

change: function(event,ui){
  $(this).val((ui.item ? ui.item.id : ""));
}

Le seul inconvénient que j’ai vu est que même si l’utilisateur saisit la valeur complète d’un élément acceptable, lorsqu’il déplacera le focus du champ de texte, il supprimera la valeur et devra le refaire. Le seul moyen de saisir une valeur consiste à la sélectionner dans la liste.

Je ne sais pas si cela compte pour vous ou pas.

39
Jason Gray

http://jsfiddle.net/pxfunc/j3AN7/

var validOptions = ["Bold", "Normal", "Default", "100", "200"]
previousValue = "";

$('#ac').autocomplete({
    autoFocus: true,
    source: validOptions
}).keyup(function() {
    var isValid = false;
    for (i in validOptions) {
        if (validOptions[i].toLowerCase().match(this.value.toLowerCase())) {
            isValid = true;
        }
    }
    if (!isValid) {
        this.value = previousValue
    } else {
        previousValue = this.value;
    }
});
6
Sam Battat

je viens de modifier pour coder dans mon cas et ça marche 

selectFirst: true,
change: function (event, ui) {
        if (ui.item == null){ 
         //here is null if entered value is not match in suggestion list
            $(this).val((ui.item ? ui.item.id : ""));
        }
    }

tu peux essayer

6
Amol Shiledar

Voici comment je l'ai fait avec une liste de colonies: 

 $("#settlement").autocomplete({
  source:settlements,
  change: function( event, ui ) {
  val = $(this).val();
  exists = $.inArray(val,settlements);
  if (exists<0) {
    $(this).val("");
    return false;
  }
 }
});
5
Matanya

Ajax soumission et traitement

Cela sera utile à certains d'entre vous:

$('#INPUT_ID').autocomplete({
    source: function (request, response) {
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            url: autocompleteURL,
            data: "{'data':'" + $('INPUT_ID').val() + "'}",
            dataType: 'json',
            success: function (data) {
                response(data.d);
            },
            error: function (data) {
                console.log('No match.')
            }
        });
    },
    change: function (event, ui) {
        var opt = $(this).val();

        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            url: autocompleteURL,
            data: "{'empName':'" + name + "'}",
            dataType: 'json',
            success: function (data) {
                if (data.d.length == 0) {
                    $('#INPUT_ID').val('');
                    alert('Option must be selected from the list.');
                } else if (data.d[0] != opt) {
                    $('#INPUT_ID').val('');
                    alert('Option must be selected from the list.');
                }
            },
            error: function (data) {
                $(this).val('');
                console.log('Error retrieving options.');
            }
        });
    }
});
0
Daniel Forrest

Je suis sur drupal 7.38 etpour permettre uniquement les entrées de la case à cocher en saisie semi-automatiquevous devez uniquement supprimer l'entrée utilisateur au point, Où js n'en a plus besoin - ce qui le cas, dès que les résultats de la recherche arrivent dans la fenêtre de suggestion à cet endroit, vous pouvez simplement définir: 

 **this.input.value = ''**

voir ci-dessous l'extrait de autocomplete.js ... J'ai donc copié tout l'objet Drupal.jsAC.prototype.found dans mon module personnalisé et l'a ajouté au formulaire souhaité avec. 

 $form['#attached']['js'][] = array(
  'type' => 'file',
  'data' => 'sites/all/modules/<modulname>_autocomplete.js',
 );

Et voici l'extrait de misc/autocomplete.js Original de Drupal modifié par cette seule ligne ... 

Drupal.jsAC.prototype.found = function (matches) {
  // If no value in the textfield, do not show the popup.
  if (!this.input.value.length) {
    return false;
  }
  // === just added one single line below ===
  this.input.value = '';

  // Prepare matches.

= coupé. . . . . . 

0
pomix