ASP.NET MVC 3: Support multiple submit buttons in one form with HTML Helper MultiSubmitButton

Out of the box ASP.NET MVC 3 only supports one submit button for each form. To be more precise: The MVC 3 framework only supports one submit action for each form, i.e. all submit buttons in the form post the data to the same URL (the URL that is defined in the action attribute of the the <form> tag).

One scenario where more than one submit button is useful is for example a form that enables the user to update a dataset or to save the data as a new dataset. On the server side, one would implement two actions (like Update() and AddNew()) and requires a logic that decides which actions should be executed depending on which button was clicked.

There are approaches that solve this problem by decorate the actions with additional attributes:

The basic idea of these approaches is to set the name attribute of the submit button’s <input> tag and implement a custom ActionNameSelectorAttribute that tests the submitted data of the HTTP request against this value to decide whether the action should be executed or not.

In this blog post I will show how to implement a custom HTML Helper that supports creating forms with multiple submit buttons. The benefit of this approach is that no changes on the server side (like additional attributes) are required. The drawback of this solution is that it depends on JavaScript (jQuery), i.e. it only works in browsers with JavaScript support enabled.

The HTML Helper MultiSubmitButton shown below depends on the SubmitButton() HTML Helper of the ASP.NET MVC 3 Futures library. One could use the NuGet package manager to install MVC 3 Futures

PM> Install-Package Mvc3Futures

or download the files here.

The MultiSubmitButton HTML Helper works like the MVC 3 Futures’ SubmitButton HTML Helper but has an additional (string) parameter url which defines the URL of the action that should be called when the button was clicked. The implementation looks as follows:

public static class MultiSubmitButtonExtension
{
  public static MvcHtmlString MultiSubmitButton(this HtmlHelper helper, string url, string name)
  {
    return MultiSubmitButton(helper, url, name, null, (IDictionary<string, object>)null);
  }
  public static MvcHtmlString MultiSubmitButton(this HtmlHelper helper, string url, string name, string buttonText)
  {
    return MultiSubmitButton(helper, url, name, buttonText, null);
  }
  public static MvcHtmlString MultiSubmitButton(this HtmlHelper helper, string url)
  {
    return MultiSubmitButton(helper, url, null, null, (IDictionary<string, object>)null);
  }
  public static MvcHtmlString MultiSubmitButton(this HtmlHelper helper, string url, string name, string buttonText, object htmlAttributes)
  {
    return helper.MultiSubmitButton(url, name, buttonText, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
  }
  public static MvcHtmlString MultiSubmitButton(this HtmlHelper helper, string url, string name, string buttonText, IDictionary<string, object> htmlAttributes)
  {
    htmlAttributes = htmlAttributes ?? new Dictionary<string, object>();
 
    // Add onClick handler
    string onClick = "$(this).parents('form').attr('action', '" + url + "');";
    if (htmlAttributes.ContainsKey("onClick")) {
      htmlAttributes["onClick"] = htmlAttributes["onClick"] + ";" + onClick;
    } else {
      htmlAttributes.Add("onClick", onClick);
   }
    return helper.SubmitButton(name, buttonText, htmlAttributes);
  }
}

You can combine the MultiSubmitButton HTML Helper with ordinary submit buttons: The multi submit buttons will call the action that is defined with its url parameter and the ordinary submit buttons will call the form’s default action (defined in the form’s action attribute).

Here is an example how to use the MultiSubmitButton HTML Helper:

@using (Html.BeginForm("DefaultAction", "Controller"))
{
 
  // Add input fields here ...
 
  @Html.SubmitButton("button1", "Default Action");
  @Html.MultiSubmitButton(Url.Action("FormAction1"), "button2", "Action 1");
  @Html.MultiSubmitButton(Url.Action("FormAction2"), "button3", "Action 2");
 
}

As you can see in the example above one could use the Url.Action() method to easily generate the URL that is passed to the MultiSubmitButton helper.

A running Visual Studio 2010 project containing all the source code could be downloaded here.

Comments

  1. Yiwen Chung

    After trying many solutions found on the web, yours is the best, cleanest and easiest to implement. Thanks.

Leave a comment

Your email address will not be published. Required fields are marked *

*