How to Handle Multiple Submit Buttons in ASP.NET MVC Framework

How do you handle multiple submit buttons in ASP.NET MVC Framework?

Here is a mostly clean attribute-based solution to the multiple submit button issue based heavily on the post and comments from Maarten Balliauw.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultipleButtonAttribute : ActionNameSelectorAttribute
{
public string Name { get; set; }
public string Argument { get; set; }

public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
var isValidName = false;
var keyValue = string.Format("{0}:{1}", Name, Argument);
var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);

if (value != null)
{
controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
isValidName = true;
}

return isValidName;
}
}

razor:

<form action="" method="post">
<input type="submit" value="Save" name="action:Save" />
<input type="submit" value="Cancel" name="action:Cancel" />
</form>

and controller:

[HttpPost]
[MultipleButton(Name = "action", Argument = "Save")]
public ActionResult Save(MessageModel mm) { ... }

[HttpPost]
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(MessageModel mm) { ... }

Update: Razor pages looks to provide the same functionality out of the box. For new development, it may be preferable.

MVC 5 multiple submit on one view

you can identify your button from there name tag like below, Your need to check like this in you controller

if (Request.Form["mySubmit"] != null)
{
//Write your code here
}
else if (Request.Form["save"] != null)
{
//Write your code here
}

OR try;

[HttpPost]
public ActionResult RoleEdit(List<UserRole> userRole, FormCollection fc)
{

if (fc["mySubmit"] != null)
{
//save draft code here
}
else if (fc["mySubmit"] != null)
{
//publish code here
}
}

How to handle two submit buttons on MVC view

See below:

View:

<input type="submit" value="Save" name="buttonType" />

<input type="submit" value="Publish" name="buttonType" />

Action

  public ActionResult MyAction(MyModel model, string buttonType)
{
if (buttonType == "Save")
{
// Do something for Save
}
if (buttonType == "Publish")
{
//Do something for Publish
}
return View(Model);
}

ASP.NET MVC Core/6: Multiple submit buttons

You can use the HTML5 formaction attribute for this, instead of routing it server-side.

<form action="" method="post">
<input type="submit" value="Option 1" formaction="DoWorkOne" />
<input type="submit" value="Option 2" formaction="DoWorkTwo"/>
</form>

Then simply have controller actions like this:

[HttpPost]
public IActionResult DoWorkOne(TheModel model) { ... }

[HttpPost]
public IActionResult DoWorkTwo(TheModel model) { ... }

A good polyfill for older browsers can be found here.

Keep in mind that...

  1. The first submit button will always be chosen when the user presses the carriage return.
  2. If an error - ModelState or otherwise - occurs on the action that was posted too, it will need to send the user back to the correct view. (This is not an issue if you are posting through AJAX, though.)

MVC razor form with multiple different submit buttons?

You could also try this:

<input type="submit" name="submitbutton1" value="submit1" />
<input type="submit" name="submitbutton2" value="submit2" />

Then in your default function you call the functions you want:

if( Request.Form["submitbutton1"] != null)
{
// Code for function 1
}
else if(Request.Form["submitButton2"] != null )
{
// code for function 2
}

Multiple submit buttons with values passed from buttons

Finally got it. Though @Stephen Muecke did not really provide a direct solution, I should say he made me reconsider using formaction again so I still have to thank him. Thanks mate! Below is how I solved it:

View

@using Models.Enums
@model MyApp.Data.ApplicationSettings

@Html.AntiForgeryToken()
@using (Html.BeginForm())
{
...
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System1" formaction="Admin/TestConnection" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
...
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System2" formaction="Admin/TestConnection" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
}

Controller

