Wednesday, May 7, 2008

Simple ASP.NET MVC jquery ajax call

One of the coolest features of ASP.NET MVC is seeing html again and being able to manipulate it in ways that the php folks have been doing for years.

I have been guilty of forgetting that javascript and html are the key components to an ajax call and been using ajax.net instead of digging into the heart of the XMLHttpRequest Object. Fortunately a number of javascript libraries that help ease the creation of a real javascript ajax call. For this example I will be using jquery, though it is important to note that this same technique will work with any of the other javascript helper libraries available that include ajax capabilities. If you feel especially hands-on you can try this sample with the classic javascript code.

For this example you will need jquery, JSON.NET, and ASP.NET MVC Preview 3

Step 1 : HTML



<html>
<head>
<title>Sitemap Manager</title>
<script src="../../Scripts/jquery-1.2.3.js" type="text/javascript"></script>
<script type="text/javascript" src="../../Scripts/EditTree.js"></script>
</head>
<div id="tree">
<ul id='browser' class='filetree'>
<li id='2'><span class="folder" onclick='javascript:getNodeDetails(2)'>Home</span></li>
<li id='3'><span class="folder" onclick='javascript:getNodeDetails(3)'>Recordings</span></li>
<li id='4'><span class="folder" onclick='javascript:getNodeDetails(4)'>Store Locations</span></li><ul>
</div>
<form id="NodeDetailsForm" action="SaveNode" method="post">
<fieldset>
<legend>Menu Link Details</legend>
<input type="hidden" name="hfSitemapId" id="hfSitemapId" />
<label for="txtMenuName">
MenuName</label>
<input type="text" name="txtMenuName" id="txtMenuName" />
<br />
<label for="txtHref">
LinkHref</label>
<input type="text" name="txtHref" id="txtHref" />
<br />
<input type="submit" value="submit" id="submit-button" name="submit-button" />
</fieldset>
</form>
</html>


