DropDownList em Cascata com ASP.NET MVC e jQuery

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.


Comments

Joseph Jackson
Joseph Jackson
17 February 2010 15:11
Very awesome post. I just came by your website and wanted to say that I have actually enjoyed  exploring your content. Any way, I’ll be subscribing to your feed and I hope you post again soon!
Jackson Paradowski
Jackson Paradowski
18 February 2010 23:19
Thanks for making the effort to describe the terminlogy towards the newbies!
stocks
stocks
19 February 2010 22:34
I was wondering if you would be interested in becoming a guest poster on my blog? In exchange you could include a link your post? Please let me know when you get a chance and I will send you my contact details - thanks.
Coupons
Coupons
20 February 2010 03:23
Every cloud has a sliver lining in this situation.
Daniel Millions
Daniel Millions
20 February 2010 06:00
Please let me know if you are looking for a writer for your website. You have some good content and I think I would be a good asset.
ssk sorgulama
ssk sorgulama
20 February 2010 19:31
i love to read articles that are informative and beneficial in nature.
diet reviews
diet reviews
21 February 2010 14:39
Do you accept guest posts? I would love to write couple articles here.
I was wondering what is up with that weird gravatar??? I know 5am is early and I'm not looking my best at that hour, but I hope I don't look like this! I might however make that face if I'm asked to do 100 pushups. lol
cinsel bilgiler
cinsel bilgiler
21 February 2010 19:51
Great article, this has to be THE single best article online.. thanks..
Fatcow Coupon
Fatcow Coupon
24 February 2010 23:45
I can't seem to locate your syndication feed, I'd love to get more your posts.
Tagesgeld Übersicht
Tagesgeld Übersicht
25 February 2010 18:46
You own a very interesting blog covering lots of topics I am interested as well.Just bookmarked your blog so I can read more in the next days... Please continue your marvellous artice writing
File Folders
File Folders
26 February 2010 12:30
Me and my friend were arguing about an issue similar to this! Now I know that I was right. lol! Thanks for the information you post.
weight tablets
weight tablets
26 February 2010 14:10
I should really be getting on with some work
Fatcow
Fatcow
28 February 2010 16:54
Should I get a Dedicated Hosting? Right now I am using shared hosting but they keep shutting me down because of high server load. Im getting about 4,000 UV a day. What brand should I get?
games ps2
games ps2
1 March 2010 03:37
Hi First time hopped here on your site, founde on Bing.
personal loans
personal loans
1 March 2010 21:43
Yes, I have been looking for this all week better late than never!
Hotels Phangan
Hotels Phangan
3 March 2010 00:39
Hey there,
I  love your weblog. Altavista sent me here. I  found so much <B>good imformation</B> here.
Will surely visit it again.
wow mobiles
wow mobiles
3 March 2010 02:48
WoW Mobiles is awesome! I get free mobile service with t-mobile because I refered 3 people to wow. You can too!
doi
doi
3 March 2010 03:56
I still believe Victor Cavalcante | Blog | DropDownList em Cascata com ASP.NET MVC e jQuery that you should have affiliate links for the products that meet your standards for excellence. Hi First time hopped here on your site, founde on Google. Thank you!! You have given me much to think about. doi Send me news to jeanhenriquealvesdasilva@hotmail.com
flash based chat
flash based chat
3 March 2010 11:04

Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon.
free hd movies
free hd movies
3 March 2010 11:43
I like watching movies online, it is way cheaper than going to the theaters.
mortgage lead generation
mortgage lead generation
3 March 2010 15:39
There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.
watch movies online
watch movies online
4 March 2010 04:04
I love watching movies online, it is way cheaper than going to the theaters.
Convent Station NJ Plumbing
Convent Station NJ Plumbing
4 March 2010 13:15
This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work.
Cheap Impotence Medication
Cheap Impotence Medication
4 March 2010 14:59
Knowing real Viagra pills is quite easy. The popular formulation by Pfizer is blue in colour, diamond-shaped and has the stated dose inscribed on one side of each pill. On the other side, the name of the manufacturer Pfizer is inscribed.
jasminlive
jasminlive
4 March 2010 15:17
Aw, this was a really quality post. In theory I'd like to write like this too - taking time and real effort to make a good article... but what can I say... I procrastinate alot and never seem to get something done
WoW Mobiles
WoW Mobiles
5 March 2010 11:53
Is tethering against the Terms of Service of mobile phone companies? Which ones allow it?
jobs uk
jobs uk
5 March 2010 12:35
jobs uk and free job postings on jobs pub

boards
boards
6 March 2010 04:37
I have recently started using the blogengine.net and I having some problems here? in your blog you stated that we need to enable write permissions on the App_Data folder...unfortunately I don't understand how to enable it.
boards
boards
6 March 2010 13:30
Hi. this is kind of an "unconventional" question , but have other visitors asked you how get the menu bar to look like you've got it? I also have a blog and am really looking to alter around the theme, however am scared to death to mess with it for fear of the search engines punishing me. I am very new to all of this ...so i am just not positive exactly how to try to to it all yet. I'll just keep working on it one day at a time.
acai
acai
7 March 2010 04:17
Hello everybody. I was just surfing the Internet for fun when I found your website. Terrific post. Thanks a ton for sharing your knowledge! It is great to see that some people still put in an effort into managing their websites. I'll be sure to check back from time to time.
Contractor Mortgage
Contractor Mortgage
8 March 2010 06:16
Nice information, many thanks to the author. It is incomprehensible to me now, but in general, the usefulness and significance is overwhelming. Thanks again and good luck!
Nathaniel Nienhaus
Nathaniel Nienhaus
8 March 2010 16:49
The Michael Jackson film has to be my preferred film. Each occasion I watch it I discover new things that I enjoy.
sildenafil citrate pill
sildenafil citrate pill
8 March 2010 19:58
I appreciate the effort, and I think the writer definately knows their stuff... has better info than the wiki on the subject!
watch the pacific online
watch the pacific online
8 March 2010 21:32
Olla.Hello.Forgive me but my english language isn't good.however i simply intend to tell that i like this article very much.Say thank you!
mortgage loan modification
mortgage loan modification
9 March 2010 04:04
Hi, Good content throughout the site. This post is probably where I got the most useful information for my information gathering. Thanks for posting, maybe we can see more on this. I also like this layout can you tell me where to get it  
Diet Pills Reviews
Diet Pills Reviews
9 March 2010 09:07
Awesome post.This is about " DropDownList em Cascata com ASP.NET MVC e jQuery ". I just came by your website and wanted to say that I have actually enjoyed  exploring your content. Any way, I’ll be subscribing to your feed and I hope you post again soon!Thanks
Allison Luiz
Allison Luiz
9 March 2010 10:09
Bom demais, Victor! Simples e direto. Ajudou bastante.
trending
trending
9 March 2010 13:40
Your site Victor Cavalcante | Blog | DropDownList em Cascata com ASP.NET MVC e jQuery is clearly a labor of love. Some of your posts take hours or even days to compile. Hi First time hopped here on your site, founde on ASK. Thank you so much for responding so quickly. It really helped me. trending Send me news to Danpitbull2k8@hotmail.com  Send me news to Danpitbull2k8@hotmail.com
web based project management software
Thanks for update

Add comment


(Will show your Gravatar icon)

biuquote
Loading