public ActionResult TestConnection(ApplicationSettings model, DatabaseSystems database)
{
// at the end, instead of putting return View() or return("Index", model), I used below code
return Redirect("/[ControllerName]");
{

... this way, formaction will do the calling of the ActionResult method for me while keeping the name attribute of the button free for other purposes such as passing it as a parameter to my TestConnection method.

multiple submit buttons asp.net mvc 5 not working

As you said Command in Action parameter is an Enum:

public enum Command { SaveAndAddMore, SaveAndNext, Save, Delete }

So whatever values given to button is need to be same as Emum values, So your first button which is working having value same as Enum value i.e. SaveAndAddMore. Changing value of second button to SaveAndNext will work as you expected. So your div after change will be:

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="SaveAndAddMore" name="command" class="btn btn-default" />
<input type="submit" value="SaveAndNext" name="command" class="btn" />

</div>
</div>

How to handle multiple submit button in same form

In HTML5 there's a new attribute named formaction where you can change the action attribute of the form depending on what button is being clicked.

<input type='submit' formaction='/home/login' value='Login'>
<input type='submit' formaction='/home/register' value='Register'>

However, this tag is isn't valid in IE9 and earlier.

Edit: extended answer

The idea behind the second example you're given is that a button only sends its value if it's being clicked. For the action method to work you need to have both a login and a register value being passed on. But since only one of the buttons can be pressed, only one of the values will be passed on. That's why he added two hidden fields with default value of false, thus making sure that both parameters always will be passed on to the action method. The button being clicked will override the hidden field.

The first variable pair has their name set to login. Notice that it's being defined twice, first as a button and then as a hidden field. If this button is clicked then true will be sent. If the other button is clicked then this button's value will not be sent and instead the hidden field (with the same name) will be sent.

<button type="submit" name="login" value="true">Login</button>
<input type="hidden" name="login" value="false"/>

The second variable pair (with the name Register) works in the same way. The hidden field becomes a "fallback option" in case this button isn't clicked.

<button type="submit" name="register" value="true">Register</button>
<input type="hidden" name="register" value="false"/>

Only one of the buttons can be clicked. If the register button is clicked then the fallback value for login will be used. If the login button is clicked then the fallback value for register will be used.

In total there are only two variables that will be sent to the action script: login and register.

If you want to solve it on the client side you can simply let the submit buttons change the action using the onclick event.

<form name="myFormName" action="Login">
<input type="submit" value="Login" />
<input type="submit" onclick="document.myFormName.action='Register'" value="Register" />

You need to use the name attribute in the form for this to work.

Edit 2: more on buttons when clicked

If you have 5 buttons...

<button type="submit" id="b1" value="true"> 1 </button>
<button type="submit" id="b2" value="true"> 2 </button>
<button type="submit" id="b3" value="true"> 3 </button>
<button type="submit" id="b4" value="true"> 4 </button>
<button type="submit" id="b5" value="true"> 5 </button>

...and you click on b3 then ONLY b3 will send it's value back to the server. This is just so you easily can see, on the server, what button that was clicked.

If you have an action method on your server that NEEDS all 5 button-variables then you have to make sure you'll send them in a different way. The reason for that is that MVC tries to match incoming variables with an action method and this action method needs all 5 button-variables to be valid.

[HttpPost]
public ActionResult LoginRegistration(string b1, string b2, string b3, string b4, string b5)
{
...
}

Since b1, b2, b4 and b5 won't be sent to the server when we click b3, and since the action method needs them, we have to figure out another way of sending them.

One way is to use hidden field that have the same name as the buttons. A hidden field is ALWAYS being sent to the server. So by adding these fields AFTER the buttons we can make sure that all of b1, b2, b3, b4 and b5 get something sent to the server. If we click on b3 then the value of the button will be used instead of the hidden field.

<input type="hidden" id="b1" value="false" />
<input type="hidden" id="b2" value="false" />
<input type="hidden" id="b3" value="false" />
<input type="hidden" id="b4" value="false" />
<input type="hidden" id="b5" value="false" />

By doing this way the action method above will work because no matter what button the user clicks, all five b-values will be sent to the server.

Edit 3 : without hidden fields
It's possible to have different buttons without having fallback hidden fields that sends the value. We still consider the same buttons as before, with different names. But this time we have no hidden values. So if Button 3 is clicked then ONLY b3=true is sent to the server.

<button type="submit" id="b1" value="true"> 1 </button>
<button type="submit" id="b2" value="true"> 2 </button>
<button type="submit" id="b3" value="true"> 3 </button>
<button type="submit" id="b4" value="true"> 4 </button>
<button type="submit" id="b5" value="true"> 5 </button>

For the action method to work with this scenario we need to make all the fields optional so MVC can match all/some/no fields against incoming variables. It is done by writing string? instead of string in the parameter field. The? means optional (it actually means that the value can be empty/null).

[HttpPost]
public ActionResult LoginRegistration(string? b1, string? b2, string? b3, string? b4, string? b5)
{
...
}

So in this case this action method would work even though only b3=true is being sent and all the others are not.

Multiple submit button with ajax submit on asp.net core

I need multiple submit button usage with ajax submit on asp.net core
mvc.

If you want to implement on the basis of ajax, I think @Imran provides a correct idea, but based on your js method, his solution can not completely solve your problem, you need to get the name of the submit button instead of getting the form id.

Here is a complete case, please refer to it:

<form method="post" asp-action="DuyuruEdit" id="myform" enctype="multipart/form-data">
<div class="form-group">
<input name="Name" type="text" /><br />
</div>
<div class="form-group">
<input name="Data" type="text" /><br />
</div>
<input type="submit" name="save" value="Save" />
<input type="submit" name="release" value="Release" />
</form>

@section Scripts
{
<script>
var clickButtonName;
$("input[type=submit]").click(function () {
clickButtonName = $(this).attr("name");
});
$("#myform").submit(function (e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
var formData = new FormData(this);
$.ajax({
type: "POST",
url: '@Url.Action("DuyuruEdit", "Duyuru")?saveOrRelease=' + clickButtonName ,
data: formData,
contentType: false,
processData: false,
//other code
});
return true;
});
</script>
}

My DuyuruEditViewModel:

 public class DuyuruEditViewModel
{
public string Name { get; set; }
public string Data { get; set; }
}

Controller:

        [HttpPost]
public IActionResult DuyuruEdit(DuyuruEditViewModel mdl, string saveOrRelease)
{
if(saveOrRelease == "save")
{

}
if (saveOrRelease == "release")
{

}
return View();
}

Here is the test result:

Sample Image



Related Topics



Leave a reply



Submit