.NET Unplugged

June 29, 2009

ASP.NET MVC Grid – Part 2 – Paging

Filed under: ASP.NET MVC — Eric P @ 9:08 am

For Part 2 – I implemented server side paging.Mvc_Grid_WithPaging

You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part2

Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part2.zip

Implementation

To add server side paging to grid I made the following changes:

1. Add page navigational controls to the View. For this I used a simple “<< >>” approach. The HTML for this was pretty straight forward.

2. Add page size control. For this task I used a drop down populated using a function on CustomerController:

html was:

<%= Html.DropDownList("pageSize", CustomerController.PageSizeSelectList(), new { onchange = "onPageSizeChange()" })%> rows per page                  

and function on CustomerController

public static SelectList PageSizeSelectList()
{
	var pageSizes = new List {"1", "2", "5", "10", "100"};
	return new SelectList(pageSizes, "Value");
}

3. Add JS code to make paging navigation and page size operational

//Set hidden variable to go to next/prev/last/first page and submit the form
function goToPage(pageIndex) {
	$("#currentPage").val(pageIndex);
	$("#gridAction").val("CurrentPageChanged");

	submitForm();
}

//Set action performed in hidden variable. When PageSize changes - PageIndex needs to be
//reset to 1. This logic will go on the server side.
function onPageSizeChange(pageIndex) {
	$("#gridAction").val("PageSizeChanged");
	submitForm();
}                   

function submitForm() {
	var form = $("#grid").parents("form:first");
	form.submit();
}    

4. Update CustomerController to perform paging using LINQ.


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult List(int currentPage, int pageSize, string gridAction)
{
        //Do logic depending on what action was performed
	if (gridAction == "PageSizeChanged")
		currentPage = 1;

        //Check if there are no results.  In this case return empty list.
	IQueryable query = _customerService.GetQueryable();
	int totalRows = query.Count();
	if (totalRows==0)
		return View(new List());

	int totalPages = (int)Math.Ceiling((double)totalRows / (double)pageSize);
	if (totalPages != 1)
	{
		//use LINQ to perform paging
		query = query.Skip((currentPage - 1) * pageSize)
						.Take(pageSize);
	}

        //Update ViewData collection to display pager stats and pager controls
	UpdatePagerViewData(totalPages, totalRows, currentPage, pageSize);

	List customers = query.ToList();
	return View(customers);
}

5. Cleanup CSS and table structure. This part took majority of the time. At first I was thinking of just using CSS and Divs for pager, but after having some issues with getting navigational control positioned in the middle, I decided to go with a table approach. In the end I ended up using a combination of Divs and CSS.

Observations

  • Using ViewData to pass information from Controller to View is getting heavy. I am currently passing 5-10 variables just for the pager. I think it makes sense to create data structure GridModel/Grid to hold all the variables. This approach has the following advantages:
    1. Strong typing using “if (gridModel.IsFirstPage) then ” instead of “if (bool)ViewState(“IsFirstPage”)
    2. Can keep call CustomerController.List(…) clean by using “UpdateModel(gridModel);” instead of passing more and more arguments to CustomerController.List(…);
    3. Will be able to compartmentalize Pager and Sorter using object hierarchy. For ex. GridModel.Pager.PageIndex, GridModel.Sorter.SortField, etc…
  • Noticed something weird in CSS. Using CSS class like:

    #grid #pager #navButtons table tr td .disabled {
    			color: #C0C0C0;
    			text-align: center;
    		}
    

    does not work. But if I change it to:

    #grid #pager #navButtons  .disabled {
    			color: #C0C0C0;
    			text-align: center;
    		}
    

    it will work. I wonder if CSS selectors don’t allow for matching “id tag class”.

For Part 3

In upcoming part 3, I will implement server side sorting.

About these ads

1 Comment »

  1. If in case we want to use the view mentioned as _Grid as different name so how can it be implemented can you please mention. write now if i define _Grid to different name it is not working, i want multiple _Grid for just 1 controller for that i must have to take multiple viewes but if i specify a different name it is not working. Please give solution for that.

    Comment by stuti16 — March 15, 2010 @ 2:03 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: