Introduction
In this article, I will create a custom DataTable in MVC using Entity Framework and jQuery/AJAX. Although jQuery’s DataTable can be used easily, here I will do server-side pagination and searching.
Requirements
- Visual Studio (2015 or higher)
- MVC
- Entity Framework
- Jquery
- MSSQL 2008 / 2008+
Getting Started
First, we will create an ASP.NET Web Application.
- Open Visual Studio.
- Select "New Project".
- Select "ASP.NET Web Application".
- Check "Empty" template and MVC in Core References followed by a click on OK.
- Now that our project is created, we will install the Entity Framework in our project via NuGet Package installer. Right-click on the project and select "Manage NuGet Packages". Select the Browse tab and type "Entity" in the search box. Select "Install".
- After that, create a new folder as Context.
- Inside Models folder, create your database class as “employee”. Also, this will be our Table name in the database. The properties inside the employee class will be the columns of employee table.
- public class employee
- {
- [Key]
- public int emp_no { get; set; }
- public DateTime birth_date { get; set; }
- public string first_name { get; set; }
- public string last_name { get; set; }
- public string gender { get; set; }
- public DateTime hire_date { get; set; }
- }
- Now, in the context folder that we created previously, add a new class as “dbEmployee”. This will help to communicate with the database and perform CRUD for every mentioned class in it. Here, we will use only the employee class. If you want to use more tables, then you can add the other classes too.
- public class dbEmployee : DbContext
- {
- public DbSet<employee> emp { get; set; }
- }
- Download jQuery and add it inside the Scripts folder.
- Add the connection string in the web.config file as below.
- <connectionStrings>
- <add name="dbEmployee" connectionString="{source}" providerName="System.Data.SqlClient" />
- </connectionStrings>
- The connection name will be the same as the name of the class that we added inside the Context folder. Here, we have added the dbEmployee class, so our name will be the same as that.
- Inside Models folder, create a class as “FilterEmployee”. This class will be used for getting the search keys and values.
- public class FIlterEmployee
- {
- public string emp_no { get; set; } = "";
- public string first_name { get; set; }
- public string last_name { get; set; }
- public string gender { get; set; }
- }
- Create one more class inside Models folder “GridPagination”. This class will have the required data to make the datatable.
- public class GridPagination
- {
- public int CurrentPage { get; set; }
- public double TotalPage { get; set; }
- public int TotalData { get; set; }
- public List<employee> Data { get; set; }
- public int TakeCount { get; set; } = 10;
- public FilterEmployee filters { get; set; } = new FilterEmployee();
- }
- Now, we have got all the required models.
- Create a MVC 5 empty controller.
- First, we will create a common function for paging and searching which will return the GridPagination as below.
-
- public GridPagination FilterData(int? PageNumber, FilterEmployee filters)
- {
- GridPagination gridData = new GridPagination();
- double count = 0;
- try
- {
- using (dbEmployee db = new dbEmployee())
- {
-
- var empData = db.emp.ToList();
-
- gridData.CurrentPage = PageNumber.HasValue ? PageNumber.Value <= 0 ? 1 : PageNumber.Value : 1;
-
- gridData.Data = empData;
-
- gridData.filters = filters;
-
-
- if (!string.IsNullOrEmpty(filters.emp_no))
- {
- gridData.Data = gridData.Data.Where(x => x.emp_no.ToString().Contains(filters.emp_no.ToString())).ToList();
- }
-
-
- if (!string.IsNullOrEmpty(filters.first_name))
- {
- gridData.Data = gridData.Data.Where(x => x.first_name.ToLower().Contains(filters.first_name.ToLower())).ToList();
- }
-
-
- if (!string.IsNullOrEmpty(filters.last_name))
- {
- gridData.Data = gridData.Data.Where(x => x.last_name.ToLower().Contains(filters.last_name.ToLower())).ToList();
- }
-
-
- if (!string.IsNullOrEmpty(filters.gender))
- {
- gridData.Data = gridData.Data.Where(x => x.gender.ToLower().Contains(filters.gender.ToLower())).ToList();
- }
-
-
-
-
- gridData.TotalData = gridData.Data.Count();
-
-
- count = (double)gridData.TotalData / gridData.TakeCount;
- gridData.TotalPage = (int)Math.Ceiling(count);
-
-
-
- gridData.Data = gridData.Data.Skip((gridData.CurrentPage - 1) * gridData.TakeCount).Take(gridData.TakeCount).ToList();
- }
- }
- catch (Exception ex)
- {
- gridData = new GridPagination();
- }
-
- return gridData;
- }
- Now inside the Index controller, we will just pass the data to the View which we will get after calling the above function with Page number as 1 and no column filters.
-
- public ActionResult Index()
- {
-
- return View(FilterData(1, new FilterEmployee()));
- }
- The function will return the 1st page’s employe, i.e., 1 to 10 employees.
- Then, we will create an Index View to display the data.
- We will use GridPagination as our model in View as we are passing that model from the controller.
- @model CustomDataTable.Models.GridPagination
- @{
- ViewBag.Title = "Index";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <h2>Index</h2>
- We will create a Partial View “_EmployeeList” inside shared folder as this will make it easy to bind records while paginating and searching.
- Paste the below code inside the Partial View. Add the explanation in that.
- Now, we will render this partial view in our index page and pass the GridPagination model to the Partial View.
- @model CustomDataTable.Models.GridPagination
- @{
- ViewBag.Title = "Index";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <style>
- .panel-table .panel-footer .pagination {
- margin: 0;
- }
-
-
-
-
- .panel-table .panel-footer .col {
- line-height: 34px;
- height: 34px;
- }
-
- .active.page {
- background-color: blue;
- color: white;
- }
- </style>
- <div class="container" id="tbEmployee">
- @{ Html.RenderPartial("_EmployeeList", Model);}
- </div>
- Now, run your project and see the results.
- Now, for searching and pagination, we need to add some jQuery and call AJAX.
- Create a JavaScript “Paginate” under Scripts folder and paste the below code.
- var paginate = function () {
- var that = {};
- var emp = {};
- var TextBox = '';
- var PageNo = 1;
-
-
-
- var InitEvents = function () {
-
-
- $(document).on('click', '.filter-page', function () {
-
- PageNo = $(this).data('page');
- Pagination();
- });
-
-
-
- $(document).on('keyup', '.filter-text', function () {
-
-
- PageNo = 1;
-
- TextBox = $(this).attr('id');
- Pagination();
- })
- }
-
-
- var Pagination = function () {
-
-
-
- emp.emp_no = $('#emp_no').val();
- emp.first_name = $('#Firstname').val();
- emp.last_name = $('#Lastname').val();
- emp.gender = $('#Gender').val();
- $.ajax({
- type: "POST",
- url: "/Employee/PaginateData",
- data: { pageNo: PageNo, filter: emp },
- content: "application/json; charset=utf-8",
- dataType: "html",
- success: function (d) {
-
- $('#tbEmployee').html(d);
-
-
- if (TextBox != '' && TextBox != null) {
- $('#' + TextBox).focusToEnd();
- }
- },
- error: function (xhr, textStatus, errorThrown) {
-
- }
- });
- }
-
- that.init = function () {
-
- InitEvents();
- }
-
- return that;
- }();
-
-
-
- (function ($) {
- $.fn.focusToEnd = function () {
- return this.each(function () {
- var v = $(this).val();
- $(this).focus().val("").val(v);
- });
- };
- })(jQuery);
- In your index page, add this JS reference and add the below line.
- <script src="~/scripts/Paginate.js"></script>
- <script type="text/javascript">
- $(document).ready(function () {
-
- paginate.init();
- })
- </script>
- Now, we will add ActionResult method as "PaginateData" in our "EmployeeController" to accept the AJAX request and return the Filtered Data.
- [HttpPost]
- public ActionResult PaginateData(int pageNo, FilterEmployee filter)
- {
-
- return PartialView("_EmployeeList", FilterData(pageNo, filter));
- }
- That's it. Run the application and look at the results on button click and filter textbox search.