Wednesday, February 21, 2018

[ASP.NET MVC] Hiển thị Delete View dưới kiểu modal

Khi tạo BooksController với lựa chọn [Controller with views, using Entity Framework], Một thư mục mới Books với 4 view (Create.cshtml, Edit.cshtml, Details.cshtml, Delete.cshtml) tương ứng với 4 action (Create, Edit, Details, Delete) trong BooksController.cs được MVC scaffolding tạo ra một cách tự động.

Screenshot_1
Khi ta bấm vào nút [Xóa], Delete view sẽ được load, cho phép người dùng kiểm tra lại thông tin của cuốn sách sẽ xóa và xác nhận xem có thực sự muốn xóa cuốn sách này hay không. Đương nhiên giao diện ban đầu được sinh ra là tiếng Anh nhưng mình đã chuyển sang tiếng Việt cho … vui 😀
Screenshot_2
Tuy nhiên, mình thấy việc chuyển sang và load một view mới chỉ để xác nhận thông tin cuốn sách sẽ xóa thực sự không cần thiết và không cool cho lắm. Thông thường cách hay được áp dụng là hiển thị popup cho phép người dùng xác nhận và thao tác mà không cần phải di chuyển sang view mới. Sau một hồi thỉnh giáo Google-sensei, mình cũng đã làm được điều này. Giờ thì đang ngồi note lại trên blog để cho khỏi quên, nếu có quên thì cũng biết đường mà tìm lại. Nhưng trên hết là để chống mốc, câu bài viết cho blog củ chuối này 😀
Thành quả thì nó như thế này.
Screenshot_3
Bạn có thể thấy rõ ràng là cool hơn rất nhiều 😀 Và để làm được điều này, chỉ cần thực hiện 2 bước đơn giản sau đây:
Bước 1: Cập nhật lại Delete.cshtml


@model BookInfo.Models.Book

@{
    Layout = null;
}

<div class="modal fade" id="deleteModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">&times;</span>
                    <span class="sr-only">Close</span>
                </button>
                <h4 class="modal-title">Xác nhận</h4>
            </div>
            <div class="modal-body">
                <h3>Bạn có chắc muốn xóa cuốn sách này?</h3>
                <div>
                <hr />
                    <table class="table table-bordered table-striped">
                        <tr>
                            <th>Tiêu đề</th>
                            <td>@Html.DisplayFor(model => model.Title)</td>
                        </tr>
                        <tr>
                            <th>Tác giả</th>
                            <td>@Html.DisplayFor(model => model.Author.Name)</td>
                        </tr>
                    </table>
                </div>
            </div><!-- /.modal-body -->
            <div class="modal-footer">
            @using (Html.BeginForm("Delete", "Books", FormMethod.Post))
            {
                @Html.AntiForgeryToken()
                <div class="form-actions no-color text-center">
                    <input type="submit" value="Xóa" class="btn btn-danger" />
                    <button type="button" class="btn btn-default" data-dismiss="modal">Hủy</button>
                </div>
            }
            </div><!-- /.modal-footer -->
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal>
Ở đây, mình dùng Bootstrap modal. Bạn có thể tìm hiểu kỹ hơn về Bootstrap modal tại đây.
Điểm cần lưu ý ở đây đó chính là dòng code Layout = null; dòng code này Delete view sẽ không sử dụng _Layout.cshtml (Views >> Shared) mà đơn giản chỉ là block div với id là deleteModal sẽ được load ngay trên Index.cshtml thông qua Bước 2 dưới đây:
Bước 2: Cập nhật lại Index.cshtml
Trước hết, ta cần cập nhật lại link [Xóa] của mỗi cuốn sách như sau.


<td>
    @Html.ActionLink("Sửa", "Edit", new { id=item.Id }) |
    @Html.ActionLink("Chi Tiết", "Details", new { id=item.Id }) |
    <a class="delete-link" href="@Url.Action("Delete", new { id = item.Id })"><span style="color: red">Xóa</span></a>
</td>
Sau đó, để load deleteModal div trong Delete.cshtml, ta cần thêm vào script section đoạn code AJAX như sau.


$('.delete-link').click(function (e) {
    var a_href = $(this).attr('href'); /* Lấy giá trị của thuộc tính href */
    e.preventDefault(); /* Không thực hiện action mặc định */
    $.ajax({ /* Gửi request lên server */
        url: a_href, /* Nội dung trong Delete.cshtml cụ thể là deleteModal div được server trả về */
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        success: function (data) { /* Sau khi nhận được giá */
            $('.body-content').prepend(data); /* body-content div (định nghĩa trong _Layout.cshtml) sẽ thêm deleteModal div vào dưới cùng */
            $('#deleteModal').modal('show'); /* Hiển thị deleteModal div dưới kiểu modal */
        }
    });
});
Và cuối cùng bạn chỉ cần build lại project và chiêm ngưỡng thành quả 🙂
Previous Post
Next Post

post written by:

2 comments:

  1. Chào bạn!
    Bạn cho mình hỏi là cái đoạn Ajax này được thêm vào chỗ nào?
    Sau đó, để load deleteModal div trong Delete.cshtml, ta cần thêm vào script section đoạn code AJAX như sau.

    ReplyDelete
    Replies
    1. bạn dán vào trang sẽ call action nhé

      Delete