Entity Framework Code First CRUD sử dụng Bootstrap Modal

Chú ý kẻo nhầm nhọt sang trồng trọt giữa 2 từ "Modal" và "Model". Modal là dialog của Bootstrap, còn Model là 1 class bất kỳ. (trong mô hình MVC)

Entity Framework (EF) code first

Code first là phương pháp tạo các class Model sau đó phát sinh ra database. Đây là cách thức phát triển ứng dụng nhanh khi chưa có database. Bằng cách sử dụng code first bạn cũng có thể tạo dữ liệu ban đầu cho database của mình. Sau đây mình sẽ hướng dẫn cách sử dụng EF code first, sẽ rất đơn giản thôi.

Mình sẽ tạo 1 project ASP.NET MVC 5 (VS 2013) để có thể sử dụng Bootstrap có sẵn trong project. Lưu ý là từ ASP.NET MVC 5 trở lên thì mới tích hợp sẵn Bootstrap. Nếu bạn dùng các phiên bản thấp hơn, Bootstrap cũng dễ dàng được thêm vào bằng cách download từ trang chủ của Bootstrap

Thêm 1 Model

Thêm model bằng cách right-click vào thư mục Models trong project > Add > Class...

Bạn có thể tùy chỉnh nhiều attribute trong các Properties, nhưng trong phần này mình sẽ không nói đến cho đơn giản. Model như sau:

Bây giờ là tạo database. Class tạo database được viết:

Class này kế thừa lớp DbContext và nằm trong namespace System.Data.Entity; Trong dbcontext mình tạo 1 table Items bằng cách khai báo 1 properties có kiểu là DbSet, khi database được tạo ra, 1 table có tên Items sẽ được thêm vào database.

Trong phương thức khởi tạo của lớp context này lại được kế thừa từ phương thức khởi tạo của lớp cha với 1 tham số là tên của chuỗi kết nối. Mở file web.config ra và thêm vào chuỗi kết nối như sau:

Tất nhiên là bạn phải chỉnh lại connectionString cho phù hợp với máy tính của mình rồi.

Vậy là ta đã có Model, database context, chuỗi kết nối. Bây giờ nếu muốn khởi tạo giá trị ban đầu cho database, các bạn làm thêm 1 class nữa như sau: (nếu không muốn khởi tạo giá trị ban đầu bạn có thể bỏ qua bước này)

Class này kế thừa từ DropCreateDatabaseIfModelChanges và override phương thức Seed để thêm dữ liệu vào. Và cuối cùng, mở file Global.asax ra và thêm phương thức khởi tạo dữ liệu vào Appication_Start

OK, vậy là xong EF code first. Khá đơn giản phải không?!

EStoreController

Tạo mới 1 controller bằng cách right-click vào thư mục Controllers > Add > Controller...

Trong controller mới tạo, tạo 1 thể hiện của database context để sử dụng, đồng thời trong phương thức Index sẽ liệt kê ra danh sách các Item có trong table Items

Tạo View cho Action Index bằng cách right-click vào Index Action > Add View...

Ngắm sơ qua View của Index, mình sẽ đi chi tiết sau

Chưa có gì khó hiểu phải không? Ở đây mình hiển thị danh sách các Item ra bằng vòng lặp foreach với Model là danh sách các Item.

Bootstrap Modal

Trước tiên là hiểu về modal và cách sử dụng. Mở tài liệu về modal của bootstrap tại đây. Copy phần example và dán vào View Index để test thử. button add new item sẽ mở modal với 2 attribute quan trọng là data-toggle='modal'data-target='#myModal'. Chú ý là nếu với thẻ a, bạn có thể sử dụng href='#myModal' để thay cho data-target. Còn nếu là button thì sử dụng attribute data-target.

Kết quả

bootstrap modal demo

Và giờ, vấn đề đặt ra là: với mỗi action add, update, delete bạn có một modal riêng. Bạn có thể viết cả 3 modal trong cùng trang Index, nhưng phải nói là cách đó không khả thi (Khó khi load data vào mỗi modal, html trùng lặp và dài vô tận). Vậy giải pháp là gì?

Mình sẽ sử dụng 3 "kỹ thuật"

  1. Đưa mỗi modal vào 1 PartialView, tất nhiên cũng sẽ có chuyện html lặp lại nhưng đó là vấn đề nâng cao. Mỗi khi click vào liên kết, gọi đến Action và Action đó trả về PartialView để load modal. Sở dĩ lại dùng PartialView vì nó sẽ trả về kết quả là View mà không có Layout, nói dễ hiểu là nó chỉ có trả về những gì (html, css, js...) nằm trong cái PartialView đấy thôi.
  2. PartialView trả về sẽ được load bằng jquery load function. Tham khảo jquery load.
  3. Cuối cùng, việc load modal sẽ được thực hiện bằng javascript chứ không dùng html (html attribute) nữa.

Đầu tiên mình sẽ làm cụ thể với việc thêm mới.

Bước 1: Đưa modal Add vào PartialView

PartialView dễ dàng có được bằng cách giống hệt như thêm mới 1 View. Mình đặt tên cho PartialView này là _Add.cshtml. Vậy nội dung của _Add là gì?

Mình sẽ không đưa nguyên cục modal vào _Add mà chỉ cần đưa những thứ phía trong thẻ div.modal-dialog. Khi nhấn vào liên kết add, modal _Add sẽ được load lại vào #myModal bằng jquery load.

