2012-06-01 24 views
25

Tengo un menú desplegable que se inicializa con un solo valor. Cuando el usuario hace clic en él, se elimina el elemento único y se agrega un nuevo elemento que dice "Cargando", luego se emite una llamada AJAX al servidor y cuando vuelve, los nuevos valores se agregan al control.Cerrar una lista desplegable SELECT programáticamente con Javascript/jQuery

El problema es que el control permanece abierto durante la actualización, y me gustaría cerrarlo.

Este es un ejemplo: http://jsfiddle.net/vtortola/CGuBk/2/

del ejemplo AJAX no recibe los datos probablemente porque algo malo que estoy haciendo cuando se llama a la API jsFiddle, pero muestra cómo el SELECT permanece abierta durante la actualización.

Quiero saber cómo cerrar la lista desplegable programáticamente sin foco en otra entrada.

Cheers.

Respuesta

12

No estoy seguro acerca de nadie más, pero estoy usando la última versión estable de Chrome, y ninguna de las otras respuestas relacionadas con .blur() me funciona.

Esta pregunta se refiere a la inversa: Programmatically open a drop-down menu

La conclusión que parecía ser obtenido es que no es posible debido a la forma en que el navegador se encarga de clics elemento de campo.

Una mejor solución sería reemplazar el menú desplegable con uno HTML puro y ocultarlo cuando sea necesario con un simple comando .hide().

+0

al cambiar un cuadro de texto, abro un cuadro de "solicitud". Si el cambio ocurre al hacer clic en la selección, evito ahora la inquietante lista desplegable al ocultar los seleccionados antes y volver a mostrar después del aviso. visibleselects = $ ('select: visible'). hide(); ... visibleselects.show(); –

12

Simplemente agregue esta línea al final de su cierre dentro de click.

$(this).blur(); 

Por lo tanto, se verá como

$select.click(function(e){ 

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

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

DEMO

HAH! Si tenemos un problema con Chrome nueva versión a continuación:

Tome una falsificación select como siguiente:

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

y hacer algo como:

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

     }) 
     ...... 
    }): 

DEMO

+1

** + 1 ** primero en responder, y con una demo! – gdoron

+0

@gdoron muchas gracias – thecodeparadox

+1

Si la intención es cerrar la lista desplegable, esto no funciona en Chrome 19 (la última), por lo que no se debe confiar. – Death

5

Creo que todo lo que tiene que hacer es objetivo algo más o debería decir enfoque perder en la selección (desenfoque)

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

Después ...

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

Trate de añadir ...

$select.blur(); 
2

Sé que esta es una vieja pregunta y ya tengo una respuesta, pero creo que la siguiente solución puede ser una forma justa de lograr el objetivo.

Puede simular el cierre de la selección volviéndola a representar. En jQuery se puede implementar un sencillo plugin para lograr que:

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

y usarlo de esta manera:

$("#mySelect").closeSelect(); 
+0

Es una buena idea. Me pregunto cómo funciona esto con el enlace. – vtortola

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

Mensaje viejo que sé, pero tengo una solución muy simple.

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

Eso colapsará el elemento seleccionado si hace clic en cualquier elemento de la lista.

0

En caso de que alguien más por ahí está utilizando Angular2, la solución que funcionó para mí fue la de añadir un evento (foco) que llama $($event.srcElement).attr("disabled","disabled");

Luego agregar un tiempo de espera para volver a habilitar el elemento cuando quiero volverse activo de nuevo.

1

SOLUCIÓN 1 Encontré una solución muy fácil.

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

Este elemento se esconden en DOM, esta causa que desplegable se cerrará y luego con 10 ms de retardo (sin demora que no funciona) volver en DOM.

SOLUCIÓN 2: Un poco más complicado pero sin demora es totalmente eliminar elemento de DOM y luego devolverlo de inmediato.

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

Esto almacena parrent de elemento, luego trae el ancla antes de seleccionar. El anclaje está allí para restaurar seleccionar en la misma posición en DOM que antes. Por supuesto, se puede implementar para seleccionar el elemento de selección.

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

y luego simplemente llamar

select.closeDropdown(); 

Example

Cuestiones relacionadas