Monday, December 07, 2009

jQuery AJAX with ASP.NET MVC

EDITED 12/8/2009 9:47PM

I’m in the process of re-building my wife’s photography website and she wanted to add a mailing list feature to the site. I didn’t want one of her users to have a page refresh on the page, so I wanted to make an AJAX call. So that’s the back story to why I started learning jQuery AJAX with ASP.NET MVC. I’m pretty new to MVC and the jQuery AJAX methods.

Here’s the setup:

On my ConnectController, I added a JoinMailingList action that looks like this:

 [AcceptVerbs(HttpVerbs.Post), ValidateModel(typeof(JoinMailingListForm)), ValidateAntiForgeryToken]
public string JoinMailingList(JoinMailingListForm form)
{
if (!ModelState.IsValid)
return "Invalid Email Address. Please press back or enable JavaScript.";

//Add to mailing list logic

return "Successfully subscribed.";
}


I will not get into the attributes other than to say the ValidateModel I got from the sample code for ASP.NET MVC in Action (GREAT BOOK) and the ValidateAntiForgeryToken I learned from a Phil Haack post.


My JoinMailingListForm looks like this:



using Castle.Components.Validator;

namespace UI.Models.Forms
{
public class JoinMailingListForm
{
[
ValidateNonEmpty(""), ValidateEmail("")]
public string EmailAddress { get; set; }
}
}

The validate attributes on the EmailAddress property are from the Castle.Components.Validator namespace.


My view control inherits from my BaseViewControl<T> class, which inherits from MvcContrib.FluentHtml.ModelViewUserControl<TModel> class. DO NOT forget to use this class if you want to take advantage of FluentHtml. I forgot this initially and it was really annoying.


Here is my ViewControl:


<%@ Control Language="C#" Inherits="UI.Helpers.ViewPage.BaseViewControl<JoinMailingListForm>" %>
<div id="joinmsg" style="display:none" class="validation-summary"></div>
<
form action="/Connect/JoinMailingList/" method="post" id="joinmailingform">
<
fieldset>
<
legend>Mailing List</legend>
<%=this.TextBox(f => f.EmailAddress)
.Label(
"Get discounts and more: ")
.Value(
"add email here")
.Attr(
"accesskey", "M")%>
<%
=Html.AntiForgeryToken() %>
<%
=Html.SubmitButton("join", "J") %>
</fieldset>
</
form>

As you can see, the control inherits from my BaseViewControl<TModel> and takes advantage of FluentHtml. I LOVE FluentHtml, I think it is very slick…I’ve grown to love all things fluent. The Html.SubmitButton is an extension method I added to the HtmlHelper.


Now for the jQuery AJAX call, which I decided to modify and take advantage of the jquery.form plugin from Mike Alsup:


<script language="javascript" type="text/javascript">
$(document).ready(
function() {
$('#joinmailingform').ajaxForm(function(data) {
if (data == 'Successfully subscribed.') {
$(
'input#EmailAddress').qtip({
content: 'Successfully subscribed.',
hide: { when:
'blur' },
show: { when:
false, ready: true, solo: true },
style: { name:
'blue', tip: true },
position: { corner: { target:
'topMiddle', tooltip: 'bottomMiddle'}}
});
} else {
$(
'input#EmailAddress').qtip({
content:
'Oops! Something went wrong.',
hide:
false,
show: { when:
false, ready: true, solo: true },
style: { name:
'red', tip: true },
position: { corner: { target:
'topMiddle', tooltip: 'bottomMiddle'}}
})
.addClass(
'input-validation-error');
}
});
});
</
script>

Basically, this is called as an action on my form and it calls the ConnectController and the JoinMailingList action. The .ajaxForm is part of the jquery.form plugin, which turns my form into an AJAX form. It handles the call for me and the real benefit to going this route is that even if JavaScript is disabled, my wife’s users can still subscribe to her mailing list. It’s not pretty without JavaScript, but it works. I’m now returning a string and displaying a message accordingly. I also went ahead and implemented qtip by Craig Thompson, which is all the .qtip({}) stuff. The qtip plugin is really sweet and has the look and feel that Amy wanted for her site.


That’s it! Pretty simple I thought and it was pretty fun to create. Please let me know if you see anything that I could improve or that I’m doing incorrectly. Thanks for reading!


Thank you Jon for the suggestion!

Shout it

kick it on DotNetKicks.com

blog comments powered by Disqus
Related Posts Plugin for WordPress, Blogger...