ASP.NET MVC with jQuery SuperLoad
The other day I wrote about the jQuery SuperLoad plugin but I couldn't offer any real working sample of an application using it. Today I'm here to rectify that and talk about the new sample code I've recently added to the project repository.

Adding products to your shopping cart

The application has a single page, which lists a few books that you can add to your shopping cart. The cart is initially empty and when we add items to it, both the cart item list and the total price (at the top of the page) get updated from a single Ajax call.

The client side

Here's sample of what each of the products' HTML looks like. They each are inside a div which's id contains the product's id.
<div id="product_8" class="product">
	<img src="../../Content/images/prod_8.jpg" align="left" />

	<div class="title">Product 8</div>
	<div class="prodPrice" >$8.88</div>
	Qty: <input type="text" size="2"  maxlength="3" 
				class="quantity" value="1"/>
	<input type="button" value="Add to cart" class="addButton" />
</div>
We just need to fire one Ajax call whenever one of those "Add to cart" buttons is clicked. Here's the code that does that.
$('.addButton').click(function() {
	var prod = $(this).parent('.product');
	var prodId = prod.attr('id').split('_')[1];
	var qty = prod.find('.quantity').val();

	$.superLoad({
		url: '/Shopping/AddItem',
		type: 'POST',
		data: { product: prodId, quantity: qty },
		success: function() { $('#empty').remove(); }
	});
	
});
As you can see, we are making a superLoad() call to the AddItem action in the ShoppingController. Since this is a data modification call, we chose to use an HTTP POST request. The posted data goes in the data option. To tidy up things, we delete the empty text from the cart (if it's still there) once the call completes successfully.

Multiple results from a single action

The challenge on the server side is to come up with a sustainable method of reusing existing actions and combine them in a single action result, formatted to SuperLoad's liking and returned to the browser. To address that issue the sample comes with an implementation of a composite action result class specifically built for the response format we are trying to create. That class is the SuperLoadResult, listed below.
public class SuperLoadResult : ActionResult
{
	public IEnumerable<SuperLoadAjaxContent> ContentItems { get; private set; }

	public SuperLoadResult(params SuperLoadAjaxContent[] contentItems)
	{
		ContentItems = new List<SuperLoadAjaxContent>();
		((List<SuperLoadAjaxContent>)ContentItems).AddRange(contentItems);
	}

	public override void ExecuteResult(ControllerContext context)
	{
		context.HttpContext.Response.ContentType = MediaTypeNames.Text.Html;

		context.HttpContext.Response.Write("<div class=\"ajax-response\">");
		foreach (var item in ContentItems)
		{
			context.HttpContext.Response.Write(
				string.Format("<div class=\"ajax-content\" title=\"{0} {1}\">",
			                  item.Command.CommandText, item.Selector));
			item.GetResult().ExecuteResult(context);
			context.HttpContext.Response.Write("</div>");
		}
		context.HttpContext.Response.Write( "</div>");
	}
}
I bet things will become clearer once I show it being used from the AddItem action. So here it goes.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddItem(int product, int quantity)
{
	var sku = GetProduct(product);
	var item = new CartItem(sku, quantity);
	var cart = GetCurrentCart();
	cart.Items.Add(item);

	//add all the separate action results that we want into 
	// a SuperLoad result, mapping each one to the right 
	// selector and update type.
	return new SuperLoadResult(
		new SuperLoadAjaxContent("#cartTotal", 
		                  SuperLoadCommand.Update, 
						  () => CartTotal(cart)),

		new SuperLoadAjaxContent("#cart", 
		                  SuperLoadCommand.Append, 
						  () => CartItem(item))
		);
}
That last parameter to the SuperLoadAjaxContent's constructor is what will be invoked to provide an ActionResult-derived object, which will be executed and injected in the right place of the combined response. If I needed to update more elements, I could simply pass more instances of SuperLoadAjaxContent to my SuperLoadResult. Both CartTotal and CartItem are regular action methods that return a partial view from an .ascx template. Here's how simple the CartItem action is.
public ActionResult CartItem(CartItem item)
{
	return PartialView("CartItem", item);
}
Again, the entire sample is available for browsing, forking, or downloading at the repository page.

Posted 08-23-2009 5:59 AM by sergiopereira
Filed under: , ,

[Advertisement]

Comments

DotNetShoutout wrote ASP.NET MVC with jQuery SuperLoad - Sergio Pereira - Devlicio.us
on 08-23-2009 9:11 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

progg.ru wrote Использование jQuery SuperLoad в ASP.NET MVC
on 08-23-2009 9:37 AM

Thank you for submitting this cool story - Trackback from progg.ru

DotNetKicks.com wrote ASP.NET MVC with jQuery SuperLoad
on 08-23-2009 12:46 PM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

9eFish wrote ASP.NET MVC with jQuery SuperLoad - Sergio Pereira - Devlicio.us
on 08-23-2009 8:57 PM

9efish.感谢你的文章 - Trackback from 9eFish

WebDevVote.com wrote ASP.NET MVC with jQuery SuperLoad
on 08-24-2009 7:13 AM

You are voted (great) - Trackback from WebDevVote.com

DotNetBurner - jQuery wrote ASP.NET MVC with jQuery SuperLoad - Sergio Pereira - Devlicio.us
on 08-24-2009 8:46 PM

DotNetBurner - burning hot .net content

Nvrnight@gmail.com wrote re: ASP.NET MVC with jQuery SuperLoad
on 11-03-2009 2:37 PM

You're pretty much my new hero.

Nimmi wrote re: ASP.NET MVC with jQuery SuperLoad
on 11-01-2012 9:00 PM

I followed steps given in the blog post here and no theme is apilepd just like that. I guess you missed to talk about JQuery binding like below, because my page works after adding below binding on document ready event in a JS file $(function() {$(  input:submit, a, button ,  .demo  ).button();$(  a ,  .demo  ).click(function() { return false; });});I may be wrong, however prefer to get it clarified by you once. Thanks!

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)