• Use jQuery Bootgrid with asp.net Gridview

    I’ve used Twitters Bootstrap template in several asp.net projects. I’m surprised that I had no large gridviews in these projects, but just when I needed one t3n has published an article containing information about jQuery Bootgrid.This plugin makes a grid much more convenient, so I set it up in my project and it works brillant.

    Here are the steps to be done to implement jQuery-Bootgrid into your existing asp:Gridview, so you should already have setup your gridview and data retrieval on your own. Once this is done, the following steps are necessary to use jQuery-Bootgrid. You will find the whole source code of WebForm1.aspx and Webform1.aspx.vb at the bottom of the article

    1. Add jQuery, Bootstrap and jquery-Bootgrid to your project. This contains several JavaScript-Files and Stylesheets.
      <!-- jQuery, http://jquery.com/ -->
         <script src="//code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script>
         <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js" type="text/javascript"></script>
         <!-- Bootstrap, http://getbootstrap.com/ -->
         <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
         <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
         <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"
             type="text/javascript"></script>
         <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.js"
             type="text/javascript"></script>
         <link rel="Stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.css" />
    2. Inform Bootgrid about the grid to be prepared. 2 Steps are necessary:
      1. Add data-toggle=”bootgrid” to your grid, and
      2. Activate Bootgrid on your gridview. Additionally I personally don’t like case-sensitivity so I turned it off, of course that’s up to you.

      <script type="text/javascript" language="javascript">
             $(function () {
                 $('#<%= MyGridview.ClientID %>').bootgrid({
                     caseSensitive: false
                 });
             });
      </script>
    3. Add data-grid-id for all columns. You could not add it right into your aspx because you would get an error message “Type ‘System.Web.UI.WebControls.BoundField’ does not have a public property named ‘data-column-id’.” Therefore you have to do this in the backend. Create a Handler for your Gridview.RowCreated and add the attributes to your header.
      Private Sub MyGridview_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridview.RowCreated
            If Not e Is Nothing Then
                If e.Row.RowType = DataControlRowType.Header Then
                    e.Row.Cells(0).Attributes.Add("data-column-id", "companyname")
                    e.Row.Cells(1).Attributes.Add("data-column-id", "customernumber")
                    e.Row.Cells(2).Attributes.Add("data-column-id", "creationdate")
                    e.Row.Cells(3).Attributes.Add("data-column-id", "search")
                End If
            End If
        End Sub
    4. Set up gridview to build also theader. By default, gridview creates a HTML-Table with only tbody. For Bootgrid it’s important to have also theader. To do this set the following attribute:
      Griview.HeaderRow.TableSection = TableRowSection.TableHeader

    Now you should be able to compile your application and it should work fine!

    Here are some more information which you might find useful once your grid works fine:

    How to sort numeric columns

    As you see, ‘CustomerNumber’ is a numeric column, but Bootgrid sorts it using string sorting, means e.g. ‘100’ is listed before ’70’. To change this behavior, you could simply set the data-converter to numeric in the backend: e.Row.Cells(1).Attributes.Add(“data-converter”, “numeric”)

    How to sort date columns

    Sorting date columns is a bit tricky, because you need to transfer the provided date into javascript date format for sorting and later on back to string for displaying. Of course Bootgrid does this for you, but you have to take care about the format.If you have a look at the example code below, column ‘CreationDate’ is provided as string, not as date column: row(“CreationDate”) = Today.AddMonths(-1).ToString(“yyyy-MM-dd”). This helps to ensure that the date is formatted in a way which javascript understands so it’s easier to write the converters. Of course you could use your own format and take care to update the converter accordingly. In my example I’ve created a new converter called ‘datetime’ with a very basic structure (For a better output you could of course use special libraries like moment.js). In the backend you need to set the datetime-converter for the correct column and make sure that the datevalues in the column are in a format which is understandable for your converter. Easiest way is of course to supply the values as string instead of date so you control the format in both backend and frontend accordingly.

     

    converters: {
                        datetime: {
                            from: function (value) { return new Date(value); },
                            to: function (value) {
                                var d = value.getDate();
                                var m = value.getMonth();
                                m += 1;  // JavaScript months are 0-11
                                var y = value.getFullYear();
                                return (d + "." + m + "." + y);
                            }
                        }
                    }

     Add a hyperlink column

    Sometimes you also need to have some hyperlink columns in your grid. As Bootgrid takes over the control of your grid, Hyperlinks defined in your gridview would not work anymore. But Bootgrid has a feature for it: Formatters. You could define formatters on your own. In my example code I have a column ‘Search’ (which is not sortable) linking to Bing to search for the companyname. In your formatter you could reference all values from the current row, e.g. see row.search: The data-column-id ‘search’ is defined in backend and then used in the formatter.

    formatters: {
                       "link": function (column, row) {
                           return "<a href=\"http://www.bing.com/search?q=" + row.search + "\">" + column.id + ": " + row.companyname + "</a>";
                       }
                   }

     

    The complete source code

    Here is WebForm1.aspx and WebForm1.aspx.vb. It’s all set up to have a master page ‘Site1.Master’ which is the default created by Visual Studio, no changes there.

     

    Webform1.aspx

    <%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site1.Master"
        CodeBehind="WebForm1.aspx.vb" Inherits="WebApplication1.WebForm1" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
        <!-- jQuery, http://jquery.com/ -->
        <script src="//code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script>
        <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js" type="text/javascript"></script>
        <!-- Bootstrap, http://getbootstrap.com/ -->
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"
            type="text/javascript"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.js"
            type="text/javascript"></script>
        <link rel="Stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.css" />
        <script type="text/javascript" language="javascript">
            $(function () {
                $('#<%= MyGridview.ClientID %>').bootgrid({
                    caseSensitive: false,
                    formatters: {
                        "link": function (column, row) {
                            return "<a href=\"http://www.bing.com/search?q=" + row.search + "\">" + column.id + ": " + row.companyname + "</a>";
                        }
                    },
                    converters: {
                        datetime: {
                            from: function (value) { return new Date(value); },
                            to: function (value) {
                                var d = value.getDate();
                                var m = value.getMonth();
                                m += 1;  // JavaScript months are 0-11
                                var y = value.getFullYear();
                                return (d + "." + m + "." + y);
                            }
                        }
                    }
                });
            });
                </script>
    </asp:Content>
    <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
        <asp:GridView ID="MyGridview" runat="server" AutoGenerateColumns="false" CssClass="table table-bordered"
            data-toggle="bootgrid">
            <Columns>
                <asp:BoundField HeaderText="Company" DataField="CompanyName" />
                <asp:BoundField HeaderText="Customer Number" DataField="CustomerNumber" />
                <asp:BoundField HeaderText="Creation Date" DataField="CreationDate" />
                <asp:BoundField HeaderText="Search Bing" DataField="Search" />
            </Columns>
        </asp:GridView>
    </asp:Content>

    Webform1.aspx.vb

    Public Class WebForm1
        Inherits System.Web.UI.Page
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not Page.IsPostBack Then
                With MyGridview
                    .DataSource = GetDatatable()
                    .DataBind()
                    .HeaderRow.TableSection = TableRowSection.TableHeader
                End With
            End If
        End Sub
        Private Function GetDatatable() As DataTable
            Dim dt As New DataTable
            dt.Columns.Add("CompanyName")
            dt.Columns.Add("CustomerNumber")
            dt.Columns.Add("CreationDate")
            dt.Columns.Add("Search")
            Dim row As DataRow
            row = dt.NewRow
            row("CompanyName") = "Company abc"
            row("CustomerNumber") = 100
            row("CreationDate") = Today.AddMonths(-1).ToString("yyyy-MM-dd")
            row("Search") = "abc"
            dt.Rows.Add(row)
            row = dt.NewRow
            row("CompanyName") = "Company def"
            row("CustomerNumber") = 1001
            row("CreationDate") = Today.AddDays(-15).ToString("yyyy-MM-dd")
            row("Search") = "def"
            dt.Rows.Add(row)
            row = dt.NewRow
            row("CompanyName") = "company ghi"
            row("CustomerNumber") = 70
            row("CreationDate") = Today.AddDays(-25).ToString("yyyy-MM-dd")
            row("Search") = "ghi"
            dt.Rows.Add(row)
            row = dt.NewRow
            row("CompanyName") = "cOmPaNy jkl"
            row("CustomerNumber") = 345
            row("CreationDate") = Today.AddDays(-5).ToString("yyyy-MM-dd")
            row("Search") = "jkl"
            dt.Rows.Add(row)
            Return dt
        End Function
        Private Sub MyGridview_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridview.RowCreated
            If Not e Is Nothing Then
                If e.Row.RowType = DataControlRowType.Header Then
                    e.Row.Cells(0).Attributes.Add("data-column-id", "companyname")
                    e.Row.Cells(1).Attributes.Add("data-column-id", "customernumber")
                    e.Row.Cells(1).Attributes.Add("data-converter", "numeric")
                    e.Row.Cells(1).Attributes.Add("data-align", "right")
                    e.Row.Cells(2).Attributes.Add("data-column-id", "creationdate")
                    e.Row.Cells(2).Attributes.Add("data-converter", "datetime")
                    e.Row.Cells(3).Attributes.Add("data-column-id", "search")
                    e.Row.Cells(3).Attributes.Add("data-sortable", "false")
                    e.Row.Cells(3).Attributes.Add("data-formatter", "link")
                End If
            End If
        End Sub
    End Class

    Site1.Master

    <%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site1.master.vb" Inherits="WebApplication1.Site1" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <head runat="server">
        <title></title>
        <asp:ContentPlaceHolder ID="head" runat="server">
        </asp:ContentPlaceHolder>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            
            </asp:ContentPlaceHolder>
        </div>
        </form>
    </body>
    </html>

Leave a comment

If you want to share your opinion, leave a comment.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>