Coding Horror

programming and human factors

The Antidote to ASP.NET Smart Navigation, Part Deux

In The Antidote to ASP.NET Smart Navigation, I mentioned an article that contained a clever solution to the scrolling problem with long ASP.NET forms and postbacks. Well, I recently located an even better version of that solution from Scott Mitchell, aka the founder of 4GuysFromRolla. I refactored it a bit into this:

  
''' <summary>
''' automatically preserves postback scroll position
''' </summary>
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender  
RegisterHiddenField("scrollLeft", Convert.ToString(Request.Form("scrollLeft")))  
RegisterHiddenField("scrollTop", Convert.ToString(Request.Form("scrollTop")))  
Dim sb As New System.Text.StringBuilder(1000)  
Dim nl As String = Environment.NewLine  
With sb  
.Append("<script language = ""javascript"">")
.Append(String.Concat(nl, "<!--", nl))
.Append("function SmartScroller_GetCoords() {")
.Append(String.Concat(nl, "var scrollX, scrollY;", nl))
.Append("if (document.all) {")
.Append(String.Concat(nl, "if (!document.documentElement.scrollLeft)", nl))
.Append("scrollX = document.body.scrollLeft;")
.Append(String.Concat(nl, "else", nl))
.Append("scrollX = document.documentElement.scrollLeft;")
.Append(String.Concat(nl, "if (!document.documentElement.scrollTop)", nl))
.Append("scrollY = document.body.scrollTop;")
.Append(String.Concat(nl, "else", nl))
.Append("scrollY = document.documentElement.scrollTop; }")
.Append(String.Concat(nl, "else {", nl))
.Append("scrollX = window.pageXOffset; scrollY = window.pageYOffset; }")
.Append(String.Concat(nl, nl))
.Append("document.getElementById('scrollLeft').value = scrollX;")
.Append(nl)
.Append("document.getElementById('scrollTop').value = scrollY;")
.Append(String.Concat(nl, "}", nl))
.Append(String.Concat(nl, "function SmartScroller_Scroll() {", nl))
.Append("var x = document.getElementById('scrollLeft').value;")
.Append(String.Concat(nl, "var y = document.getElementById('scrollTop').value;", nl))
.Append("window.scrollTo(x, y); }")
.Append(String.Concat(nl, nl, "window.onload = SmartScroller_Scroll;"))
.Append(String.Concat(nl, "window.onscroll = SmartScroller_GetCoords;", nl))
.Append("window.onclick = SmartScroller_GetCoords; window.onkeypress = SmartScroller_GetCoords;")
.Append(String.Concat(nl, "// -->", nl))
.Append("</script>")
End With  
RegisterClientScriptBlock("scrollCode", sb.ToString)  
End Sub  

Works great! Of course, you can insert this script any number of ways: in an inherited base page, as a server control, or by directly inserting it into a single page.

Written by Jeff Atwood

Indoor enthusiast. Co-founder of Stack Exchange and Discourse. Disclaimer: I have no idea what I'm talking about. Find me here: http://twitter.com/codinghorror