javascript - html5 autocomplete




Afficher les étiquettes des datalistes mais soumettre la valeur réelle (3)

En utilisant PHP, j'ai trouvé un moyen assez simple de le faire. Les gars, juste utiliser quelque chose comme ça

<input list="customers" name="customer_id" required class="form-control" placeholder="Customer Name">
            <datalist id="customers">
                <?php 
    $querySnamex = "SELECT * FROM `customer` WHERE fname!='' AND lname!='' order by customer_id ASC";
    $resultSnamex = mysqli_query($con,$querySnamex) or die(mysql_error());

                while ($row_this = mysqli_fetch_array($resultSnamex)) {
                    echo '<option data-value="'.$row_this['customer_id'].'">'.$row_this['fname'].' '.$row_this['lname'].'</option>
                    <input type="hidden" name="customer_id_real" value="'.$row_this['customer_id'].'" id="answerInput-hidden">';
                }

                 ?>
            </datalist>

Le code ci-dessus permet au formulaire de porter l'identifiant de l'option également sélectionnée.

Actuellement, l'élément <datalist> HTML5 est pris en charge par la plupart des navigateurs principaux (sauf Safari) et semble être un moyen intéressant d'ajouter des suggestions à une entrée.

Cependant, il semble y avoir des divergences entre la mise en œuvre de l'attribut value et le texte interne sur <option> . Par exemple:

<input list="answers" name="answer">
<datalist id="answers">
  <option value="42">The answer</option>
</datalist>

Ceci est géré différemment par différents navigateurs:

Chrome et Opera:

FireFox et IE 11:

Après en avoir sélectionné un, l'entrée est remplie avec la valeur et non le texte intérieur. Je veux seulement que l'utilisateur voie le texte ("La réponse") dans le menu déroulant et dans l'entrée, mais transmette la valeur 42 lors de la soumission, comme le ferait un select .

Comment puis-je faire en sorte que tous les navigateurs aient dans la liste déroulante les libellés (texte interne) de <option> , mais qu'ils envoient l'attribut value lorsque le formulaire est soumis?


La solution que j'utilise est la suivante:

<input list="answers" id="answer">
<datalist id="answers">
  <option data-value="42" value="The answer">
</datalist>

Accédez ensuite à la valeur à envoyer au serveur en utilisant JavaScript comme ceci:

var shownVal = document.getElementById("answer").value;
var value2send = document.querySelector("#answers option[value='"+shownVal+"']").dataset.value;


J'espère que ça aide.


Notez que datalist n’est pas la même chose qu’une select . Il permet aux utilisateurs de saisir une valeur personnalisée qui ne figure pas dans la liste et il serait impossible d'extraire une autre valeur pour cette entrée sans la définir au préalable.

Les manières possibles de gérer les entrées utilisateur sont de soumettre la valeur entrée telle quelle, de soumettre une valeur vide ou d'empêcher la soumission. Cette réponse ne traite que les deux premières options.

Si vous souhaitez interdire totalement les saisies utilisateur, select serait peut-être un meilleur choix.

Pour afficher uniquement la valeur textuelle de l' option dans la liste déroulante, nous utilisons le texte interne pour cette option et omettons l'attribut value . La valeur réelle que nous voulons envoyer est stockée dans un attribut de data-value personnalisé:

Pour soumettre cette data-value nous devons utiliser un <input type="hidden"> . Dans ce cas, nous omettons le name="answer" sur l'entrée habituelle et le déplaçons vers la copie masquée.

<input list="suggestionList" id="answerInput">
<datalist id="suggestionList">
    <option data-value="42">The answer</option>
</datalist>
<input type="hidden" name="answer" id="answerInput-hidden">

De cette façon, lorsque le texte de l'entrée d'origine change, nous pouvons utiliser javascript pour vérifier si le texte est également présent dans le datalist et récupérer sa data-value . Cette valeur est insérée dans l'entrée masquée et soumise.

document.querySelector('input[list]').addEventListener('input', function(e) {
    var input = e.target,
        list = input.getAttribute('list'),
        options = document.querySelectorAll('#' + list + ' option'),
        hiddenInput = document.getElementById(input.getAttribute('id') + '-hidden'),
        inputValue = input.value;

    hiddenInput.value = inputValue;

    for(var i = 0; i < options.length; i++) {
        var option = options[i];

        if(option.innerText === inputValue) {
            hiddenInput.value = option.getAttribute('data-value');
            break;
        }
    }
});

Les id id answer et answer-hidden sur les entrées régulière et masquée sont nécessaires au script pour savoir quelle entrée appartient à quelle version masquée. De cette façon, il est possible d'avoir plusieurs input sur la même page avec un ou plusieurs datalist fournissant des suggestions.

Toute entrée d'utilisateur est soumise telle quelle. Pour soumettre une valeur vide lorsque l'entrée utilisateur n'est pas présente dans le datalist, remplacez hiddenInput.value = label par hiddenInput.value = ""

Exemples de travail jsFiddle: javascript et jQuery simples





html-datalist