A Look at JamesCMS: Ajax Controls

Posted Monday, March 11, 2013 in Old JamesCMS Posts

In general when developing a website I like to use multiple SPAs to define the site as a whole. This means that once you are at a page, all related functions should be performed on that page without a full page load. To accomplish this in JamesCMS I used a few controls such as Ajax forms and jQuery load(). The first control is button that can trigger a load() function. The button is defined by the class jLoad and attributes href-loading and href-to-load.

{{javascript}}
function jLoad() {
    $(".jLoad").click(function () {
        $($(this).attr("target")).html(
            "<img src='" + 
            $(this).attr("href-loading") + 
            "' alt='loading' /> Loading");
        $($(this).attr("target")).load(
            $(this).attr("href-to-load"))
    });
}

To ease coding of these buttons I wrote a complementatry HtmlHelper extension to construct a button:

{{C#}}
public static MvcHtmlString AjaxButton(
    this HtmlHelper helper, string buttonText, 
    string target, string action)
{
    string controller = helper.ViewContext.
        RouteData.GetRequiredString("controller");
    return AjaxButton(helper, buttonText, 
        target, action, controller, null);
}

public static MvcHtmlString AjaxButton(
    this HtmlHelper helper, string buttonText, 
    string target, string action, 
    object routeValues)
{
    string controller = helper.ViewContext.
        RouteData.GetRequiredString("controller");
    return AjaxButton(helper, buttonText, 
        target, action, controller, routeValues);
}

public static MvcHtmlString AjaxButton(
    this HtmlHelper helper, string buttonText, 
    string target, string action, 
    string controller, object routeValues)
{            
    var anchor = new TagBuilder("input");
    anchor.Attributes["type"] = "button";
    anchor.Attributes["href-to-load"] = 
        UrlHelper.GenerateUrl("Default", 
        action, controller, 
        new RouteValueDictionary(routeValues), 
        RouteTable.Routes, 
        helper.ViewContext.RequestContext, false);

    anchor.Attributes["target"] = "#" + target;
    anchor.Attributes["href-loading"] = 
        UrlHelper.GenerateContentUrl(
            "~/images/loading.gif", 
            helper.ViewContext.HttpContext);

    anchor.Attributes["value"] = buttonText;  

    foreach (string css in new string[] 
        {"jLoad", "form-button"})
        anchor.AddCssClass(css);            

    return MvcHtmlString.
        Create(anchor.ToString());
}

This can be used as follows:

{{C#}}
@Html.AjaxButton("Edit", "text-" + Model.Id, "edit", new { id = Model.Id })

This will display a button that when clicked will load an edit page in place of the original data.

A similar method is used to call “ReadyLoad” divs at page load.