Khi đó, modal ở Index chỉ còn lại "cái khung"

Và button add chỉ còn đơn giản thế này, không cần attribute vì mình sẽ sử lý trong javascript.

Bước 2: Gọi modal

Việc gọi modal trong javascript được thực hiện như sau:

Chú ý:
  1. Nếu bạn đặt đoạn script này trong Index, bạn phải đặt trong @section scripts. Vì sao thì bạn cũng biết rồi đấy, trong _Layout, jquery được load phía sau @RenderBody, nếu không đặt trong @section scripts (section này load phía dưới jquery) thì các jquery function sẽ không hoạt động.
  2. Thêm 1 action trong EStoreController và trả về PartialView("_Add")

Cùng xem lại trang Index.cshtml 1 cách tổng quát

Bước 3: Hoàn thiện form Add

Bây giờ mình sẽ hoàn thiện các chức năng còn lại. Đầu tiên là ở PartialView _Add.cshtml

Cuối cùng: Add Action

Tiếp theo sẽ là Action Add

Kết quả

Đơn giản phải không? Các hành động cập nhật hay xóa hoàn toàn tương tự, các bạn có thể tự viết hoặc tham khảo trong source code bên dưới nhé.

Source code

Comments

  1. Chào bạn.
    Mình cũng đang làm phần thêm, xóa, sửa sử dụng modal trong bootstrap nhưng chưa truyền dữ liệu qua lại giữa các modal được. Bạn có thể share source code cho mình tham khảo được không?
    Email: haivuit91@gmail.com
    Cảm ơn bạn!

    ReplyDelete
    Replies
    1. Đã update source code, hy vọng giúp được bạn.

      Delete
  2. Mr. Hải,
    mình đã "lỡ tay" xóa source code của bài này đi rồi, mình sẽ làm lại 1 ví dụ tương tự trong thời gian sớm nhất (tối nay - nếu có thể). Nếu bạn gặp khó khăn ở bước nào, mình có thể giúp.
    Thân.

    ReplyDelete
    Replies
    1. Chào bạn,
      Về cơ bản mình đã làm được rồi, chỉ còn một số lỗi nhỏ hi vọng bạn có thể giúp mình.
      1, Khi load trang index sao có một đường mờ của cái modal hiện lên chỉ khi click vào edit hoặc del rồi tắt cái modal đó thì đường mờ đó mới ẩn đi
      https://drive.google.com/open?id=0B6G5C9uGw7e3UllILXlabVFsQmc&authuser=0
      2, Mình có sử dung ckeditor để soạn thảo nội dung, khi mình nhấn vào Create chỉ sử dung modal của bootstrap thì nó vẫn hoạt động mình thường.
      https://drive.google.com/open?id=0B6G5C9uGw7e3WFB5dTZzNW96Mlk&authuser=0
      Nhưng khi mình truyền dữ lieu qua modal theo cách của bạn thì khung soạn thảo ckeditor không hoạt động nữa mà chỉ hiển thị một textarea đơn thuần
      https://drive.google.com/open?id=0B6G5C9uGw7e3NkRFaVRleGdVTm8&authuser=0
      Không biết bạn có các nào khắc phục không?

      Delete
    2. Tất cả những vấn đề trên mình có thể đoán (khoảng 50% là đúng) là do nguyên nhân sau: khi load model, bạn đang load bằng javascript và sử dụng jquery, tức là cần thư viện jquery để chạy. Trong khi đó trang _Layout bạn lại đặt Render jquery ở cuối trang, tức là cái chỗ load model đó chưa có jquery để chạy nên nó sẽ bị lỗi, cả cái ckeditor cũng vậy. Cách khắc phục đơn giản nhất là ra trang _Layout, copy cái render jquery lên đặt ở thẻ header là xong.
      ---
      Nếu không được thì mở Console (F12) ra xem thử lỗi gì và khắc phục thôi :v

      Delete
    3. Cái thứ nhất mình đã khắc phục được rồi, còn cái thứ 2 đã làm như bạn mà vẫn không được. Mình cũng ko hiểu tại sao nữa vì không thấy báo lỗi gì :3

      Delete
    4. Nếu viết js trong Modal bạn không được viết trong @section scripts mà phải viết thẳng trong thẻ script luôn

      Delete
  3. Thanks bạn nhiều, mình đã áp dụng thành công !

    ReplyDelete
  4. Trong trường hợp mình muốn valid dữ liệu thì sao bạn ? vd: nếu ko nhập name thì hiển thị thông báo lỗi trên popup dc ko bạn ?

    ReplyDelete
    Replies
    1. Tất nhiên là được nhưng chả ai làm vậy hết. Giả sử form của bạn có hàng chục field thì không nên show popup hàng chục lần.

      Để validate thì bạn có nhiều cách, sử dụng jquery validate, sử dụng bootstrap validator http://formvalidation.io/, hoặc là html5...Nói chung là hàng đống thứ.

      Mình sẽ cố gắng viết 1 bài validate data trong một ngày không xa =))

      Delete
  5. Bạn giúp mình với. Của mình chỉ load trang PartialView mà không load các layout và trang gốc khi click vào nút.

    ReplyDelete

Post a Comment

Popular posts from this blog

Gỡ bộ Visual Studio ra khỏi máy tính

Căn giữa thẻ div trong thẻ div