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
- 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> <!-- Bootgrid, http://jquery-bootgrid.com/ or https://github.com/rstaib/jquery-bootgrid --> <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" />
- 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>
- 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
- 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> <!-- Bootgrid, http://jquery-bootgrid.com/ or https://github.com/rstaib/jquery-bootgrid --> <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"> <html xmlns="http://www.w3.org/1999/xhtml"> <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>