Friday, January 9, 2009

Smart Page Scroll after Postback

For a long extended page, it is devastating that you need to scroll the mouse to the location where you are working after each time of a postback. Here, I am going to discuss a solution with javascript features.

Window.ScrollTo(xpos, ypos) is a useful function, we can easily scroll a page to a exact location. However it brings another issue - we need to determine the pixel coordinates, which is usually not gotten for free.

Using scrollIntoView(alignment) method is more practical by scrolling to a specified control. Every html control has this method. The parameter "alignment" indicates top-top or bottom-bottom alignment condition that affect the exact location scrolled to.

List 1 shows a method to be used in an asp.net page or user control class.

[list 1]
/// <summary>
/// Scroll the page to a location where given control is visible
/// </summary>
/// <param name="ctrlClientId">control's client id</param>
private void ScrollToControl(string ctrlClientId)
{
string jsScript = "<SCRIPT language=\"javascript\"> document.getElementById('" + ctrlClientId + "').focus(); document.getElementById('"
+ ctrlClientId + "').scrollIntoView(true) </SCRIPT>";

Page.RegisterStartupScript("controlFocus", jsScript);

}

To call the method, we only need to pass in a web control's client id (list 2).

[list 2]
this.ScrollToControl(this.trColumns.ClientID);

Instead of being placed in a page or user control, this method can be placed in a common place so as to make it shared across whole application. Among tons of options, it can find a niche in Global class (list 3).

// in Global.asax.cs:
public class Global : System.Web.HttpApplication
{
// insert static SetFocus method here, just below the class Global declaration:
public static void SetFocus(System.Web.UI.Page webPage)
{
string[] pbCtrl = webPage.Page.Request.Form.GetValues("__EVENTTARGET");
if (pbCtrl != null && pbCtrl.Length > 0)
{
string ctrlId;
ctrlId = pbCtrl[0];
System.Web.UI.Control ctrlFound = webPage.Page.FindControl(ctrlId);
if ((ctrlFound != null) &&
(
ctrlFound is System.Web.UI.WebControls.DropDownList ||
ctrlFound is System.Web.UI.WebControls.TextBox ||
ctrlFound is System.Web.UI.WebControls.RadioButton ||
ctrlFound is System.Web.UI.WebControls.RadioButtonList))
{
string ctrlClientId;
ctrlClientId = ctrlFound.ClientID;
string strScript;
strScript = "<SCRIPT language=\"javascript\"> document.getElementById('" + ctrlClientId + "').focus(); document.getElementById('"
+ ctrlClientId + "').scrollIntoView(true) </SCRIPT>";
webPage.Page.RegisterStartupScript("controlFocus",strScript );
}
}
}

// In your Page_Load handler for (any page:
private void Page_Load(object sender, System.EventArgs e)
{
// insert this conditional call to the SetFocus Method:
if(IsPostBack) Global.SetFocus(this);
}

No comments: