Desenvolvimento - ASP. NET
ASP.NET MVC e Bootstrap - Exibindo views modais
Veja neste artigo como abrir views do ASP.NET MVC em janelas modais com o framework Bootstrap.
por Joel RodriguesUm dos frameworks front-end mais utilizados atualmente (provavelmente o mais utilizado) é o Bootstrap, que além de nos permitir desenvolver páginas web responsivas, nos oferece diversos outros recursos de interface, como menus, botões e ícones. Uma prova da solidez e estabilidade desse framework é a sua utilização nativa nos projetos ASP.NET, com os templates gerados automaticamente pelo Visual Studio.
Neste artigo veremos como utilizar o componente modal do Bootstrap, que, como o nome sugere, abre uma janela popup na tela para visualização ou inserção de dados. Neste componente podemos exibir deste texto simples até formulários completos, bastando seguir o modelo indicado na documentação oficial (ver seção Links no final do artigo).
Entendendo o modal do Bootstrap
Na documentação do Bootstrap encontramos a seguinte estrutura que deve ser usada para formar a janela modal (Listagem 1), o que resulta na janela que vemos na Figura 1.
Listagem 1: Estrutura da janela modal
<div class="modal fade"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body…</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->
Figura 1: Exemplo de janela modal padrão
Para abrir o modal, existem duas formas:
- Adicionar as propriedades data-toggle=”modal” e data-target=”#id_da_div_modal” no elemento que abrirá a janela (um botão, por exemplo). Desta forma, sempre que clicarmos no botão, a div cujo id foi indicado na propriedade data-target será aberta.
- Usar JavaScript e chamar a função modal a partir da div previamente selecionada (via jQuery, por exemplo). Esta forma permite uma maior customização do procedimento, e por isso será utilizada neste artigo, pois em nosso exemplo precisaremos carregar o conteúdo do modal dinamicamente, ler propriedades, etc., o que só pode ser feito via JavScript.
Bootstrap modal no ASP.NET MVC
Em nosso exemplo partiremos de um cenário bastante simples e conhecido por todos: uma listagem de registros (view Index) com opções para abrir as views secundárias (Delete, Details e Edit) em janelas modais.
Nosso objeto modelo será a classe Produto, que possui apenas três propriedades para exemplificação e cujo código pode ser visto na Listagem 2.
Listagem 2: Código da classe modelo
public class Produto { private string _codigo; [Display(Name="Código")] public string Codigo { get { return _codigo; } set { _codigo = value; } } private string _descricao; [Display(Name = "Descrição")] public string Descricao { get { return _descricao; } set { _descricao = value; } } private decimal _preco; [Display(Name = "Preço Unitário")] public decimal Preco { get { return _preco; } set { _preco = value; } } }
A parte de persistência de dados não será tratada neste artigo, direcionaremos nossa atenção apenas às views.
Em nossa view Index, onde automaticamente é criada uma tabela para listar os registros, adicionaremos na última coluna alguns botões que serão usados para abrir as janelas modais das ações secundárias. Assim, nossa table ficará como mostra a Listagem 3.
Listagem 3: Tabela para listagem de dados na view Index
<table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Codigo) </th> <th> @Html.DisplayNameFor(model => model.Descricao) </th> <th> @Html.DisplayNameFor(model => model.Preco) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Codigo) </td> <td> @Html.DisplayFor(modelItem => item.Descricao) </td> <td> @Html.DisplayFor(modelItem => item.Preco) </td> <td> <button class="btn btn-default details" data-id="@item.Codigo"><i class="glyphicon glyphicon-file"></i></button> <button class="btn btn-danger delete" data-id="@item.Codigo"><i class="glyphicon glyphicon-trash"></i></button> <button class="btn btn-primary edit" data-id="@item.Codigo"><i class="glyphicon glyphicon-edit"></i></button> </td> </tr> } </table>
Observe que foi adicionado um data-attribute aos botões contendo o id (ou código neste caso) do registro listado em cada linha. Essa propriedade será resgatada quando clicarmos nos botões, para que possamos passar esse código para as actions Details, Delete e Edit.
Existem várias formas de abrir uma view em uma janela modal, neste artigo utilizaremos a seguinte: teremos uma div vazia na view Index dentro da qual carregaremos dinamicamente o conteúdo das demais views, usando Ajax. As views secundárias deverão seguir o modelo que foi visto anteriormente, contendo todo a estrutura a partir da div modal-dialog. A div de classe modal ficará na view Index.
Assim, adicionaremos apenas uma div vazia logo após a table (Listagem 4).
Listagem 4: Div dentro da view Index que irá carregar o modal
<div class="modal" id="modal"> </div>
Feito isso, precisamos agora tratar o evento click dos botões para carregar o conteúdo desta div e exibi-la na forma de modal. Utilizaremos a section scripts dentro da view Index e usaremos o método load da jQuery para carregar a view secundária, passando como parâmetro o código do produto em questão (Listagem 5).
Listagem 5: Código JavaScript para carregar e abrir o modal
@section scripts{ <script> $(function () { $(".details").click(function () { var id = $(this).attr("data-id"); $("#modal").load("Details?id=" + id, function () { $("#modal").modal(); }) }); }) </script> }
Neste código, passamos para a função load o endereço que queremos carregar e uma função de callback que é executada quando a requisição é concluída. Neste caso, quando o load carregar o conteúdo, faremos com que a div modal seja exibida.
Basta agora que adequemos a view Details à estrutura vista anteriormente. Assim, essa view ficará como mostra a Listagem 6, contendo todas as classes que o Bootstrap requer para organizar o modal.
Listagem 6: View Details adequada ao modal
@model WebApplication1.Models.Produto @{ Layout = null; ViewBag.Title = "Details"; } <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> <h4 class="modal-title">Detalhes do produto</h4> </div> <div class="modal-body"> <p>@Html.DisplayNameFor(model => model.Codigo) : @Html.DisplayFor(model => model.Codigo)</p> <p>@Html.DisplayNameFor(model => model.Descricao) : @Html.DisplayFor(model => model.Descricao)</p> <p>@Html.DisplayNameFor(model => model.Preco) : @Html.DisplayFor(model => model.Preco)</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Fechar</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog -->
Agora, se clicarmos no primeiro botão de uma das linhas da tabela da view Index, teremos uma janela modal com a view Details referente àquele produto, como mostra a Figura 2.
Figura 2: Detalhes do produto em janela modal
Façamos agora a view Edit, que é um pouco mais complexa por conter um form. Neste caso, basta que adicionemos o form dentro da div modal-content e as divs modal-header, modal-body e modal-footer dentro do form, como mostra a Listagem 7.
Listagem 7: View Edit adequada para modal
@model WebApplication1.Models.Produto @{ Layout = null; ViewBag.Title = "Edit"; } <div class="modal-dialog"> <div class="modal-content"> @using (Html.BeginForm()) { <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> <h4 class="modal-title">Editar produto</h4> </div> @Html.AntiForgeryToken() <div class="modal-body"> <div class="form-horizontal"> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.Codigo, new { @class = "control-label col-md-3" }) <div class="col-md-9"> @Html.TextBoxFor(model => model.Codigo, new { @class = "form-control" , @readonly="readonly"}) @Html.ValidationMessageFor(model => model.Codigo) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Descricao, new { @class = "control-label col-md-3" }) <div class="col-md-9"> @Html.TextBoxFor(model => model.Descricao, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Descricao) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Preco, new { @class = "control-label col-md-3" }) <div class="col-md-9"> @Html.TextBoxFor(model => model.Preco, new { @class="form-control"}) @Html.ValidationMessageFor(model => model.Preco) </div> </div> </div> </div> <div class="modal-footer"> <input type="submit" value="Salvar" class="btn btn-primary" /> <input type="button" value="Cancelar" class="btn btn-default" data-dismiss="modal"/> </div> } </div><!-- /.modal-content --> </div><!-- /.modal-dialog -->
E para abrir a view Edit no modal, na view Index devemos realizar o mesmo procedimento em JavaScript feito para a view Details (Listagem 8).
Listagem 8: Abrindo a view Edit no modal
$(".edit").click(function () { var id = $(this).attr("data-id"); $("#modal").load("Edit?id=" + id, function () { $("#modal").modal(); }) });
Isso resulta no que vemos na Figura 3. Observe que agora temos dois botões, sendo que um é o input submit do form e o outro é um botão que simplesmente fechará modal, sem submeter o form.
Figura 3: Edição do registro na janela modal
As views Delete e Create seguem o mesmo formato, por isso não serão vistas aqui, mas o leitor poderá facilmente implementá-las seguindo os modelos aqui apresentados.