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.
Something I don't like about ActionSelectName is that IsValidName is called for every action method in the controller; I don't know why it works this way. I like a solution where every button has a different name based on what it does, but I don't like the fact that you have to have as many parameters in the action method as buttons in the form. I have created an enum for all button types:
Instead of ActionSelectName, I use an ActionFilter:
The filter will find the button name in the form data and if the button name matches any of the button types defined in the enum, it will find the ButtonType parameter among the action parameters:
and then in views, I can use:
This script allows to specify a data-form-action attribute which will work as the HTML5 formaction attribute in all browsers (in an unobtrusive way):
The form containing the button will be posted to the URL specified in the data-form-action attribute:
This requires jQuery 1.7. For previous versions you should use
live()
instead ofon()
.Modified version of
HttpParamActionAttribute
method but with a bug fix for not causing an error on expired/invalid session postbacks. To see if this is a problem with your current site, open the your form in a window and just before you go to clickSave
orPublish
, open a duplicate window, and logout. Now go back to your first window and try to submit your form using either button. For me I got an error so this change solves that problem for me. I omit a bunch of stuff for the sake of brevity but you should get the idea. The key parts are the inclusion ofActionName
on the attribute and making sure the name passed in is the name of the View that shows the formAttribute Class
Controller
View
If you do not have restrictions on the use of HTML 5, you can use the
<button>
tag withformaction
Attribute:Reference: http://www.w3schools.com/html5/att_button_formaction.asp
There are three ways by which you can solve the above issue
Below is a video which summarizes all the three approaches in a demonstrative way.
https://www.facebook.com/shivprasad.koirala/videos/vb.100002224977742/809335512483940
HTML way :-
In the HTML way we need to create two forms and place the “Submit” button inside each of the forms. And every form’s action will point to different / respective actions. You can see the below code the first form is posting to “Action1” and the second form will post to “Action2” depending on which “Submit” button is clicked.
Ajax way :-
In case you are a Ajax lover this second option would excite you more. In the Ajax way we can create two different functions “Fun1” and “Fun1” , see the below code. These functions will make Ajax calls by using JQUERY or any other framework. Each of these functions are binded with the “Submit” button’s “OnClick” events. Each of these function make call to respective action names.
Using “ActionNameSelectorAttribute”:-
This is a great and a clean option. The “ActionNameSelectorAttribute” is a simple attribute class where we can write decision making logic which will decide which action can be executed.
So the first thing is in HTML we need to put proper name’s to the submit buttons for identifying them on the server.
You can see we have put “Save” and “Delete” to the button names. Also you can notice in the action we have just put controller name “Customer” and not a particular action name. We expect the action name will be decide by “ActionNameSelectorAttribute”.
So when the submit button is clicked , it first hits the “ActionNameSelector” attribute and then depending on which submit is fired it invokes the appropriate action.
So the first step is to create a class which inherits from “ActionNameSelectorAttribute” class. In this class we have created a simple property “Name”.
We also need to override the “IsValidName” function which returns true or flase. This function is where we write the logic whether an action has to be executed or not. So if this function returns true then the action is executed or else it is not.
The main heart of the above function is in the below code. The “ValueProvider” collection has all the data that has been posted from the form. So it first looks up the “Name” value and if its found in the HTTP request it returns true or else it returns false.
This attribute class can then decorated on the respective action and the respective “Name” value can be provided. So if the submit is hitting this action and if the name matches of the HTML submit button name it then executes the action further or else it does not.
Here's an extension method I wrote to handle multiple image and/or text buttons.
Here's the HTML for an image button:
or for a text submit button :
Here is the extension method you call from the controller with
form.GetSubmitButtonName()
. For image buttons it looks for a form parameter with.x
(which indicates an image button was clicked) and extracts the name. For regularinput
buttons it looks for a name beginning withSubmit_
and extracts the command from afterwards. Because I'm abstracting away the logic of determining the 'command' you can switch between image + text buttons on the client without changing the server side code.Note: For text buttons you have to prefix the name with
Submit_
. I prefer this way becuase it means you can change the text (display) value without having to change the code. UnlikeSELECT
elements, anINPUT
button has only a 'value' and no separate 'text' attribute. My buttons say different things under different contexts - but map to the same 'command'. I much prefer extracting the name this way than having to code for== "Add to cart"
.