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 Rodrigues



Um 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 -->
Exemplo de janela modal padrão

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.

Detalhes do produto em janela modal

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.

 Edição do registro na janela modal

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.

Links

Modal - Bootstrap
Joel Rodrigues

Joel Rodrigues - Técnico em Informática - IFRN Cursando Bacharelado em Ciências e Tecnologia - UFRN Programador .NET/C# e Delphi há quase 3 anos, já tendo trabalhado com Webservices, WPF, Windows Phone 7 e ASP.NET, possui ainda conhecimentos em HTML, CSS e Javascript (JQuery).