Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Creating a custom AJAX Helper

, 15 Apr 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
Unobtrusive AJAX and how we can create custom AJAX helpers quite easily by adding extension methods to the AjaxHelper class.

"THE ARTICLE IS NO LONGER MAINTAINED HERE. PLEASE POST ANY FURTHER DISCUSSIONS/QUESTIONS IN MY BLOG http://www.prideparrot.com/blog/archive/2012/6/creating_a_custom_ajax_helper" - Author

Unobtrusive AJAX

Unobtrusive AJAX is an approach in which the AJAX behaviors are separated out from the HTML elements. ASP.NET MVC framework provides supports for AJAX using the AjaxHelper and AjaxHelperExtensions classes. For example you can easily create an HTML form that submits the data through AJAX using the BeginForm extension method. The below listing shows how to create an AJAX form in a Razor view.

@Ajax.BeginForm("AddMovie", new AjaxOptions {
    UpdateTargetId = "divMovies"
})
Listing 1. Creating an AJAX form in razor

In views we can access the AjaxHelper through the property AJAX. Prior to version 3, MVC framework doesn't supports unobtrusive AJAX so when you try to create an AJAX form using the above code you will see the following html rendered to the browser.

<form action="/Movie/AddMovie" id="form0" method="post" 
    onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));" 
    onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), 
    { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: 'divMovies' });">
Listing 2. Obtrusive html generated by the AJAX form

You can notice the event handlers are directly specified in the html, also the arguments are passed as an object to the onsubmit handler. Yeah, the HTML looks ugly! The unobtrusive AJAX helps to clean away the mess by separating the AJAX behaviors from the DOM. Using unobtrusive AJAX we not only gain clean html but also we can gracefully handle the cases where the browsers doesn't supports JavaScript. ASP.NET MVC 3 supports unobtrusive AJAX with the help of jQuery.

When unobtrusive AJAX enabled this is what the form looks like:

<form action="/Movie/AddMovie" 
    data-ajax="true" 
    data-ajax-mode="replace" 
    data-ajax-update="#divMovies" 
    id="form0" method="post">
Listing 3. Unobtrusive html generated by MVC 3

It's clearly evident the html is clean and easy to maintain.

How thing works?

The MVC framework represents the additional arguments that need to be passed for AJAX calls as HTML5 data attributes in the form. Microsoft provides a library called jquery.unobtrusive-ajax.js that reads form elements those have the attribute data-ajax as true, extract the data attributes attached to the form and call the necessary jQuery's AJAX methods passing those arguments.

In MVC, to enable unobtrusive AJAX we have to do couple of things.

  1. Include both the jQuery library and Microsoft's unobtrusive AJAX library in views.
  2. Set the UnobtrusiveJavaScriptEnabled as true in web.config.

Creating a custom AJAX helper extension

The MVC 3 framework supports AJAX behaviors for two html elements: forms and links. You can create an AJAX form or an AJAX link by the AjaxHelper class. To create an AJAX form or an AJAX link we need to supply the AjaxOptions instance to the extension method. The MVC framework writes the properties specified in the AjaxOptions instance as data attributes to the html elements.

Here is an example of creating an AJAX link using one of the extension method provided by the AjaxHelper.

@Ajax.ActionLink("Load All Movies", new AjaxOptions {
    UpdateTargetId = "divMovies",
    InsertionMode = InsertionMode.Replace
})
Listing 4. AJAX link

Like custom html helpers we can create custom AJAX helpers. The approach is nearly same as creating a custom html helper, instead of creating extension method for the HtmlHelper class we have to do for AjaxHelper.

Let see how we can create an AJAX search textbox by creating a custom AJAX helper. Our search textbox make AJAX calls to the server when we enter/change the text and dynamically update the html. First we have to create an extension method for AjaxHelper as shown in the below listing.

public static MvcHtmlString Textbox(this AjaxHelper ajaxHelper, string name, 
    AjaxOptions ajaxOptions, object htmlAttributes)
{
    var tag = new TagBuilder("input");
    tag.MergeAttribute("name", name);
    tag.MergeAttribute("type", "text");

    tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    tag.MergeAttributes((ajaxOptions ?? new AjaxOptions()).ToUnobtrusiveHtmlAttributes());

    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}
Listing 5. Custom textbox AJAX helper

Our extension method Textbox is quite simple takes three parameters: a name for the textbox, AjaxOptions instance and htmlattributes object. In the first three lines of the code we are creating the input element with appending the name and type attributes using the TagBuilder class. Then we are appending the additional html attributes passed as an anonymous object htmlattributes to the input element by calling the AnonymousObjectToHtmlAttributes method of HtmlHelper class.

What we are doing next is quite important, we are converting the passed AjaxOptions instance into HTML5 data attributes and appending to the input element by calling the AnonymousObjectToHtmlAttributes method of it.

So our search textbox is quite good but not ready to use. Unless we do some work in the client-side it simply doesn't work.

Extending the unobtrusive JavaScript library

The unobtrusive JavaScript library queries only for form and anchor elements and not for others unless we do something about that. To enable AJAX behaviors for textbox we have to modify the library.

$("input[type=text][data-ajax=true]").live("keyup", function (evt) {       
    asyncRequest(this, 
        { 
            type: "GET", 
            data: [{ name: $(this).attr("name'), value: $(this).val()}] 
        });
});
Listing 6. Modifying unobtrusive AJAX library for textbox helper

In the above script we query the textboxes that have AJAX enabled and listen to the keyup event. Whenever the event fires we make an AJAX call using the private helper method asyncRequest. We have to add this snippet right before or above the library queries for form and link elements.

Test drive

We can call for custom AJAX helper as below from any razor view, we have to include the namespace where our extension lives in the web.config under the Views folder.

@Ajax.Textbox("search",
    new AjaxOptions
    {
        Url = "/Movie/Search",
        UpdateTargetId = "movies",
        InsertionMode = InsertionMode.Replace
    }, 
new { size = 50 })
Listing 7. Creating custom AJAX textbox helper in razor view
<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, 
        System.Web.Mvc, Version=3.0.0.0, Culture=neutral, 
        PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
    <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="TextboxAjaxHelper.Extensions" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />        
    </namespaces>
    </pages>
</system.web.webPages.razor>
Listing 8. Adding the extension namespace in web.config

Here is a sample application that describes how we can use our custom AJAX helper.

Summary

In this article we saw about unobtrusive AJAX and how we can create custom AJAX helpers quite easily by adding extension methods to the AjaxHelper class.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

After2050
Software Developer Trigent Software Private Limited
India India
I'm a software developer from south tip of India. I spent most of the time in learning new technologies. I've a keen interest in client-side technologies especially JavaScript and admire it is the most beautiful language ever seen.
 
I like sharing my knowledge and written some non-popular articles. I believe in quality and standards but blames myself for lagging them.
 
I believe in small things and they makes me happy!
Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141216.1 | Last Updated 15 Apr 2014
Article Copyright 2012 by After2050
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid