De Webforms para MVC – DropDownList em cascata

Continuando o artigo sobre como criar DropDownList com MVC, hoje vou finalizar mostrando como criar um DropDownList em cascata, ou seja ao selecionar um item de um DropDownList, um segundo DropDownList deve ser carregado.

No exemplo, ao selecionar um determinado Autor os livros desse autor devem ser carregados.

Antes de começar algumas informações importantes, se você não conhece JQuery considero obrigatório conhecer, na verdade não da para ficar mais sem saber JavaScript, e para os que tem algum “trauma” de JavaScript o JQuery facilita e muito a nossa vida, e falando em JQuery recomendo essa série de posts do Fabrício Sanchez sobre JQuery, leitura obrigatória!

Para começar eu criei um classe para representar os Livros.

[sourcecode language=”csharp”]
public class Livro
{
public int IdLivro { get; set; }
public int IdAutor { get; set; }
public string Titulo { get; set; }
}
[/sourcecode]

E no Controller criei um método que vai receber o id do Autor, e fazer uma busca pelos livros, para representar os livros criei uma lista de Livros no método do Controller mesmo, só para criar o exemplo. Vamos ao código.

[sourcecode language=”csharp”]
public JsonResult ObterLivrosDoAutor(int id)
{
var livros = new List<Livro>
{
new Livro{IdAutor = 2, IdLivro = 1, Titulo = "O Anticristo"},
new Livro{IdAutor = 2, IdLivro = 2, Titulo = "Assim Falou Zaratustra"},
new Livro{IdAutor = 2, IdLivro = 3, Titulo = "Para Além do Bem e do Mal"},
new Livro{IdAutor = 1, IdLivro = 4, Titulo = "Os Irmãos Karamazov"},
new Livro{IdAutor = 1, IdLivro = 5, Titulo = "O Jogador"},
new Livro{IdAutor = 1, IdLivro = 6, Titulo = "Recordações da Casa dos Mortos"}
};

return Json(livros.Where(l => l.IdAutor == id), JsonRequestBehavior.AllowGet);
}
[/sourcecode]

Alguns detalhes sobre esse código, o retorno do método é um JsonResult, para quem não conhece JSON (JavaScript Object Notation) veja alguns exemplos e informações. O MVC já possui algumas funcionalidades para pegar nossos objetos e “converter” para a notação dos objetos em JSON, é isso que acontece no return Json(), outro detalhe é nesse método autorizar o GET, o que informamos no segundo parâmetro do método JsonRequestBehavior.AllowGet.

Isso tudo porque vamos fazer tudo por AJAX, não vamos recarregar a página toda quando o usuário selecionar um Autor, vamos pedir a lista de Livros e carregar só o DropDownList dos Livros.

Voltando a View, vamos as alterações, primeiro adicionei um item Selecione…, no DropDownList de Autor, e criei um para os Livros.

[sourcecode language=”html”]
<p>
<select id="autor">
<option value="0">Selecione…</option>
@foreach (var autor in Model.Autores)
{
<option value="@autor.IdAutor">@autor.Nome</option>
}
</select>
</p>
<p>
<select id="livro">

</select>
</p>
[/sourcecode]

E agora a parte divertida, um pouco de JavaScript/JQuery para fazer toda a lógica de descobrir se existe algum Autor selecionado, se existir chamar o método no servidor que devolve a lista de Livros, e com a lista obtida escrevemos HTML na página já carregada, caso nenhum Autor for selecionado limpamos a lista de Livros  já carregados.

[sourcecode language=”javascript”]
<script type="text/javascript" language="javascript">
$(function () {
$("#autor").change(function () {
if (possuiAutorSelecionado()) {
carregarLivrosDoAutor();
} else {
limparLivrosCarregados();
}
});
});

function possuiAutorSelecionado() {
return $("#autor").val() != "0";
}

function carregarLivrosDoAutor() {
var url = "dropdown/obterlivrosdoautor/" + $("#autor").val();
$.getJSON(url, null, function (data) {
limparLivrosCarregados();
$.each(data, function (indice, livro) {
$("#livro").append("<option value=’" + livro.IdLivro +"’>" + livro.Titulo + "</option>");
});
});
}

function limparLivrosCarregados() {
$("#livro").empty();
}
</script>
[/sourcecode]

Bom com isso temos o DropDownList em cascata, usando alguns recursos interessantes, JQuery, Ajax, e tudo que temos direito. Para quem vei odo WebForms não temos mais AjaxToolkit, nada de UpdatePanel, nada disso para atrapalhar nossa vida \o/, então estude JQuery ;).

Outro ótimo artigo sobre o assunto com MVC, é o artigo do José Lino Neto, vale a leitura!

Código no GitHub.

Abraços e até o próximo artigo.