So I have been working with ASP.NET AJAX and the Toolkit for about a year and a half total - give or take a few months. Over this period I have played around with building a handful of AJAX controls ...
- YUI Style Glow Buttons
- Scrolling Ticker
- Trace Console
- Anti-Aliased Rounded Corners
- GridView Hover Extensions
... and I am generally happy with how each one of these turned out. However I have learned over time that a new control extender or script control is not always the right fit for the job.
Take the problem Mustafa was solving the other day ...
I have recently figured out that if there is a scrollbar’ed Panel control inside an UpdatePanel, it looses its scrollbar position after any type of partial postback within that UpdatePanel. There can be a GridView, a DIV container or another similar control instead of this Panel.
Mustafa generously provides a solution to the problem. He describes a technique he is using for hooking into the PageRequestManager's beginRequest and endRequest events to tuck away the scroll bar position before the partial page is reloaded. He then reapplies the scroll position after the panel has been refreshed. I look at the code he provides for this and I am thinking - Yep, that looks great. I want it.
And that is when I came across this bit of documentation ...
The one thing you should notice with the onPageLoading function is that I am maintaining the scroll position for all HTML elements that have the maintain-scroll class applied to them. To fetch these elements I am using a helper function called getElementsByClassName (taken from here) that scans the panel to find all of the elements that have this maintain-scroll class applied to them. This approach is different from the typical extender control that extends a single control that it knows the ID of.
So for my demo page, I have a DIV contained within an UpdatePanel with a fixed width/height, and have enough content that scroll bars are being applied. To let my component know that we want it to maintain the scroll position of this DIV across partial postbacks all we have to do is tag the DIV with the maintain-scroll class like so ...
And to get my majax.MaintainScrollPosition script loaded I let the ScriptManager on the page know about my scripts and it will take care of the rest (the reference to majax.js is the script that contains the getElementsByClassName function. I planned on putting other common scripts in this file as well).
These Path references are pointers to the location on the webserver where my scripts reside.
Is this a one-off Solution or is it something more General?
After creating the component that maintains the scroll position, I started wondering if this was a pattern that could be applied a little more broadly. One of the first Toolkit controls I created extended a GridView control and added a bunch of cool row and column hovering effects. And after I got it build just the way I wanted .Net 3.5 came out and I fell head over heals for the new ListView control. And while I could still use my original extender control, it would take a little more work (i.e. explicit calls to $create for each of the tables I want to apply the behaviors to). So I quick like moved my old TABLE hover behavior script into this new patter to see how it fit. So I ...
- After these TABLE's are located I use the $create function to apply my hover behavior to the control
- Add a reference to my script to the ScriptManager control
- Updated my GridView to include the tablehover CSS class
And the coolest part is that without any code changes I can render the same grid using the ListView control as well ...
And they both work exactly the same.
Finally, The Demo's
The demo page for this post contains 2 sections. The first one demonstrates how the majax.MaintainScrollPosition can be used to persist the scroll position of elements between async postbacks. You can move the scroll bar around, then click the post back button. This will cause the panel to refresh and because this panel has Mustafa's script tied to it - the original scroll position will be restored.
And the second demo shows how to use the majax.TableHover script with both the GridView and ListView controls. Just hover over any of the table's cells and you will see how it works.
And you can download the sample site here.
I am kind of impressed with how this is looking so far. I like that ...
- If I don't need to interact with the control from the server I don't need to go through the process of building a server side piece for the component
- I thought it was cool how I could easily apply the same behavior to both a GridView as well as an HTML table rendered by the ListView without changing a single line of code
- I can hook into the PageRequestManager and attach to the ASP.NET AJAX client side life cycle events from within the Component
All of that being said, I spent a total of 3 hours putting this together stream-of-consciousness style, so odds are that I am missing something huge or that none of this is really all that useful to anyone but me. Either way, leave a comment and let me know what you think.
That's it. Enjoy!