Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Alert / Confirm or Call any JavaScript Function on ASP.NET DataGrid Paging

3.69/5 (7 votes)
10 Dec 20052 min read 1   1.5K  
Did you know that you can call any JavaScript function or stop the user from moving to the next page when he clicks on the paging links in an ASP.NET DataGrid? Read on...

Introduction

Did you know that you can call any JavaScript function or stop the user from moving to the next page when he clicks on the paging links in an ASP.NET DataGrid? For your information, by default, the paging parts in an ASP.NET DataGrid are generated by the .NET framework and you don't have any control over it.

Problem

I was once having an editable grid and wanted to make sure that if a user changes the data, he is alerted about it if he tries to go out of the page without saving the change. I was able to put a boundary validation everywhere on the web page, but I wasn't getting how to put it on the DataGrid paging facility (it is not even controlled through the footer or header item-bound).

How I solved it

I realized that it could only be managed if I use a custom data grid control and manage the paging myself on its OnRender event, and this is what I have done to mitigate this problem.

Benefits

You can not only alert a user that he is navigating out of the page but also confirm for save changes if he hasn't saved the information while navigating to a different page.

Technical part

How I did it

I created my own custom DataGrid control and added an attribute BeforePagingCallJSFunction. You can pass any JavaScript function in this attribute or you can stop the navigation process to different page, by returning false.

C#
public class DataGridCustom : System.Web.UI.WebControls.DataGrid  
{ 
  ..
  public string BeforePagingCallJSFunction
  ..
  protected override void Render(HtmlTextWriter output)
  {      
    if ( AllowPaging == true && BeforePagingCallJSFunction != "" ) 
    {
     //Get the output string rendered.
     System.Text.StringBuilder sb = 
       new System.Text.StringBuilder();
     HtmlTextWriter writer = 
       new HtmlTextWriter(new System.IO.StringWriter(sb));
     base.Render(writer);

     //the output has been retrieved in the stringbuilder 
     //AND do the modification here      
     string datgridString = sb.ToString();    
         
     //Attach javascript to top pager      
     if ( this.PagerStyle.Position == PagerPosition.Top || 
       this.PagerStyle.Position == PagerPosition.TopAndBottom )
     {
      int firstRowPos = datgridString.IndexOf(@"</tr>");
      string firstpart = datgridString.Substring(0,firstRowPos);
      string secondpart = datgridString.Substring(firstRowPos);
      //Use Page.GetPostBackEventReference instead of __doPostBack
      firstpart = firstpart.Replace("href=\"javascript:__doPostBack(", 
                  ( "style='cursor:hand;text-decoration:underline;" + 
                  "color:blue' href1='javascript:void(0)'" + 
                  " onclick=\"javascript:" + 
                  beforePagingCallJSFunction + ";__doPostBack("));
      datgridString = firstpart + secondpart;
     }

     //Attach javascript to bottom pager      

     if ( this.PagerStyle.Position == PagerPosition.Bottom || 
       this.PagerStyle.Position== PagerPosition.TopAndBottom) 
     {
      int lastRowPos = datgridString.LastIndexOf("<tr");
      string firstpart = datgridString.Substring(0,lastRowPos);
      string secondpart = datgridString.Substring(lastRowPos);
      //Use Page.GetPostBackEventReference instead of __doPostBack
      secondpart = secondpart.Replace("href=\"javascript:__doPostBack(", 
                   ( "style='cursor:hand;text-decoration:underline;" + 
                   "color:blue' href1='javascript:void(0)' " + 
                   "onclick=\"javascript:" + 
                   beforePagingCallJSFunction + ";__doPostBack("));   
      datgridString = firstpart + secondpart;      
     }
    
     output.Write(datgridString.ToString());  
   }
   else
   {
    base.Render(output);
   }
  } 
}

How to use it

In ASPX, get the proper references, enable paging (AllowingPaging=true) and do it as follows:

  1. HTML
    <Tittle:DataGridCustom BeforePagingCallJSFunction = 
         "alert('You are navigating out of this page')"
    ..
    >
    <columns>
    </columns>
    </Tittle:DataGridCustom>
  2. HTML
    <!--You can even stop user moving to next page returning false.--!>
    
    <Tittle:DataGridCustom BeforePagingCallJSFunction = 
        "if ( !confirm('Are you sure you want to navigate?') ) return false"
    .. >
  3. HTML
    <!--You can even verify if modifed data has not been saved,--!>
    <!--calling other javascript function--!>
    
    <Tittle:DataGridCustom BeforePagingCallJSFunction = 
               "if ( !DataSaved() ) return false"
    ...>

Some Technical FAQs

  • Why did I replace "href" with "onclick"?

    It is because stopping the execution of the next JavaScript function is only possible through "onclick".

  • Is there any disadvantage when I use it?

    Yes, since I replaced "href" with "onclick", you can not focus on paging hyperlink through Tab.

  • Will this work in case I have paging on top, bottom or both?

    Yes.

Future

  1. You can even check which page number the user has clicked, by reading the innerText of the hyperlink and passing this to the JavaScript function called.
  2. You can replace the hard-coded __doPostBack with Page.GetPostBackEventReference in case it is changed in future.
  3. You can format or color the paging text the way you want.

Conclusion

Not necessarily every one will like it, but it is for developers who have ever tried implementing boundary handling in their web applications, because this is a place they never had control earlier while validating if the page content was saved or not, here they can now.

Please free to post your comments and feedback.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here