Sunday, October 14, 2007 12:47 PM
As an IT Consultant with numerous number of projects that has to do with a lot of data which at the end of the day requires paging - I'm really tired of writing paging methods for every project. Therefore, on this nice beautiful Saturday I've decided that I'll knock out a paging control which I'll gladly call the Data Pager Control.
It's almost inevitable to get a project these days that doesn't require some kind of data management. The two major aspects of web development that takes the majority of my time are: UI and Data Access. I've taken upon myself to always use SubSonic for Data Access so that leaves UI - I've yet to see a faster way of building one! For those of you who don't know, SubSonic implements the ActiveRecord design pattern which is my favorite, so does Castle. Back to the topic, here are my basic requirements so far.
- Support for events
- Cascading stylesheet styling
- Self contain
- Support for first, previous, next and last
- Cause page postbacks
- Easy to setup and use
Note: I was a little choked on whether or not the Data Pager Control (DPC) should be aware of the actual data, anyway so far I see no reason why it should if I do find one down the road, I'll happily update the code.
private int firstPageIndex = 1;
private int pageSize = 10;
private int totalRecords;
private int totalPages;
private bool showFirstAndLast;
private bool showAlternativeText;
Due to the fact that I had to keep it really simple, I created a few properties that required. The firstPageIndex defaults to 1 and should always be 1, I don't see any other reason why it wouldn't be. The pageSize which defaults to 10 determines the amount of records to show per page and etc... The other properties are all commented if you need more details.
public event EventHandler PageIndexChanged;
This is the only event that is fired when any of the links are clicked, it means the page index was changed by one of the many ways that you can change the page index. You can add more events if you need to, such as first and last clicked or similar events.
private void PrepareForRender()
{
if (!IsReadyToRender()) return;
try
{
// Figure out how many pages we will have
totalPages = (totalRecords / pageSize);
// Add 1 if there is a remainder
if ((totalRecords % pageSize) > 0) totalPages++;
// Check System.Web.UI.Page and make sure
its in a server for with runat = server if (Page != null)
Page.VerifyRenderingInServerForm(this);
}
catch { isReadyToRender = false;
}
}
The PrepareForRender prepares the control for rendering by performing necessary calculations and more. If you need to do more number crunching, you should probably dump that in this method. It gets called right before the rendering of the table takes place.
private DropDownList GetPageIndexList(int start, int end)
{
DropDownList ddl = new DropDownList();
ddl.ID = DDLPageListName;
for (int i = start; i <= end; i++)
{
ddl.Items.Add(new ListItem(i.ToString(), i.ToString()));
if (i == CurrentPageIndex)
ddl.Items.FindByValue(i.ToString()).Selected = true;
}
// Fire postback event on selected index changed
ddl.Attributes.Add("onchange", Page.ClientScript.GetPostBackEventReference(this, null));
return ddl;
}
The above code was the most tricky part of the code! Determining which index to move to next from the click of any of the hyperlinks was pretty easy and straight forward, since I simply had to use the Page.ClientScript.GetPostBackClientHyperlink method to generate the __doPostBack script. However, it was a little trickier when it came to capturing the value of the drop down list which is the second parameter of that method, therefore,I resulted in using the Form.Params to get the value from it. Take a look at the RaisePostBackEvent method.
<raw:DataPager runat="server" ID="dataPager" />
protected void Page_Load(object sender, EventArgs e)
{
dataPager.TotalRecords = 99;
dataPager.PageSize = 10;
dataPager.ShowFirstAndLast = true;
dataPager.ShowAlternativeText = true;
dataPager.PageIndexChanged += new EventHandler(dataPager_PageIndexChanged);
}
void dataPager_PageIndexChanged(object sender, EventArgs e)
{
//1. Get data from Cache of Database with this new index and bind
Response.Write("Yeee haaaa - New Index:" + dataPager.CurrentPageIndex.ToString());
}
The above few lines of code is all that you need to get started with the Data Pager control. Off course I hard coded the current values. You should replace those values with the actual data numbers from your recordset - Implement some data caching and SQL Server 2005 paging and you are done!
The control can also be styled with the use of stylesheet, simply pass the css class name to the Data Pager. Here is a quick and dirty sheet, really? hmm looks like its just a single style!
<style type="text/css">
table.DataPager{ font-family: verdana, tahoma;
font-size:8pt;
padding: 0;
margin:0;
width:320px;
border: 3px solid #FFD880;
background-color:#FFF2BF;
}
</style>
Remember you have access to the actual parent table, so you can style every item within the control - let me know if you find any issues.
Download File