Mais uma vez recebi algumas dúvidas sobre ASP.NET MVC e vou compartilhar com todos a resposta que eu dei, desta vez a dúvida foi de como fazer um conjunto de DropDownList em cascata.
O que me parece recorrente na maioria das dúvidas que eu recebo em relação ao ASP.NET MVC, é que as dúvidas sempre estão no lado do cliente, no WebForms poderíamos configurar a propriedade AutoPostBack para True do DropDowList e tratar o resto no lado do servidor, no MVC é diferente, você vai ter que escrever um pouco de JavaScript para fazer isso, vamos analisar o problema e criar um cenário.
Vamos fazer uma página que terá um DropDownList com uma relação de estados e quando for selecionado o estado listaremos no outro DropDownList a relação de cidades.
Para isso quando a página for renderizada pela primeira vez já iremos trazer o DropDownList de Estados carregado e iremos carregar o de Cidades com jQuery/Ajax.
Para fazer isso vamos criar as nossas classes do modelo, na pasta “models” crie as classes abaixo:
Uf.cs:
public class Uf
{
public Uf(string siglaUf, string nome)
{
this.Nome = nome;
this.SiglaUf = siglaUf;
}
public string SiglaUf { get; set; }
public string Nome { get; set; }
}
Cidade.cs
public class Cidade
{
public Cidade(string id,string siglaUf, string nome)
{
this.Id = id;
this.SiglaUf = siglaUf;
this.Nome = nome;
}
public string Id { get; set; }
public string SiglaUf { get; set; }
public string Nome { get; set; }
}
Vamos criar agora 2 classes de repositório, para facilitar a consulta no exemplo, crie as 2 classes abaixo na pasta “models”:
UfRepository.cs
public class UfRepository
{
public static IList<Uf> ListaUf()
{
List<Uf> cidades = new List<Uf>();
cidades.Add(new Uf("SP", "São Paulo"));
cidades.Add(new Uf("RJ", "Rio de Janeiro"));
cidades.Add(new Uf("MG", "Minas Gerais"));
return cidades;
}
}
CidadeRepository.cs
public class CidadeRepository
{
public static IList<Cidade> ListaCidade(string SiglaUf)
{
List<Cidade> cidades = new List<Cidade>();
cidades.Add(new Cidade("1","RJ", "Angra dos Reis"));
cidades.Add(new Cidade("2", "RJ", "Rio de Janeiro"));
cidades.Add(new Cidade("3", "RJ", "Barra Mansa"));
cidades.Add(new Cidade("4","SP", "São Paulo"));
cidades.Add(new Cidade("5", "SP", "Sertãozinho"));
cidades.Add(new Cidade("6", "SP", "Osasco"));
cidades.Add(new Cidade("7", "MG", "Belo Horizonte"));
cidades.Add(new Cidade("8", "MG", "Poços de Caldas"));
cidades.Add(new Cidade("9", "MG", "Betim"));
return cidades.Where(x=> x.SiglaUf==SiglaUf).ToList();
}
}
Agora vamos modificar o arquivo Site.Master que está na pasta \Views\Shared, esta modificação é só para acrescentar a referência para o arquivo do jQuery e criar um ContentPlaceHolder para acrescentarmos o JavaScript necessário na nossa View.
Site.Master (linhas 5 e 6)
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<asp:ContentPlaceHolder ID="HeadContent" runat="server"></asp:ContentPlaceHolder>
</head>
Como falado acima precisamos que na primeira renderização da página ela carregue a lista de estados, para isso precisamos carregar esta lista para a View, vou fazer isso através da ViewData[“Ufs”], irei fazer isso na Action Index da HomeController (se ainda não foi feito, adicione um using para o namespace Models no começo da sua classe), veja no exemplo abaixo:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
ViewData["Ufs"] = new SelectList(UfRepository.ListaUf(),"SiglaUf","Nome");
return View();
}
Agora poderemos já começar a fazer o HTML, para isso acrescente o código na View Index da pasta Home conforme o exemplo abaixo:
<% =Html.DropDownList("Ufs","Estado") %>
<select id="Cidades">
<option selected="selected" value="">Cidade</option>
</select>
Como vocês podem perceber na primeira linha, estou criando um DropDownList passando somente 2 parâmetros, o método tentará encontrar uma ViewData com o nome passado no primeiro parâmetro e irá tentar converter esta ViewData para um objeto SelectList, não vou me aprofundar muito para não fugir do escopo, em outro post irei falar mais detalhadamente sobre o DropDownList e SelectList.
Se você testar, verificará que o primeiro DropDownList já está carregando, mas quando mudamos o item selecionado nada acontece, para fazer isso devemos escrever um pouquinho de JavaScript, para facilitar este trabalho iremos usar o jQuery e fazer uma chamada Ajax para uma Action que retorna um JSON.
Vamos começar criando uma Action chamada ListarCidade na HomeController que irá receber no parâmetro id o estado que foi selecionado e irá retornar uma lista de cidades que são daquele estado conforme o código abaixo:
public ActionResult ListaCidade(string id) {
return Json(CidadeRepository.ListaCidade(id));
}
Voltando na View Index na pasta Home vamos acrescentar o JavaScript necessário para fazer a chamada Ajax via jQuery, segue o código:
<asp:Content ID="Javascript" ContentPlaceHolderID="HeadContent" runat="server">
<script type="text/javascript">
$(document).ready(function() {
$("#Ufs").change(function() {
listaCidade($(this).val());
});
});
//chamada ajax para a Action ListaCidade
//passando como parâmetro a Estado selecionado
function listaCidade(uf) {
$.getJSON('<%= Url.Action("ListaCidade") %>/' + uf, listaCidadeCallBack);
}
//função que irá ser chamada quando terminar
//a chamada ajax
function listaCidadeCallBack(json) {
//Limpar os itens que são maiores que 0
//Ou seja: não retirar o primeiro item
$("#Cidades :gt(0)").remove();
$(json).each(function() {
//adicionando as opções de acordo com o retorno
$("#Cidades").append("<option value='" + this.Id + "'>" + this.Nome + "</option>");
});
}
</script>
</asp:Content>
Está pronto, é claro que não é mais fácil que o WebForms, mas o controle te traz mais responsabilidades, você vai ter que fazer (e conhecer) mais HTML e Javascript, não tem jeito.
Faça o download da solução.

