Pages

Thursday, May 24, 2012

GridView Selection and Postback using jQuery


Abstract: The following article demonstrates how to select a row in a GridView and execute a postback using jQuery.
GridView Selection and Postback using jQuery
 
Recently Suprotim Agarwal wrote a cool article on GridView UI Tips and Tricks using jQuery. In one of his examples, he demonstrated how to highlight a row in a GridView. I thought I would take Suprotim’s example one step further and demonstrate how to perform a postback once you have selected the row. 
Before we get started, if you’re not familiar with jQuery, Suprotim has also written an article on beginning jQuery called Using jQuery with ASP.NET - A Beginner's Guide. This example uses the latest version of jQuery which is 1.3.2 and can be downloaded here.
Okay Lets get started! Open Visual Studio 2008 and create a new Web Application. This example won’t hook into a database, but we will create a class to mock a table and retrieve data from it instead. Right click on the project and choose Add > Class. Name the class Employee. Open the Employee class and add the following code: 
C# 
public class Employee
{
      public int ID { getset; }
      public string GivenName { getset; }
      public string Surname { getset; }
      public string Department { getset; }
}
 VB.NET
 Public Class Employee
      Private privateID As Integer
      Public Property ID() As Integer
            Get
                  Return privateID
            End Get
            Set(ByVal value As Integer)
                  privateID = value
            End Set
      End Property
       Private privateGivenName As String
       Public Property GivenName() As String
             Get
                   Return privateGivenName
             End Get
             Set(ByVal value As String)
                   privateGivenName = value
             End Set
       End Property
       Private privateSurname As String
       Public Property Surname() As String
             Get
                   Return privateSurname
             End Get
             Set(ByVal value As String)
                   privateSurname = value
             End Set
       End Property
       Private privateDepartment As String
       Public Property Department() As String
             Get
                   Return privateDepartment
             End Get
             Set(ByVal value As String)
                   privateDepartment = value
             End Set
       End Property
End Class
 
The Employee class contains four properties. The ID property is going to the unique identifier, so this is what we’ll use to get the selection from the user. 
Open the Default.aspx page and the following code:
<asp:GridView ID="grdEmployee" runat="server" AutoGenerateColumns="false">
      <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:Image runat="server" ID="imgPeople"                                   ImageUrl="~/People_031.gif" />
                    <asp:Label CssClass="hideId" runat="server" ID="lblID" Text='<%# Eval("ID") %>' />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="GivenName" />
            <asp:BoundField DataField="Surname" />
            <asp:BoundField DataField="Department" />
      </Columns>
</asp:GridView>
The GridView has AutoGenerateColumns set to false. This is because we don’t want to display the ID field. I have created an ItemTemplate for this and am hiding it from the user by using a CSS class called hideId. This sets the display style to none. Instead of showing an empty table cell, an image will be displayed instead.
The next step is to create a collection of Employee objects and bind that to the GridViewcontrol. Open the Default.aspx.cs page and add the following code:
 
C#
 
protected void Page_Load(object sender, EventArgs e)
{
      if (!IsPostBack)
      {
                var names = new List<Employee>();
                names.Add(new Employee() { ID = 1, Surname = "sheridan", GivenName ="malcolm", Department = "sales" });
                names.Add(new Employee() { ID = 2, Surname = "sheridan", GivenName ="debby", Department = "it" });
                names.Add(new Employee() { ID = 3, Surname = "sheridan", GivenName ="livvy", Department = "real estate" });
                grdEmployee.DataSource = names;
                grdEmployee.DataBind();
      }
}
 
VB.NET
 
Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs)
      If (Not IsPostBack) Then
                        Dim names = New List(Of Employee)()
                        names.Add(New Employee() With {.ID = 1, .Surname = "sheridan", .GivenName = "malcolm", .Department = "sales"})
                        names.Add(New Employee() With {.ID = 2, .Surname = "sheridan", .GivenName = "debby", .Department = "it"})
                        names.Add(New Employee() With {.ID = 3, .Surname = "sheridan", .GivenName = "livvy", .Department = "real estate"})
                        grdEmployee.DataSource = names
                        grdEmployee.DataBind()
      End If
