A Slider DataPager with Dynamic Tooltips
A few weeks ago I wrote a post explaining how the AjaxControlToolkit's Slider control could be used as a data pager. One of the teams I am currently working with has adopted this approach and is implementing it throughout their site. While this technique seems to work well, one feature the team would like to add is a custom tooltip that not only displays the typical paging statistics (i.e. page X of Y), but also gives the user a hint as to what can be found on each page of data.
It's this last bit of information that increases the value of the tooltip. Not only are we showing the user the typical paging statistics, but now they can get an idea of what data can be found on the page before actually navigating to it. Below is a screen shot of how this looks.
Live Demo (IE6, IE7 and FF) | Download (.Net 3.5 and toolkit version 3.5.11119.0)
We are still in the prototype stage with this sample, but I thought I would provide a quick explanation of how we have approached this problem and a few of the challenges we encountered along the way.
Displaying the Tooltip
The easiest way to have the Slider display a tooltip is to use the it's Tooltip property. The Slider's client side behavior translates the tooltip's text into the alt attribute of the Slider's handle image. Most browsers display the image's alt text when the image is moused over. This is what I used in my original example, but it isn't quite flexible enough for this scenario. I want full control over how the tooltip is rendered, so I decided it would be best to display the tooltip with a PopupControl.
So I added a Panel control to my PagerTemplate that contains the popup for my tooltip. When I determine what the tooltip needs to display, I will add the text I want displayed to the body and footer elements.
Generating the Tooltip
Now that I have the pieces in place to display my tooltip, I need to write the code that is able to figure out what information tooltip should display for each of the pages. To do this I decided to implement a PageMethod that accepts the page index as a parameter and returns the information that is needed to construct the tooltip.
Once the data for the tooltip has been gathered and returned to the client, I format the data, add it to the popup and display it.
Prefetching and Caching the Tooltip
Because the tooltip needs to be displayed immediately, I played around with prefetching to try to ensure the tooltip will be available as the user interacts with the Slider. I have a bit of JavaScript that does this at two separate times. First, when the page loads on the client, I prefetch the tooltips for the first three pages of data. Then, every time the Slider value changes, I again prefetch the tooltips for the next two pages of data. Once the tooltip has been retrieved from the server, I keep a local copy of it to avoid unnecessary round trips. Here is the JavaScript that runs as the Slider's value is changed.
Conclusion
Like I said, as far as the implementation goes, this sample hasn't quite made it out of the prototype stage. I know we are going to provide this type of functionality, but we still have to iron out a few more details ...
- What strategy would work best for fetching the tooltips?
- Use PageMethods to fetch the tooltips one at a time (this is what I have done above)
- Use PageMethods to fetch a batch of tooltips
- Generate the tooltips and send them along when the page is first requested
- Some other approach or a combination of the above approaches?
- Ideally, the tooltip should display a preview of the column that data is sorted by. In my sample, the grid doesn't support sorting so it isn't an issue. But, I will have to come back to this.
That's it. Enjoy!
Comments
Matt,
Using slider as a data pager finally makes sense to me with this tooltip utility.
Did you have a chance to test the first and third strategies (for tooltip fetching) as a performance base?
Hey Matt,
Have you looked at adding a marker to the slider line to also indicate where the intervals are?
Great post.
G
Matt, youre my new hero...
ScottGu mentioned you the other day on his blog and shouted, "WooHoo, props where props are due!"
Keep up the great work, loving it!
RA
Matt,
I continue to be impressed with the work you show here. Another thing for the tooltip that might be nice to have is to incorporate it into the First-Prev-Next-Last buttons as well. Normally I would think thats extra information already present elsewhere, but since youre including data that can be found on those pages, I can see the desirability.
Thanks again for all you do here.
Adam
@Mustafa -
I agree. The slider works much better with this type of tooltip. I didnt get a chance to play around with the other 2 options. When/if I do, you can bet I will post about what I find.
@Geoff -
No I havent, but I think that would be pretty useful. I will put that on the todo list. Thanks for the suggestion.
@Ryan -
Thanks Ryan.
@Adam -
Good suggestion. I think that would be useful.
Matt,
A great article and a really smooth solution.
I am having a small problem borrowing your technique though...On my page I have various textboxes etc. that can be used to specify search criteria. Clicking on a button then posts back to populate the listview with the relevant data. If I then scroll through to e.g. page 20, then amend my search criteria and click the button again, the listview re-binds to the new data, but the slider (and indeed the current page for the listview) remain at 20, rather than resetting.
I have tried a few things but am not getting anywhere. Can you give me a pointer?
Thanks, and keep up the good work!
Matt,
Also, I have found that performance is not good at all when you have a considerable amount of data, e.g. a few hundred pages. This is because, if you slide to page 500 or so, the javascript goes to fetch all those pages for which the valueChanged event fires, which can be a lot!
I found a way around this by moving the calls to getPreview out into a separate function, which is called with setTimeout with a relatively short delay (200 milliseconds). The func then only calls getPreview if the slider has stayed still during that time, which increases performance without presenting the user with any serious delay.
I cant get the:
return new
{
FirstRowPreview = HttpUtility.HtmlEncode(firstRow["lname"].ToString()),
LastRowPreview = HttpUtility.HtmlEncode(lastRow["lname"].ToString()),
pageIndex = displayPageIndex,
totalPages = totalPages
};
Section to work at all. Compiler errors, and Ive never seen that syntax before. What could I be doing wrong?
Hi Matt,
really a good work..,
Can we use number slider instead of scrolling slider.
Like 1 2 3 4 5 and we click on 5th link and slider will moves to 6 7 8 9 10
Thanks in advance
Ricky