Untitled Page
cuestión a
resolver
Imaginemos que queremos cargar 3 combos en
cascada, que contienen respectivamente continentes, países y ciudades: Cuando el
usuario cambie el valor del primer combo (continente) hay que cambiar el
contenido del combo de países, y cuando cambie el de países, hay que cambiar el
de las ciudades.
Esta otra entrada de mi blog hace referencia a algunos de los conceptos que aquí se utilizan: Actualización de datos en página web mediante AJAX y JSON
parte cliente
Definición de los combos EN Html
<select name="cmbContinentes" id="continentes" class="combosLugar"></select>
<select name="cmbPaises" id="paises" class="combosLugar "></select>
<select name="cmbCiudades" id="ciudades" class="combosLugar"></select>
eL CÓDIGO Javascript
1.
En la carga de la pantalla (con jQuery) añadir la
carga del primer combo que a su vez desencadena la carga de los siguientes, y el
evento .change para los elementos con class="comboDeLugar" (es decir, nuestros
combos).
$(document).ready(function () {
// Cargar 1er combo (que a su vez desencadena la carga de los demás)
cargaCombo("cmbContinentes", '../../Lugar/Continentes', null);
// Definición evento OnChange para los combos de medida de neumáticos
$(".combosLugar").change(function (e) {
cargaSiguienteCombo(this.id)
});
// Inicialización (opcional). Sólo el primer combo a modo de ejemplo.
$("#comboContinentes")[0].value = "cmbContinentes"
}
2.
Definición de la función que carga un combo
mediante Ajax y Json
// Cargar combo de forma asíncrona, utilizando ajax y formato json.
function cargaCombo(cmb, url, params) {
$.ajax({
url: url,
data: params,
dataType: 'json',
success: (function (data) {
$("#" + cmb).html('');
$.each(data, function (i, item) {
$("#" + cmb).append("<option value='" +
item.Value + "'>" + item.Text + "</option>");
});
cargaSiguienteCombo(cmb);
})
});
}
3.
Definición de la función que carga el siguiente
combo.
// Cargar el siguiente combo
function cargaSiguienteCombo(changedCombo) {
if (changedCombo == "") {
return cargaCombo(
"cmbContinentes",
'../../Lugar/Continentes',
null
);
}
if (changedCombo == "cmbContinentes") {
return cargaCombo(
"cmbPaises",
'../../Lugar/Paises',
"continente=" + $("#cmbContinentes")[0].value
);
}
if (changedCombo == "cmbPaises") {
return cargaCombo(
"cmbCiudades",
'../../Lugar/Ciudades',
"pais=" + $("#comboPaises")[0].value
);
}
}
parte servidor:
la clase que recibe las peticiones ajax
Partimos de la base de que utilizamos
ASP.Net MVC 3.
La definición de las entidades Continente,
Pais y Ciudad no se describe en este documento, porque son muy simples. Sólo
indicaré que están ligadas a sendas tablas cuyos campos son:
·
Continentes: Nombre
·
Paises:
Nombre, Continente
·
Ciudades:
Nombre, Pais
La definición de la clase que recibe las
peticiones Ajax desde el código javascript de la página web, es la siguiente:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Dream.Models;
namespace MiProyecto.Controllers
{
public class LugarController : Controller
{
private MisEntities db = new MisEntities();
/// <summary>
/// Retorna los continentes, hardcoded (no desde BDD)
/// </summary>
/// <returns></returns>
public JsonResult Continentes()
{
var list = new List<object>() {
new { Text = "Europa", Value = "Europa" },
new { Text = "América", Value = "América" },
new { Text = "Asia", Value = "Asia" },
new { Text = "África", Value = "África" },
new { Text = "Oceanía", Value = "Oceanía" },
};
return this.Json(list, JsonRequestBehavior.AllowGet);
}
/// <summary>
/// Retorna los países de cierto continente
/// </summary>
/// <param name="continente">Nombre de continente</param>
/// <returns></returns>
public JsonResult Paises(string continente)
{
var list = from pais in db.Paises
where pais.Continente == continente
select new { Text = pais.Nombre, Value = pais.Nombre };
return this.Json(list.ToList(), JsonRequestBehavior.AllowGet);
}
/// <summary>
/// Retorna las ciudades de cierto pais
/// </summary>
/// <param name="pais">Nombre de pais</param>
/// <returns></returns>
public JsonResult Ciudades(string pais)
{
var list = from ciudad in db.Ciudades
where ciudad.Pais == pais
select new { Text = ciudad.Nombre, Value = ciudad.Nombre };
return this.Json(list.ToList(), JsonRequestBehavior.AllowGet);
}
}