views:

14134

answers:

10

Is there some easy way to handle multiple submit buttons from the same form? Example:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" value="Send" />
<input type="submit" value="Cancel" />
<% Html.EndForm(); %>

Any idea how to do this in ASP.NET Framework Beta? All examples I've googled for have single buttons in them.

+4  A: 

You should be able to name the buttons and give them a value; then map this name as an argument to the action. Alternatively, use 2 separate action-links or 2 forms.

Marc Gravell
+8  A: 

You could write:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Send" />
<input type="submit" name="button" value="Cancel" />
<% Html.EndForm(); %>

And then in the page check if the name == "Send" or name == "Cancel"...

Ironicnet
+23  A: 

You can check the name in the action as has been mentioned, but you might consider whether or not this is good design. It is a good idea to consider the responsibility of the action and not couple this design too much to UI aspects like button names. So consider using 2 forms and 2 actions:

<% Html.BeginForm("Send", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Send" />
<% Html.EndForm(); %>

<% Html.BeginForm("Cancel", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Cancel" />
<% Html.EndForm(); %>

Also, in the case of "Cancel", you are usually just not processing the form and are going to a new URL. In this case you do not need to submit the form at all and just need a link:

<%=Html.ActionLink("Cancel", "List", "MyController") %>
Trevor de Koekkoek
This is ok when you dont need same form data for every submit button. If you need all data in common form than Dylan Beattie is the way to go. Is there any more elegant way to do this?
zidane
A: 

I'm not yet familiar with the framework, but generally I would use javascript. Something along the lines (syntax will likely be wrong):

<script type ="text/javascript">
function sendTo(url)
{
  document.myForm.action = url;
  document.myForm.submit();
}
</script>

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="button" value="Send to page 1" onclick="javascript:sendTo('page1')"/>
<input type="button" value="Send to page 2" onclick="javascript:sendTo('page2')" />
<% Html.EndForm(); %>
ya23
hmm... what is so wrong with this solution?
ya23
MyAction and MyController define what the form gets submitted to. If you do javascript on it, you would lose things like model mapping to the controller action.
paulwhit
+48  A: 

Give your submit buttons a name, and then inspect the submitted value in your controller method:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="Send" />
<input type="submit" name="submitButton" value="Cancel" />
<% Html.EndForm(); %>

posting to

public class MyController : Controller {
    public ActionResult MyAction(string submitButton) {
        switch(submitButton) {
            case "Send":
                // delegate sending to another controller action
                return(Send());
            case "Cancel":
                // call another action to perform the cancellation
                return(Cancel());
            default:
                // If they've submitted the form without a submitButton, 
                // just return the view again.
                return(View());
        }
    }

    private ActionResult Cancel() {
        // process the cancellation request here.
        return(View("Cancelled"));
    }

    private ActionResult Send() {
        // perform the actual send operation here.
        return(View("SendConfirmed"));
    }

}

EDIT:

To extend this approach to work with localized sites, isolate your messages somewhere else (e.g. compiling a resource file to a strongly-typed resource class)

Then modify the code so it works like:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="<%= Html.Encode(Resources.Messages.Send)%>" />
<input type="submit" name="submitButton" value="<%=Html.Encode(Resources.Messages.Cancel)%>" />
<% Html.EndForm(); %>

and your controller should look like this:

// Note that the localized resources aren't constants, so 
// we can't use a switch statement.

if (submitButton == Resources.Messages.Send) { 
    // delegate sending to another controller action
    return(Send());

} else if (submitButton == Resources.Messages.Cancel) {
     // call another action to perform the cancellation
     return(Cancel());
}
Dylan Beattie
This is what I was looking for here: http://stackoverflow.com/questions/649513/how-do-i-perform-a-secondary-action-i-e-calculate-fields-in-asp-net-mvc - thanks
paulwhit
Just what I needed ... thanks
jalchr
too bad you depend on the text displayed on the button, it's kinda tricky with a multilanguage user interface
Omu
Omu - see latest edit, which explains (briefly!) how to do the same thing with localized string/message resources.
Dylan Beattie
+8  A: 

Eilon suggests you can do it like this:

If you have more than one button you can distinguish between them by giving each button a name:

<input type="submit" name="SaveButton" value="Save data" />
<input type="submit" name="CancelButton" value="Cancel and go back to main page" />

In your controller action method you can add parameters named after the HTML input tag names:

public ActionResult DoSomeStuff(string saveButton, string
cancelButton, ... other parameters ...)
{ ... }

If any value gets posted to one of those parameters, that means that button was the one that got clicked. The web browser will only post a value for the one button that got clicked. All other values will be null.

if (saveButton != null) { /* do save logic */ }
if (cancelButton != null) { /* do cancel logic */ }

I like this method as it does not rely on the value property of the submit buttons which is more likely to change than the assigned names and doesn't require javascript to be enabled

See: http://forums.asp.net/p/1369617/2865166.aspx#2865166

PabloBlamirez
+3  A: 

David Findley writes about 3 different options you have for doing this, on his ASP.Net weblog.

Read the article multiple buttons in the same form to see his solutions, and the advantages and disadvantages of each. IMHO he provides a very elegant solution which makes use of attributes that you decorate your action with.

Saajid Ismail
+4  A: 

Just written a post about that: Multiple submit buttons with ASP.NET MVC.

Andrey Shchekin
+4  A: 

I would suggest interested parties have a look at a solution i think is very elegant here >> http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

In case the link dissapears its using the MultiButton attribute applied to a controller action to indicate which button click that action should relate to.

Izmoto
+1 Lovely solution .. quite crisp and clean!
Rashmi Pandit