Cruft - (occasionally kruft) is jargon for computer software, computer hardware or internet information of poor quality. The term originates from software code that is rewritten leaving irrelevant or unwanted data within the code.

ASP.NET MVC AJAX Action Button (Unobtrusive)

Posted: October 15th, 2013 | Author: | Filed under: c#, experimental | Tags: , , , | No Comments »

It’s been a while since I’ve made a post, mostly because I’ve been busy and mostly because I usually post information I feel will be helpful to others. Today I want to share a snippet of code that I put together because I was unable to track down the answer I was looking for.

Currently I am in a long term project that is primarily based ASP.NET MVC3 and with that comes troubles of its own. The trouble I was having was I wanted to create an HTML BUTTON that behaved much like MVC’s Ajax.ActionLink does. I wanted to be able to specifiy some button content as well as AjaxOptions for Unobtrusive parsing. I looked on the web, no luck. So I ventured out and created my own extension that I hope you find worthy.

C# (Place in new or existing file)

public static MvcHtmlString ActionButton(this AjaxHelper ajaxHelper,
   string buttonText,
   string iconSrc,
   AjaxOptions ajaxOptions,
   object routeValues = null,
   object htmlAttributes = null,
   object iconAttributes = null)
{
UrlHelper urlHelper = new UrlHelper(ajaxHelper.ViewContext.RequestContext);
RouteValueDictionary htmlAttributeDictionary =
    HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
string imgUrl = urlHelper.Content(iconSrc);
//Build icon for use in button
TagBuilder buttonIcon = new TagBuilder("img");
buttonIcon.MergeAttribute("src", imgUrl);
buttonIcon.MergeAttributes(new RouteValueDictionary(iconAttributes));
//Text
TagBuilder text = new TagBuilder("span") { InnerHtml = buttonText };
//Build Button and place text and icon inside
TagBuilder button = new TagBuilder("button");
button.MergeAttributes(ajaxOptions.ToUnobtrusiveHtmlAttributes());
button.MergeAttributes(htmlAttributeDictionary);
button.InnerHtml = buttonIcon.ToString(TagRenderMode.SelfClosing) + text.ToString();
return MvcHtmlString.Create(button.ToString());
}

You can of course overload or customize this extension method to suit your needs (remove routeValues, htmlAttributes, etc…), we actually have a few variants (icon, no icon) for use in our system for different calls but I wanted to show you a full capability call.

We are not out of the woods just yet, Microsoft’s Unobtrusive AJAX support library for jQuery does not attach to Buttons! They support attaching to A, Form, INPUT[type=image] and Submit but not to regular ole Button. So you are going to need to add a little binding in there to get you hooked up. Copy and paste the following.

JavaScript (Place in your Unobtrusive jQuery Library File)

    $("button[data-ajax=true]").live("click", function (evt) {
        evt.preventDefault();
        if (!$(this).attr("disabled")) {
            asyncRequest(this, {
                url: this.href,
                type: "GET",
                data: []
            });
        }
    });

 

Making the call.
Now that you are all set you can use the following in your code in your View to return unobtrusive BUTTONS with AJAX bindings, below is a sample call.

    @Ajax.ActionButton("Button Text", "/Images/x_sm.png", new AjaxOptions
                {
                    Url = Url.Action("Add"),
                    UpdateTargetId = "Details",
                    OnComplete = "javascript: weAreDone();",
                    InsertionMode = InsertionMode.Replace,
                    OnSuccess = "javascript: hooray();"
                },
                null,
                new { id = "btn1"})

 

That’s it. Now you have an unobtrusive button in MVC3. Get to styling.

I hope this helps you. I think in the future I will allow for iconAttributes to allow for height/width options. Maybe IDK, I might just leave it all up to CSS.

 

HTML Output from above call:

<button id="btn1" data-ajax-update="#Details" data-ajax-success="javascript:
hooray();" data-ajax-mode="replace" data-ajax="true" data-ajax-url=
"/Assignments/Assignments/Add" data-ajax-complete="javascript: weAreDone();">
   <img src="/Images/x_sm.png" alt="" />
   <span>Button Text</span>
</button>