Cómo completar un menú desplegable en cascada con JQuery

Resuelto user2609756 asked hace 11 años • 5 respuestas

tengo el siguiente problema:

Comencé a crear un formulario con HTML y JS y hay dos menús desplegables (País y Ciudad). ahora quiero dinamizar estos dos con JQuery para que solo sean visibles las ciudades de los países seleccionados.

Comencé con algunos JS básicos que funcionaron bien pero causan algunos problemas en IE. Ahora estoy intentando convertir mi JS a JQuery para una mejor compatibilidad.

Mi JS original se ve así:

function populate(s1, s2) {
    var s1 = document.getElementById(s1);
    var s2 = document.getElementById(s2);
    s2.innerHTML = "";
    if (s1.value == "Germany") {
        var optionArray = ["|", "magdeburg|Magdeburg", "duesseldorf|Duesseldorf", "leinfelden-echterdingen|Leinfelden-Echterdingen", "eschborn|Eschborn"];
    } else if (s1.value == "Hungary") {
        var optionArray = ["|", "pecs|Pecs", "budapest|Budapest", "debrecen|Debrecen"];
    } else if (s1.value == "Russia") {
        var optionArray = ["|", "st. petersburg|St. Petersburg"];
    } else if (s1.value == "South Africa") {
        var optionArray = ["|", "midrand|Midrand"];
    } else if (s1.value == "USA") {
        var optionArray = ["|", "downers grove|Downers Grove"];
    } else if (s1.value == "Mexico") {
        var optionArray = ["|", "puebla|Puebla"];
    } else if (s1.value == "China") {
        var optionArray = ["|", "beijing|Beijing"];
    } else if (s1.value == "Spain") {
        var optionArray = ["|", "barcelona|Barcelona"];
    }

    for (var option in optionArray) {
        var pair = optionArray[option].split("|");
        var newOption = document.createElement("option");
        newOption.value = pair[0];
        newOption.innerHTML = pair[1];
        s2.options.add(newOption);
    }
};

y aquí mi Jquery:

http://jsfiddle.net/HvXSz/

Sé que es muy simple pero no puedo ver la madera por los árboles.

user2609756 avatar Aug 21 '13 15:08 user2609756
Aceptado

Debería ser tan simple como

jQuery(function($) {
    var locations = {
        'Germany': ['Duesseldorf', 'Leinfelden-Echterdingen', 'Eschborn'],
        'Spain': ['Barcelona'],
        'Hungary': ['Pecs'],
        'USA': ['Downers Grove'],
        'Mexico': ['Puebla'],
        'South Africa': ['Midrand'],
        'China': ['Beijing'],
        'Russia': ['St. Petersburg'],
    }

    var $locations = $('#location');
    $('#country').change(function () {
        var country = $(this).val(), lcns = locations[country] || [];

        var html = $.map(lcns, function(lcn){
            return '<option value="' + lcn + '">' + lcn + '</option>'
        }).join('');
        $locations.html(html)
    });
});

Demostración: violín

Arun P Johny avatar Aug 21 '2013 08:08 Arun P Johny

Voy a proporcionar una segunda solución, ya que esta publicación todavía está en la búsqueda de Google de 'jquery cascade select'. Esta es la primera selección:

<select class="select" id="province" onchange="filterCity();">
  <option value="1">RM</option>
  <option value="2">FI</option>
</select>

y este es el segundo, deshabilitado hasta que se seleccione el primero:

<select class="select" id="city" disabled>
  <option data-province="RM" value="1">ROMA</option>
  <option data-province="RM" value="2">ANGUILLARA SABAZIA</option>
  <option data-province="FI" value="3">FIRENZE</option>
  <option data-province="FI" value="4">PONTASSIEVE</option>
</select>

éste no es visible y actúa como contenedor para todos los elementos filtrados por la selección:

<span id="option-container" style="visibility: hidden; position:absolute;"></span>

Finalmente, el script que filtra:

<script>

    function filterCity(){
      var province = $("#province").find('option:selected').text(); // stores province
      $("#option-container").children().appendTo("#city"); // moves <option> contained in #option-container back to their <select>
      var toMove = $("#city").children("[data-province!='"+province+"']"); // selects city elements to move out
      toMove.appendTo("#option-container"); // moves city elements in #option-container
      $("#city").removeAttr("disabled"); // enables select
};
</script>
marco bonfigli avatar Mar 06 '2015 15:03 marco bonfigli

He creado un menú desplegable en cascada para país, estado, ciudad y código postal.

Puede que le resulte útil a alguien. Aquí solo se publica una parte del código; puede ver un ejemplo de funcionamiento completo en jsfiddle.

//Get html elements
var countySel = document.getElementById("countySel");
var stateSel = document.getElementById("stateSel"); 
var citySel = document.getElementById("citySel");
var zipSel = document.getElementById("zipSel");

//Load countries
for (var country in countryStateInfo) {
    countySel.options[countySel.options.length] = new Option(country, country);
}

//County Changed
countySel.onchange = function () {

     stateSel.length = 1; // remove all options bar first
     citySel.length = 1; // remove all options bar first
     zipSel.length = 1; // remove all options bar first

     if (this.selectedIndex < 1)
         return; // done

     for (var state in countryStateInfo[this.value]) {
         stateSel.options[stateSel.options.length] = new Option(state, state);
     }
}

Fiddle Demo

Rikin Patel avatar Apr 12 '2016 09:04 Rikin Patel