Header Ads

ASP.NET Webform: Buttons in Datatables Jquery plugin

Today tutorial is an extension of my earlier article on ASP.NET Webform: Datatables Jquery plugin Server Side Integration.
I have received multiple requests on how to incorporate buttons, links or any action in the datatables jquery plugin that is in correspondent with a particular row e.g. CRUD (Create, Read, Update, Delete) operations for instance.



In today's tutorial I will demonstrate the idea of using any kind of action within jquery base datatables plugin.

Following are some prerequisites before you proceed any further in this tutorial:

Prerequisites:  


1) Knowledge about classic ASP.NET webform.  
2) Knowledge about HTML.  
3) Knowledge about Javascript.
4) Knowledge about AJAX.
5) Knowledge about CSS.
6) Knowledge about Bootstrap.
7) Knowledge about C# programming.  
8) Knowledge about C# LINQ.  
9) Knowledge about JQuery.  
10) Knowledge about WebMethod attribute
11) Knowledge about Datatebles plugin

You can download the complete source code for this tutorial or you can follow the step by step discussion below. The sample code is developed in Microsoft Visual Studio 2015 Enterprise. I am using SalesOrderDetail table extract from Adventure Works Sample Database.

Since, I am extending my earlier article ASP.NET Webform: Datatables Jquery plugin Server Side Integration, so, I will not be covering the basics which is already being covered.

Download Now!

Let's begin now.

1) Create new Webform web application project and name it "JqDatatablesWebfoms".
2) Open "Default.aspx" page and replace following code in it:
 
<%@ Page Title="ASP.NET Webform: How to add button in JQuery DataTables Plugin" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JqDatatablesWebForm._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">

    <div class="row">
        <div class="panel-heading">
            <div class="col-md-10  custom-heading3">
                <h3>
                    <i class="fa fa-table"></i>
                    <span>ASP.NET Webform C#: How to add button in JQuery DataTables Plugin </span>
                </h3>
            </div>
        </div>
    </div>

    <div class="row">
        <section class="col-md-12 col-md-push-0">
            <section>
                <div class="well bs-component">
                    <br />

                    <div class="row">
                        <div>
                            <table class="table table-striped table-bordered table-hover"
                                    id="TableId"
                                    cellspacing="0"
                                    align="center"
                                    width="100%">
                                <thead>
                                    <tr>
                                        <th>Sr</th>
                                        <th>Order Track Number</th>
                                        <th>Quantity</th>
                                        <th>Product Name</th>
                                        <th>Special Offer</th>
                                        <th>Unit Price</th>
                                        <th>Unit Price Discount</th>

                                        <th></th>
                                    </tr>
                                </thead>
                            </table>
                        </div>
                    </div>
                </div>
            </section>
        </section>
    </div>

</asp:Content>

 Here, the only change is the new header column which will contain our action button within the datatables jquery plugin i.e.

<th></th>

3) Now, make changes into "SalesOrderDetail.cs" file by adding new property, replace below code in this file i.e.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JqDatatablesWebForm.Models
{
    public class SalesOrderDetail
    {
        public int Sr { get; set; }
        public string OrderTrackNumber { get; set; }
        public int Quantity { get; set; }
        public string ProductName { get; set; }
        public string SpecialOffer { get; set; }
        public double UnitPrice { get; set; }
        public double UnitPriceDiscount { get; set; }
        public string Action { get; set; }
    }
}

In the above code, we have simply add new property i.e. Action of type string.  

4) Now, replace following code in "Default.aspx.cs" file i.e.