End Sub
 
Now we have data in the GridView, let’s add some JavaScript to highlight the row when the user moves their mouse and make the GridView execute a postback. Add the following code to the head of the Default.aspx page:
 
<script language="javascript" type="text/javascript" src="jquery-1.3.2.js"></script>
    <script type="text/javascript" language="javascript">
        $(document).ready(function() {
            $("tr").filter(function() {
                return $('td', this).length && !$('table', this).length
            })
            .click(function() {               
                __doPostBack('grdEmployee', $(this).find("span").text());
            })
            .mouseover(function() {
                $(this).css("cursor", "hand");
            })
            .css({ background: "ffffff" }).hover(
                function() { $(this).css({ background: "#C1DAD7" }); },
                function() { $(this).css({ background: "#ffffff" }); }
                );
        });
    </script>
 
The click event is handled by the .click method. This method takes a function as a parameter and runs the __doPostBack function which is an ASP.NET JavaScript function that is automatically rendered when you want to perform a postback. This is normally generated by controls that have AutoPostBack set to true. Because the GridView does not have an AutoPostBack property, the page will not render the __doPostBack function. To get this JavaScript rendered, you need to add the following into the page load event:
 
ClientScript.GetPostBackEventReference(new System.Web.UI.PostBackOptions(this));
 
This tells ASP.NET to render __doPostBack:
 
 function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
 __doPostBack will submit the form and accepts two parameters:
 
1.    eventTarget – the control submitting the data
2.    eventArgument – additional information
 
The JavaScript in this example executes when a user clicks the TR. It will raise the click event and run
__doPostBack and pass in the ID of the selected row. Remember the ID column is an ItemTemplate that
has a Label control hidden by CSS. ASP.NET Labels are rendered as span tags. The JavaScript will find the
text of the span tag and pass that into the function as the eventArgument.
In the page load event, we need to add some code that looks for our postback by looking into the
Request.Form collection. Add the following code to the page load event:
 
C#
 
if (!string.IsNullOrEmpty(Request.Form["__EVENTTARGET"]))
{
      if (Request.Form["__EVENTTARGET"] == "javaScriptEvent")
      {
            ProcessGridSelection(Request.Form["__EVENTARGUMENT"]);
      }
}
 
VB.NET
 
If (Not String.IsNullOrEmpty(Request.Form("__EVENTTARGET"))) Then
      If Request.Form("__EVENTTARGET") = "javaScriptEvent" Then
             ProcessGridSelection(Request.Form("__EVENTARGUMENT"))
      End If
End If
 
Now when the user clicks a row in the GridView, the ID of the row will be passed through as the __EVENTARGUMENT value. From there I have created a separate function called ProcessGridSelection which adds the ID to a session variable and redirects the user to a separate page and displays the selected ID:
 
C#
 
private void ProcessGridSelection(string p)
{
      Session["Selection"] = p;  
      Response.Redirect("~/SelectedRow.aspx");
}
 
VB.NET
 
Private Sub ProcessGridSelection(ByVal p As String)
      Session("Selection") = p
       Response.Redirect("~/SelectedRow.aspx")
End Sub
 
To finish this, add a new web form and name it SelectedRow.aspx. Add a Label to the page and add the following code in the page load event:
 
C#
 
protected void Page_Load(object sender, EventArgs e)
{
      if (Session["Selection"] != null)
      {
            lblSelectedRow.Text = "Selected ID is " + Session["Selection"]                as string;
      }            
}
 
VB.NET
 
Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs)
      If Session("Selection") IsNot Nothing Then
             lblSelectedRow.Text = "Selected ID is " & TryCast(Session("Selection"),String)
      End If
End Sub
 
We’re done! We have got a control that highlights where the user is in a GridView and allows them to click anywhere to post data. Allowing the user to make a selection from anywhere in the GridViewmakes your application more slick and professional in my opinion. The entire source code of this article can be downloaded from here

No comments:

Post a Comment