web-dev-qa-db-fra.com

Fermer une liste déroulante SELECT par programme avec Javascript/jQuery

J'ai une liste déroulante qui est initialisée avec une seule valeur. Lorsque l'utilisateur clique dessus, l'élément unique est supprimé et un nouvel élément est ajouté avec le message "Chargement en cours". Un appel AJAX est alors émis vers le serveur et, lors du retour, les nouvelles valeurs sont ajoutées au contrôle.

Le problème est que le contrôle reste ouvert pendant la mise à jour et je voudrais le fermer.

Ceci est un exemple: http://jsfiddle.net/vtortola/CGuBk/2/

L'exemple AJAX de l'exemple ne reçoit pas de données, probablement parce que je ne fais pas correctement lorsque j'appelle l'api jsfiddle, mais il montre comment SELECT reste ouvert pendant la mise à jour.

Je veux savoir comment fermer la liste déroulante par programme sans mettre l'accent sur une autre entrée.

26
vtortola

Je ne suis sûr de personne, mais j'utilise la dernière version stable de Chrome et aucune des autres réponses impliquant .blur() ne fonctionne pour moi.

Cette question demande l'inverse: Ouvrir par programme un menu déroulant

La conclusion qui semblait être obtenue est que ce n'est pas possible en raison de la manière dont le navigateur gère les clics sur les éléments de champ.

Une meilleure solution consisterait à remplacer le menu déroulant par un HTML pur et à le masquer le cas échéant avec une simple commande .hide().

12
Death

Ajoutez simplement cette fin de ligne de votre clôture dans click.

$(this).blur();  

Alors ça va ressembler

$select.click(function(e){

    $select.html('<option value="-1">Loading</option>');

    $(this).blur();
    ......
    ...
});

D&EACUTE;MO

HAH! Si nous rencontrons un problème avec Chrome nouvelle version, alors:

Prenez un faux select comme suit:

<select class="fake" style="display: none">
    <option value="-1">Loading</option>
</select>

et faire quelque chose comme:

$select.click(function(e) {
    $(this).hide(0); // hide current select box

    //$select.html('<option value="-1">Loading</option>');

    $('select.fake').show(0); // show the fake slide

    $.ajax({
           // your code
        }).done(function(data) {

           $('select.fake').hide(0);
           $select.show(0);

        })
        ......
    }):

D&EACUTE;MO

12
thecodeparadox

Après...

$select.html('<option value="-1">Loading</option>');

Essayez d'ajouter ...

$select.blur();
6
freefaller

Je pense que tout ce que vous avez à faire est de cibler autre chose ou devrais-je dire perdre le focus sur la sélection

<select>
    <option value="0">Initial Value</option>
</select>

var $select = $('select');
$select.click(function(e){

    $select.html('<option value="-1">Loading</option>');

    $.ajax({
        url: '/echo/json/',
        method:'post',
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: { json: JSON.stringify([1, 2, 3]), delay:1 }
    }).done(function(data){

        $.each($.map(data, function (item, i) {
                    return "<option value='" + item +"' >" + item + "</option>";

                }), function (i, item) {
                    $element.append(item);
                });

    }).fail(function(){
        alert('error');
    });

   e.preventDefault();
   e.stopPropagation(); 
   $(this).blur();    
});
5
Huangism

Je sais que c'est une vieille question et que j'ai déjà une réponse, mais je pense que la solution suivante peut être un moyen juste d'atteindre l'objectif. 

Vous pouvez simuler la fermeture de la sélection en la rendant à nouveau. Dans jQuery, vous pouvez implémenter un simple plugin pour y parvenir:

$.fn.closeSelect = function() {
    if($(this).is("select")){
        var fakeSelect = $(this).clone();
        $(this).replaceWith(fakeSelect);
    }
};

et l'utiliser de cette façon:

$("#mySelect").closeSelect();
2
Jonathan

SOLUTION 1 J'ai trouvé une solution très simple.

select.style.display = "none";
setTimeout(function () {
    select.style.display = "block";
}, 10);

Cet élément cache dans le DOM, ce qui provoque la fermeture du menu déroulant, puis avec un délai de 10 ms (sans délai cela ne fonctionne pas) le renvoie dans le DOM.

SOLUTION 2: Un petit peu plus compliqué, mais sans tarder, supprimons totalement l'élément de DOM et le renvoyons immédiatement.

var parent = select.parentElement;
var anchor = document.createElement("div");
parent.insertBefore(anchor, select);
parent.removeChild(select);
parent.insertBefore(select, anchor);
parent.removeChild(anchor);

Ceci stocke le parrent d'élément, puis amène l'ancre avant de sélectionner. Anchor est là pour restaurer select dans la même position dans le DOM puis avant. Bien sûr, il peut être implémenté pour fonctionner en sélectionnant un élément.

HTMLSelectElement.prototype.closeDropdown = function () {
    var parent = this.parentElement;
    var anchor = document.createElement("div");
    parent.insertBefore(anchor, this);
    parent.removeChild(this);
    parent.insertBefore(this, anchor);
    parent.removeChild(anchor);
}

et ensuite il suffit d'appeler

select.closeDropdown();

Exemple

1
Misaz

Le moyen le plus simple que j'ai trouvé de fermer un élément sélectionné est de le désactiver temporairement:

$selectElement.attr('disabled', true);

setTimeout(() => {
   $selectElement.attr('disabled', false);
}, 4);
0
Bogdan Chernovol

Au cas où quelqu'un utiliserait Angular2, la solution qui fonctionnait pour moi était d'ajouter un événement (focus) qui appelle $($event.srcElement).attr("disabled","disabled");

J'ajoute ensuite un délai d'expiration pour réactiver l'élément lorsque je souhaite qu'il redevienne actif.

0
Vern Jensen
$('.select').on('change', function () {
    $(this).click();
});
0
panser

Ancien post je sais mais j'ai une solution très simple.

$(someSelectElement).on('change', function(e) {
    e.target.size = 0    
}

Cela réduira l'élément select si vous cliquez sur un élément de la liste. 

0
user3619165