Blue Theme Orange Theme Green Theme Red Theme
 
Home | Forums | Videos | Photos | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
Search :       Advanced Search »
Home » Blogs Home » Blog Detail
Using MVCContrib Grid in a Web 2.0 World with jquery and AJAX
 by Mike Gold on Nov 07, 2008

In a web 2.0 world it is not enough to keep posting the entire page back rendered to the browser. Otherwise the whole screen blinks and it looks web 1.0 ish. The following blog describes a strategy of how you can create your own "components" and populate them on a part of the page through the controller.
Comments: 1 Views: 14780       Printable Version

Recently I had the challenge on a project to create a grid for my MVC ASP.NET web application that could sort and paginate on the page, but all population of the grid happened from the controller (server).  Also, the grid had to be updated asynchronously without rendering the rest of the page.

In the old ASP.NET world you could just use a GridView stuck inside an AJAX UpdatePanel control and it would work.  What exactly the UpdatePanel was doing (or the GridView for that matter) is pretty much a mystery to the developer, but for the most part it works.

In the MVC world you need to have a little bit more understanding of the web request/response and Ajax world in order to get this same thing to work.  Especially since there are not that many controls out for MVC yet.

An opensource codeplex group callled MVCContrib has created a set of useable controls (extensions) that can generate HTML from code.  One of these controls is the Grid control.  This grid control is so flexible (not to mention you have the source code), that if used creatively, you can get it to solve the problem I mentioned above.  That is, you can get the MVCContrib Grid control to populate in an "ajax manner" and do sorting and paging in-place.  Meanwhile, getting all of it's data by calling the controller.

The way to do this is to construct your MVC content page as you normally would and leave a blank div for the grid, let's id it as "order_grid"

<h1>Simple Grid</h1>

<div id="order_grid" >

</div>

 

Next we will create a separate 'component' page that holds the mvccontrib grid itself (called OrderGrid.aspx). I also added a pager from Suteki Extensions (the built in MVCContrib pager won't work here).

<div id="grid1">

<%

Html.Grid<Orders>("orders",

column => {

column.For(c => c.Text,

String.Format("<a id=\"col{0}\" href=\"javascript:Sort('{0}')\">Order</a>", "Text"));

column.For(c => c.CreateDate, "receive date");

column.For(c => c.CategoryID, "type");

column.For("Edit").Do(c => { %>

<td class="unProcessed" id=Process<%= c.ID %>><a href="javascript:Process(<%= c.ID %>)">Claim</a>

</td>

<%}); }

);

%>

<%= Html.Pager((IPagedList)ViewData["orders"])%>

</div>

Populating the Grid

First we will create a method in the controller to initially populate the order grid with orders on the OrderPage. 

 

public ActionResult GetOrderGrid(int? page)

{

if (page == null)

page = 0;

_currentPage = page;

DateTime date = new DateTime(2008, 08, 19);

var orderDB = new ordersDataContext();

var orders = orderDB .GetOrders("test");

int numOrders = (orders as IEnumerable<Order>).ToList().Count();

List<Order> orderList = (orders as IEnumerable<Order>).Skip((int)(30 * _currentPage)).Take(30).ToList();

IPagedList ordersOnPage = orderList.ToPagedList(_currentPage.GetValueOrDefault(), 30, numOrders);

ViewData["orders"] = ordersOnPage;

return View("OrderGrid");

}

This populates the ViewData needed to fill the grid with 30 orders, depending on what page we are in.  Notice that all the pagination logic is happening in the server and not the client.

Now we need a way to tell the OrderPage to populate the empty div tag by calling GetOrderGrid.  We also need to make sure that it only populate the div tag and doesn't rerender the screen.  This is accomplished through the magic of jquery which nicely raps ajax calls.  because this is the initial population of the grid, we want to make the call on the jquery ready method that automatically gets called when the page is finished rendering its response.

<script type="text/javascript" language="javascript">

$(document).ready(function() {

// Your code here

$.ajax({

type: "POST",

url: "/GridTest/GetOrderGrid",

success: function(msg) {

$("#order_grid").append(msg);

},

error: function(msg) {

debugger;

}

});

});

The ajax call will call GetOrderGrid in the controller, and upon success it will call the success callback.  The callback just appends the html generated by the GetOrderGrid call into the order_grid div directly in the DOM.

Sorting

In order to follow an ajax strategy, when a header column is pressed in the grid, we only want the grid to sort in-place, and we want the grid to do its sorting in the controller.  In order to do any ajax, we need to attach a javascript call to the link of our Order header instead of, for example, a url directly to the controller.  A url to the controller would render the whole page, and we don't want this behavior.

Looking back at the mvccontrib grid code we notice that the link is shown as follows

column.For(c => c.Text,

String.Format("<a id=\"col{0}\" href=\"javascript:Sort('{0}')\">Order</a>", "Text"));

The Text column has a link to call a javascript function called sort.

Here is what that function looks like in our OrderGrid:

function Sort(col) {

$.ajax({

type: "POST",

url: "/GridTest/Sort",

data: "columnName=" + col,

success: function(msg) {

$("#order_grid").html(msg);

},

error: function(msg) {

alert("Data Failed to Sort: " + msg);

}

});

}

 

Note the Sort method doesn't do any sorting, it simply calls the controller through an ajax call.  In the success callback it appends html returned by the controller into the div of the order grid.

Here is the Sort method of the controller:

public ActionResult Sort(string columnName)

{

if (columnName == null)

return View();

_currentColumn = columnName;

var orderDB = new ordersDataContext();

var orders= orderDB .GetOrdersSorted(_currentColumn);

int numOrders = (orders as IEnumerable<Order>).ToList().Count();

List<Order> orderList = (orders as IEnumerable<Order>).Skip((int)(30*_currentPage)).Take(30).ToList();

IPagedList ordersOnPage = orderList.ToPagedList(_currentPage.GetValueOrDefault(), 30, numOrders );

ViewData["orders"] = ordersOnPage; //.AsPagination(_currentPage ?? 1, 10);

return View("OrderGrid");

}

After sorting the orders in the database, it gets only the orders to be presented on the current page and returns it in the View call.  Using the MVCContrib grid, the View then renders the html with the sorted orders.

What do you say about this post? Post a comment here
*Title:
*Comment:
 

aman by aman monga On Nov 08, 2008
ttttttttttttttttt


 Blogger's Profile
Age: Not Available
Location:
Title: Consultant
Joined: Apr 07, 2005
Education: Masters Degree
 More Blogs from this Blogger
How To: Binding a Property to a Label Control in a Windows Form
Passing JSON into an ASP.NET MVC Controller
How to set a Request Header in a JQuery Ajax Call
Single Responsibility Principle in Serialization
How To: Getting files from Team Foundation Server from the Command Line
Porting from C# to Java
Using anonymous delegates with extensions to create your own LINQ extensions
How to add Padding to a Button inside a StackPanel in silverlight
Using a ValueConverter as a DataTemplateSelector in Silverlight
Using a ContainerBindingCollection in a Telerik RadTreeView in Silverlight
View all »
 Latest Blogs
Replace vs Stuff in sql server 2005
How to use Partition Operators in LINQ: part 1
Quantifiers Operators in LINQ
Most secure Password regular expession validator
Storing Arabic and Chinese fonts in SQL Server
Convert a string to Title Case in C#
Close PopupControlExtender using javascript
Some good MSI information and tools
XAML coding best practices
Top 10 WPF Performance Tips
View all »

 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Suggest an Idea  |  Media Kit
Current Version: 5.2010.8.14
 © 2010  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.