The form tag could also be replaced with: <%=using(Html.Form("Sitemap", "SaveNode")){ %>

Step 2 : Javascript

I wanted to keep this first example as simple as possible to illustrate how easy it is to use jquery ajax instead of ajax.net. The $ operator is the heart of the jquery library, for a better explanation head over to the site and investigate, as there are numerous other articles written about this library. For this example I am going to refrain from using the $ operator everywhere because I don't want to intimidate the newcommers.


function getNodeDetails(id)
{
$.getJSON("NodeClicked?id="+id,
function(result){
document.getElementById('hfMenuID').value = result.MenuID;
document.getElementById("txtMenuName").value = result.MenuName;
document.getElementById('txtHref').value = result.LinkName;
});
}

getNodeDetails(id) calls $.getJSON will send a HttpGet command to the url specified. The controller class in asp.net mvc will attempt to find an action to match the url ("NodeClicked").

Once the result is recieved from the url the function(result) portion will be run, filling the html elements with appropriate values is fairly straight forward from here. Notice how clean and friendly javascript looks using json, it's identical to the C# code...

Step 3 : The Controller


public ActionResult NodeClicked()
{
string id = this.ReadFromRequest("id");

MerriweatherDataContext db = new MerriweatherDataContext();

var node = (from s in db.MenuLayouts
where s.MenuID == Convert.ToInt32(id)
select new { s.MenuName, s.LinkName }).First();

string json = JavaScriptConvert.SerializeObject(node);
Response.Write(json);
return null;
}

First I grab the "id" parameter from the querystring and return a custom select statement. I tried this example without the custom select statement and ended up with a "self referencing loop" error, so I strongly advice considering what data you need and returning only the relevant fields.

Next I use JSON.NET to serialize the the node object into a json string.

Instead of using RenderView(), I use Response.Write which allows the javascript function to interpret the json result.

I'm using MVC Preview 3 and as a result the controller action requires something to be returned, so I return null. If anyone knows of a more elegant solution I would love to hear the solution.

Finally the code I am sharing is part of a larger cms project that I am working on and hope to release as an open source project eventually...but really don't we have enough custom cms solutions out there already?

*Before anyone flames me the DataContext object should not be called from the controller but for the purpose of this example I'm ignoring that piece of logic.

13 comments:

Jordan said...

Nice tutorial!

You could exploit jQuery a little more, and tease out the Javascript from your HTML. Instead of adding inline onclick handlers to the list items, I'd do something like this:

$(function() {
$("#browser li").bind("click", function() {
$.getJSON("NodeClicked?id="+this.id,
function(result){
$("#hfMenuID").val(result.MenuID);
$("#txtMenuName").val(result.MenuName);
$("#txtHref").val(result.LinkName);
});
});
});

For those who—like me—need to work in VB.NET (it's what my workplace uses), I'd have written the controller action something like this:

Function NodeClicked(ByVal id As String) As JsonResult
Dim db As New MerriweatherDataContext()
Dim Node = (From s In db.MenuLayouts
Where s.MenuID = Convert.ToInt32(id)
Select s.MenuName, s.LinkName).FirstOrDefault()
Return Json(Node)
End Function

A couple of final observations. I always put my Javascript at the end of the document, as recommended by the Yahoo! Exceptional Performance Team, since they block parallel downloads while your browser waits to download them. Also consider using the minified, gzipped version of jQuery hosted by Google, since it's pretty tiny and there's a good chance that as usage increases, it will already be in a browser's cache.

(By the way, there's no way to indent my code properly using the tags allowed in these comments. Any ideas?)

Anonymous said...

To get started winning at an online casino the first thing that you need to do is find one that suits your needs. After all, if you do not have an internet casino that you can wager with, you will never be able to reach your goals in the end. In order to find a casino all you have to do is start your search online. This will allow you to find several options to choose from, and also research each one. In turn, you will never have any problems finding the one that will best match your needs.
[url=http://www.casinolesoleil.com]casino[/url] http://www.casinolesoleil.com casino Live-based allows you to interact with real casinos in real time. You can see, hear, and interact with live dealers and players. This works best with a high-speed internet connection.
[url=http://www.redlotuscasino.com]online casino[/url] http://www.redlotuscasino.com casino Remember, before you visit any sites like these, check your local laws. Make sure that gambling and online gambling are allowed in your area. Even in different areas that allow online gambling, the rules may differ, so be sure to check the laws and rules thoroughly. Also, read all the terms, conditions, and rules of an online casino before signing up. Thanks for reading this guide! [url=http://www.triumphcasino.com]casino[/url] http://www.triumphcasino.com casino http://www.affrewards.com [url=http://www.affrewards.com]casino affiliate program[/url] Bingo is a beautiful game of luck, which involves patience, rapid coordination between hearing and searching out the numbers and lots of fun. [url=http://www.bingokisses.com]bingo[/url] [url=http://www.bingoeuphoria.com]bingo[/url] bingo bingo http://www.bingokisses.com http://www.bingoeuphoria.com With online bingo your cards are randomly selected by the computer and you can play with a great number of cards sometimes as many as 100 or more. Ordinarily you will need no more than three or four cards. A display board or a caller will flash your bingo numbers and you will need to fill the pattern displayed to win the game. Some online games will have the computer automatically search and fill the numbers for you. Some people find this automation a kill-joy but some actually love the fact that all they have to do watch for the bingo flash!!!
http://www.casinolesoleil.com http://www.redlotuscasino.com http://www.triumphcasino.com http://www.bingokisses.com http://www.bingoeuphoria.com http://www.pulsebet.com http://www.affrewards.com http://www.thehighrollerclub.com
http://www.buyphentermine1.com [url=http://www.buyphentermine1.com]phentermine[/url] http://www.norxbuy.com buy phentermine

Anonymous said...

These online sports betting become widely patronized especially among the global masses. Since the globe contains a huge number of masses compared to the other two social statuses, the online sports betting is pouring a lot of money compared to Las Vegas - the betting capital of the world. [url=http://www.pulsebet.com/bg/]bet online[/url] [url=http://www.pulsebet.com/da/]bet online[/url] [url=http://www.pulsebet.com/de/]bet online[/url] [url=http://www.pulsebet.com/es]apuestas[/url] [url=http://www.pulsebet.com/fr/]jouer en ligne[/url] [url=http://www.pulsebet.com/gr]bet online[/url] [url=http://www.pulsebet.com/jp]bet online[/url] [url=http://www.pulsebet.com/nl]bet online[/url] [url=http://www.pulsebet.com/pl]bet online[/url] [url=http://www.pulsebet.com/pt]bet online[/url] [url=http://www.pulsebet.com/ro]bet online[/url] [url=http://www.pulsebet.com/ru]bet online[/url] [url=http://www.pulsebet.com/se]bet online[/url] [url=http://www.pulsebet.com/it]bet online[/url] [url=http://www.pulsebet.com/cn]bet online[/url] To get started, decide on a sport to bet on and an online sportsbook to place your wager. Selecting a wager venue used to be a very secretive mission and your betting options were limited to what an individual bookie, or book maker, was capable of covering. These limited choices resulted in odds stacked against the bettor and an apprehension when it came time for payouts. http://www.pulsebet.com/bg/ http://www.pulsebet.com/da/ http://www.pulsebet.com/de/ http://www.pulsebet.com/es/ http://www.pulsebet.com/fr/ http://www.pulsebet.com/gr/ http://www.pulsebet.com/jp/ http://www.pulsebet.com/nl/ http://www.pulsebet.com/pl/ http://www.pulsebet.com/pt/ http://www.pulsebet.com/ro/ http://www.pulsebet.com/ru/ http://www.pulsebet.com/se/ http://www.pulsebet.com/it/ http://www.pulsebet.com/cn/

Anonymous said...

order an counterfeit handbags to your friends I0PD0616

Anonymous said...

Hello to all, because I am genuinely keen of reading this webpage's post to be updated regularly. It consists of fastidious material.

My blog post ... Designskala.com

Anonymous said...

What's up i am kavin, its my first occasion to commenting anyplace, when i read this piece of writing i thought i could also make comment due to this good paragraph.

My blog - Http://Cheapwebhostingfirms.Com/Vexxhost-Reviews

Anonymous said...

Howdy just wanted to give you a brief heads up and let you know a few of the images aren't loading correctly. I'm not sure why but I think its a linking issue.
I've tried it in two different browsers and both show the same results.

Also visit my weblog free vps hosting minecraft server

Anonymous said...

What's up to all, it's truly a pleasant for me to pay a
visit this site, it includes helpful Information.

Here is my site ... host-monster Reviews

Anonymous said...

It's great that you took the time to write this, as it's a matter that is very important to me.

Is there any way I can get in touch with you? My name's Aida Wong and I'd love to discuss this in depth.


Here is my blog ... retro

Anonymous said...

Great site from that which I've seen already. My name's Maureen and I'm really glad to view your blog. In fact, I'd love to get in touch with you.
Will you make sure you drop me a e-mai?

Visit my blog post - schack

Anonymous said...

I couldn't refrain from commenting. Exceptionally well written!

Feel free to surf to my blog post: cloud hosting in fort lauderdale

Anonymous said...

The return period is actually allowed an array between a pair of weeks merely this article Search engines look for certain keywords that they would show in their results page

Anonymous said...

When one goes with a game that he does not infer, that is if you are allowed to spiel other types of games with the bonus. [url=http://www.bvfdpaydayloans.co.uk/]payday loans uk[/url] uk payday loans With over 130, players testament never get world-weary children, wish a Seven-spot Mavin Karate fist and catapult perform handstands - so all futures disputes over the TV remote restraint are settled in your favor. http://www.bvfdpaydayloans.co.uk/