65.9K
CodeProject is changing. Read more.
Home

Row click event for DataGrid

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (3 votes)

Jan 18, 2007

CPOL

2 min read

viewsIcon

53710

A way to add server side events for a row of a DataGrid withouth using server controls.

Introduction

I was looking for some functionalities over the net for extending the DataGrid control to submit a page by clicking the row, without having any buttons or server controls used for submitting the page. Unfortunately, I could not find a simple way of doing this till found the article of ssjvackar. The problem with this article was that it was titled as related to the DataGrid control but actually, the code was written for the GridView control. I was hoping that the scenario will work and for the DataGrid, but there were some changes required. Here is the code (it is very simple and similar to the ssjvackar's code):

protected void DataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || 
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        e.Item.Attributes.Add("onmouseover", "this.style.cursor='hand'");
        e.Item.Attributes.Add("onclick", "javascript:__doPostBack" +
           "('" + e.Item.UniqueID , 'Select$" + e.Item.ItemIndex + "')");
    }
}

Issues

The first main issue is that this code works only if these statements are correct:

  • There is at least one server control that will postback the page. This statement is major, because if there is no such record, then the __doPostBack function will not be added on the page. If there is no server control, you must add the code above in your PageLoad event manually to be sure that the page and the DataGrid control will work correctly:
  • if (!this.Page.IsClientScriptBlockRegistered("DoPostBack"))
    {
    
        System.Text.StringBuilder scriptBuilder = new System.Text.StringBuilder();
        scriptBuilder.Append("<script type=\"text/javascript\">" + Environment.NewLine);
        scriptBuilder.Append("<!--" + Environment.NewLine);
        scriptBuilder.Append("var theForm = document.forms['form1'];" + 
                             Environment.NewLine);
        scriptBuilder.Append("if (!theForm) {" + Environment.NewLine);
        scriptBuilder.Append("    theForm = document.form1;" + Environment.NewLine);
        scriptBuilder.Append("}" + Environment.NewLine);
        scriptBuilder.Append("function __doPostBack(eventTarget, eventArgument) {" + 
                             Environment.NewLine);
        scriptBuilder.Append("    if (!theForm.onsubmit || " + 
                             "(theForm.onsubmit() != false)) {" + Environment.NewLine);
        scriptBuilder.Append("        theForm.__EVENTTARGET.value = eventTarget;" + 
                             Environment.NewLine);
        scriptBuilder.Append("        theForm.__EVENTARGUMENT.value = eventArgument;" + 
                             Environment.NewLine);
        scriptBuilder.Append("        theForm.submit();" + Environment.NewLine);
        scriptBuilder.Append("    }" + Environment.NewLine);
        scriptBuilder.Append("}" + Environment.NewLine);
        scriptBuilder.Append("// -->" + Environment.NewLine);
        scriptBuilder.Append("</script>" + Environment.NewLine);
    
        this.Page.RegisterStartupScript("DoPostBack", scriptBuilder.ToString());
    }
  • Related to the above statement, the hidden fields __EVENTTARGET and __EVENTARGUMENT must be on the page when the browser renders the page. To fix this problem, you will have to manually add these fields in the <form> tag like this:
  • <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
    <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />

Another issue is that using this code, the OnItemCommand event of the DataGrid will not fire. To fire this event, the code must be changed like this:

protected void DataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || 
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        e.Item.Attributes.Add("onmouseover", "this.style.cursor='hand'");
        e.Item.Attributes.Add("onclick", "javascript:__doPostBack" +
           "('" + e.Item.UniqueID + "$ctl00' , 'Select$" + e.Item.ItemIndex + "')");
    }
}

The above code has a problem: if the item of the DataGrid control has at least one server control, it will have the same UniqueID as e.Item.UniquID. This will not be a problem during development if you keep this in mind.