using JqDatatablesWebForm.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace JqDatatablesWebForm
{
     public partial class _Default : Page
    {
        #region Page Load event

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                // Verification
                if (string.IsNullOrEmpty(this.Request.QueryString["id"]))
                {
                    // Info.
                    return;
                }

                // Initialization.
                string reqVal = this.Request.QueryString["id"];
                string regName = "Jfunc" + reqVal;
                string alert = "alert('Row ID = " + reqVal + "');";

                // Javascript Call.
                this.ClientScript.RegisterStartupScript(this.GetType(), regName, alert, true);
            }
            catch (Exception ex)
            {
                // info.
                Console.Write(ex);
            }
        }

        #endregion

        #region Get data method.

        /// <summary>
        /// GET: Default.aspx/GetData
        /// </summary>
        /// <returns>Return data</returns>
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
        public static object GetData()
        {
            // Initialization.
            DataTables result = new DataTables();

            try
            {
                // Initialization.
                string search = HttpContext.Current.Request.Params["search[value]"];
                string draw = HttpContext.Current.Request.Params["draw"];
                string order = HttpContext.Current.Request.Params["order[0][column]"];
                string orderDir = HttpContext.Current.Request.Params["order[0][dir]"];
                int startRec = Convert.ToInt32(HttpContext.Current.Request.Params["start"]);
                int pageSize = Convert.ToInt32(HttpContext.Current.Request.Params["length"]);

                // Loading.
                List<SalesOrderDetail> data = _Default.LoadData();

                // Total record count.
                int totalRecords = data.Count;

                // Verification.
                if (!string.IsNullOrEmpty(search) &&
                    !string.IsNullOrWhiteSpace(search))
                {
                    // Apply search
                    data = data.Where(p => p.Sr.ToString().ToLower().Contains(search.ToLower()) ||
                                           p.OrderTrackNumber.ToLower().Contains(search.ToLower()) ||
                                           p.Quantity.ToString().ToLower().Contains(search.ToLower()) ||
                                           p.ProductName.ToLower().Contains(search.ToLower()) ||
                                           p.SpecialOffer.ToLower().Contains(search.ToLower()) ||
                                           p.UnitPrice.ToString().ToLower().Contains(search.ToLower()) ||
                                           p.UnitPriceDiscount.ToString().ToLower().Contains(search.ToLower())).ToList();
                }

                // Sorting.
                data = _Default.SortByColumnWithOrder(order, orderDir, data);

                // Filter record count.
                int recFilter = data.Count;

                // Apply pagination.
                data = data.Skip(startRec).Take(pageSize).ToList();

                // Loading drop down lists.
                result.draw = Convert.ToInt32(draw);
                result.recordsTotal = totalRecords;
                result.recordsFiltered = recFilter;
                result.data = data;
            }
            catch (Exception ex)
            {
                // Info
                Console.Write(ex);
            }

            // Return info.
            return result;
        }

        #endregion

        #region Helpers

        #region Load Data

        /// <summary>
        /// Load data method.
        /// </summary>
        /// <returns>Returns - Data</returns>
        private static List<SalesOrderDetail> LoadData()
        {
            // Initialization.
            List<SalesOrderDetail> lst = new List<SalesOrderDetail>();

            try
            {
                // Initialization.
                string line = string.Empty;
                string srcFilePath = "content/files/SalesOrderDetail.txt";
                var rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
                var fullPath = Path.Combine(rootPath, srcFilePath);
                string filePath = new Uri(fullPath).LocalPath;
                StreamReader sr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read));

                // Read file.
                while ((line = sr.ReadLine()) != null)
                {
                    // Initialization.
                    SalesOrderDetail infoObj = new SalesOrderDetail();
                    string[] info = line.Split(',');

                    // Setting.
                    infoObj.Sr = Convert.ToInt32(info[0].ToString());
                    infoObj.OrderTrackNumber = info[1].ToString();
                    infoObj.Quantity = Convert.ToInt32(info[2].ToString());
                    infoObj.ProductName = info[3].ToString();
                    infoObj.SpecialOffer = info[4].ToString();
                    infoObj.UnitPrice = Convert.ToDouble(info[5].ToString());
                    infoObj.UnitPriceDiscount = Convert.ToDouble(info[6].ToString());

                    infoObj.Action = "<a class='btn btn-warning' href='Default.aspx?id=" + infoObj.Sr + "'>Click Me</a>";

                    // Adding.
                    lst.Add(infoObj);
                }

                // Closing.
                sr.Dispose();
                sr.Close();
            }
            catch (Exception ex)
            {
                // info.
                Console.Write(ex);
            }

            // info.
            return lst;
        }

        #endregion

        #region Sort by column with order method

        /// <summary>
        /// Sort by column with order method.
        /// </summary>
        /// <param name="order">Order parameter</param>
        /// <param name="orderDir">Order direction parameter</param>
        /// <param name="data">Data parameter</param>
        /// <returns>Returns - Data</returns>
        private static List<SalesOrderDetail> SortByColumnWithOrder(string order, string orderDir, List<SalesOrderDetail> data)
        {
            // Initialization.
            List<SalesOrderDetail> lst = new List<SalesOrderDetail>();

            try
            {
                // Sorting
                switch (order)
                {
                    case "0":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.Sr).ToList()
                                                                                                 : data.OrderBy(p => p.Sr).ToList();
                        break;

                    case "1":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.OrderTrackNumber).ToList()
                                                                                                 : data.OrderBy(p => p.OrderTrackNumber).ToList();
                        break;

                    case "2":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.Quantity).ToList()
                                                                                                 : data.OrderBy(p => p.Quantity).ToList();
                        break;

                    case "3":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.ProductName).ToList()
                                                                                                 : data.OrderBy(p => p.ProductName).ToList();
                        break;

                    case "4":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.SpecialOffer).ToList()
                                                                                                   : data.OrderBy(p => p.SpecialOffer).ToList();
                        break;

                    case "5":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.UnitPrice).ToList()
                                                                                                 : data.OrderBy(p => p.UnitPrice).ToList();
                        break;

                    case "6":
                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.UnitPriceDiscount).ToList()
                                                                                                 : data.OrderBy(p => p.UnitPriceDiscount).ToList();
                        break;

                    default:

                        // Setting.
                        lst = orderDir.Equals("DESC", StringComparison.CurrentCultureIgnoreCase) ? data.OrderByDescending(p => p.Sr).ToList()
                                                                                                 : data.OrderBy(p => p.Sr).ToList();
                        break;
                }
            }
            catch (Exception ex)
            {
                // info.
                Console.Write(ex);
            }

            // info.
            return lst;
        }

        #endregion

        #endregion
    }
}

