2
respostas

Ajax com bootstrap Modal

Afim de expandir os conhecimentos do curso, implementei método de alteração do produto com modal bootstrap.No Back end está tudo certo, é alterado certo. Porém estou com dificuldade no Front-End que não está asincrono.

Página Index

@model IEnumerable<CaelumEstoque.Models.Prod>




<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 id="prod@(item.Codigo)">
        <td>
            @Html.DisplayFor(modelItem => item.Codigo)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Descricao)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Preco)
        </td>
        <td>
                <a href="#" class="btn btn-default details" data-url="@Url.Action("Details", "Prod", new { id = item.Codigo })">Detalhe</a>
                <a href="#" class="btn btn-primary edit" data-url="@Url.Action("Edit", "Prod", new { id = item.Codigo })"><i class="glyphicon glyphicon-edit"></i></a>
                @*<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>

<div class="modal" id="modal">

</div>


<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

<script>


    $(function () {
        $('.details').click(function () { // class name selector
            var url = $(this).data('url'); // use data(), not attr()
            $("#modal").load(url, function () {
                $("#modal").modal("show");
            })
        });
    })

    $(".edit").click(function () {
        var url = $(this).data('url'); // use data(), not attr()
        $("#modal").load(url, function () {
            $("#modal").modal("show");
        })
    })


</script>

Modal Edit

@model CaelumEstoque.Models.Prod
@{
    Layout = null;
}


<div class="modal-dialog">
    <div class="modal-content">
        @using (Html.BeginForm("ParcialEdit","Prod"))
        {
            <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>

            <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 salvar" />
                <input type="button" value="Cancelar" class="btn btn-default" data-dismiss="modal" />
            </div>
        }
    </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

<script>


</script>

Código Back-End

using CaelumEstoque.DAO;
using CaelumEstoque.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CaelumEstoque.Controllers
{
    public class ProdController : Controller
    {

        public static List<Prod> _listaProdutos = new List<Prod>()
        {
            new Prod { Codigo=01, Descricao="Produto 1", Preco=10 },
            new Prod { Codigo=02, Descricao="Produto 2", Preco=15 },
            new Prod { Codigo=03, Descricao="Produto 3", Preco=20 }
        };
        // GET: Prod
        public ActionResult Index()
        {

            IList<Prod> lista = _listaProdutos;

            return View(lista);
        }


        public ActionResult Details(int id) {

            var existe = _listaProdutos.Find(x => x.Codigo == id );

            ViewBag.Detalhes = existe;
            return View("parcial",existe);
        }

        public ActionResult Edit( int id) {
            var existe = _listaProdutos.Find(x => x.Codigo == id);


            //return Json( registro);
            return View(existe);
        }

        public ActionResult ParcialEdit(Prod p)
        {
            var registro = _listaProdutos.Find(x => x.Codigo == p.Codigo);
            registro.Descricao = p.Descricao;
            registro.Preco = p.Preco;

            //return Json(registro);
            //return RedirectToAction("Index");
            //return Json(new {"/Prod/Index" });
            //return Json(new { Title = "abc", Summary = "Summary", Magazine = "This is magazine", Url = "Index" }, JsonRequestBehavior.AllowGet);
            return Json( registro );
        }

        public ActionResult parcial() {
            return View();
        }


    }
}

Veja que eu faço retornar um Json, porém tenho que fazer o código front pra ficar assincrono.

2 respostas

Olá, Lorran

Não sei se entendi direito o que você deseja fazer, mas veja o código abaixo:

            var url = $(this).data('url'); // use data(), not attr()
            $("#modal").load(url, function () {
                $("#modal").modal("show");
            })
  • Primeiro, a view parcial é requisitada com .load(url, ...
  • Em seguida, assim que a view parcial é carregada, a página é exibida com $("#modal").modal("show");. Isso acontece porque dentro de load há uma function que é o callback, isto é, a função que é chamada só quando o carregamento é completado

Esses passos acima mostram o comportamento síncrono. Se você quiser deixar assíncrono, é preciso deixar o método modal fora do callback, ou seja:

            $("#modal").load(url)
            $("#modal").modal("show");

Isso fará com que uma dialog modal vazia (ou não, dependendo da última vez que foi usada) seja aberta imediatamente, e quando os dados forem carregados ela é exibida.

Para mostrar ao usuário que a dialog está carregando, você pode exibir um gif "carregando..." ou algo parecido, sempre que a função load for chamada. E antes de chamar a função modal, você esconde esse gif, aí o usuário verá a nova view modal carregada.

Não funcionou :(