The above piece of code simply loads data from text file into list and create a web method that is mapped to our datatables jquery plugin.

The important change as of extension to previous article ASP.NET Webform: Datatables Jquery plugin Server Side Integration is in Page_load(...) & LoadData(...) method i.e. in LoadData(...) method we have create an HTML link as string and map that value to our new action property i.e.

infoObj.Action = "<a class='btn btn-warning' href='Default.aspx?id=" + infoObj.Sr + "'>Click Me</a>";

And in Page_Load(...) method, we are simply retrieving the query string value which is row ID in our case i.e.


        #region Page Load event

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                // Verification
                if (string.IsNullOrEmpty(this.Request.QueryString["id"]))
                {
                    // Info.
                    return;
                }

                // Initialization.
                string reqVal = this.Request.QueryString["id"];
                string regName = "Jfunc" + reqVal;
                string alert = "alert('Row ID = " + reqVal + "');";

                // Javascript Call.
                this.ClientScript.RegisterStartupScript(this.GetType(), regName, alert, true);
            }
            catch (Exception ex)
            {
                // info.
                Console.Write(ex);
            }
        }

        #endregion
   
5) Now, replace following code in "custom-datatable.js" file i.e.


$(document).ready(function ()
{
    $('#TableId').DataTable(
    {
        "columnDefs": [
            { "width": "5%", "targets": [0] },
            { "width": "10%", "searchable": false, "orderable": false,  "targets": [7] },
            { "className": "text-center custom-middle-align", "targets": [0, 1, 2, 3, 4, 5, 6, 7] },
        ],
        "language":
            {
                "processing": "<div class='overlay custom-loader-background'><i class='fa fa-cog fa-spin custom-loader-color'></i></div>"
            },
        "processing": true,
        "serverSide": true,
        "ajax":
            {
                "url": "Default.aspx/GetData",
                "contentType": "application/json",
                "type": "GET",
                "dataType": "JSON",
                "data": function (d)
                {
                    return d;
                },
                "dataSrc": function (json)
                {
                    json.draw = json.d.draw;
                    json.recordsTotal = json.d.recordsTotal;
                    json.recordsFiltered = json.d.recordsFiltered;
                    json.data = json.d.data;

                    var return_data = json;
                    return return_data.data;
                }
            },
        "columns": [
                    { "data": "Sr" },
                    { "data": "OrderTrackNumber" },
                    { "data": "Quantity" },
                    { "data": "ProductName" },
                    { "data": "SpecialOffer" },
                    { "data": "UnitPrice" },
                    { "data": "UnitPriceDiscount" },
                    { "data": "Action" }
        ]
    });
});

In the above code, we have adjusted our jquery datatables plugin due to addition of new column and map the action property on our datatables jquery plugin.

6) Let, execute the project now and you will be able to see following i.e.


When you click any button in jquery datatables plugin, you will see below result i.e.


Conclusion

In this article, you will learn about adding any sort of button, link or action within jquery datatables which is in correspondent to a particular row in order to perform operations like CRUD (Create, Read, Update, Delete). This article is extension of ASP.NET Webform: Datatables Jquery plugin Server Side Integration, so, if anyone is interested he/she can look into that article for better understanding.

11 comments:

  1. Thanks for your help by posting content, when i try to add more columns to below example I am receiving tn7 error.Please Help

    https://www.asmak9.com/2017/07/aspnet-webform-buttons-in-datatables.html

    https://datatables.net/manual/tech-notes/7

    ReplyDelete
    Replies
    1. how are you adding the columns?

      Delete
    2. Please see below, added 5 empth th to html



      Ajax Call
      -------------------------------
      "columns": [
      { "data": "Sr" },
      { "data": "OrderTrackNumber" },
      { "data": "Quantity" },
      { "data": "ProductName" },
      { "data": "SpecialOffer" },
      { "data": "UnitPrice" },
      { "data": "UnitPriceDiscount" },
      { "data": "Action" },
      { "data": Null },
      { "data": Null },
      { "data": Null },
      { "data": Null }
      ]

      Delete
    3. Do you understand what are these values?

      Delete
  2. Yes, these values are returned from our webmethod(code behind), for now i wanted to display them as Null columns. But the real challenge is if you try to display more than 9 Columns in Datatable its erroring out. Please help me overcome this issue..

    ReplyDelete
    Replies
    1. This is where you are mistaking these are not values but object mapping properties of your Sales order object class. Since you are passing null the platform try to map null as object mapping property and get error. There is no limit on number of Columns do study datatables docs for more detail. Change null to some property.

      Delete
    2. Hi Asma, I have tried to map with a property but same error.Please find below link to the code i am using including screenshot

      http://s000.tinyupload.com/?file_id=07183580272347799064

      Delete
    3. Give me two days i'll look into your code and response back.

      Delete
    4. I have posted my answer at https://bit.ly/2x7iLse

      Delete
    5. Thanks Asma, that worked like a Charm. Previously I tried below setting which didn't resolve my issue..once again thanks for quick resolution.

      Delete
    6. requestLimits maxQueryString="32768"

      Delete