I'm working on an ASP.NET MVC form that requires multiple submit buttons. I've read a half-dozen or so posts on SO regarding submit button identification, but I'm unable to even detect the submit button on the form post. The buttons are named, so I expect them to at least show up in the posted elements.
After a lot of trial-and-error, my form is presently defined as follows:
@using (Html.BeginForm("LineItems", "Loan", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
// Several omitted fields.
<input type="submit" id="Command" name="Command" value="Save" class="btn btn-primary btn-sm" />
<input type="submit" id="Command" name="Command" value="Confirm Budget" class="btn btn-sm btn-success" />
}
Yes, those buttons are presently named the same thing out of desperation trying to at least detect a posted form element with the name of "Command".
My ActionResult looks like this.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LineItems(LineItemsModel model, string Command)
{
//var button = Request.Params.AllKeys.FirstOrDefault(key => key.StartsWith("btnSave"));
//var errors = ModelState.Where(x => x.Value.Errors.Count > 0).Select(x => new { x.Key, x.Value.Errors }).ToArray();
if (ModelState.IsValid)
{
// Save code omitted...
}
return View(model);
}
I put a breakpoint on that ModelState.IsValid line and then started inspecting in debugger. Here are a couple of watches that I reviewed. Request.Params.AllKeys Request.Form.AllKeys
The submit button doesn't show up in either of those. Also, you'll notice I stuck string Command in the parameters of the ActionResult. That just returns NULL. I've changed the names and IDs of those buttons a few times, and still have been unable to find them.
In the Immediate Window, this returns null: Request.Form["Command"]
Where would the button show up on the form post? If it's not in Request.Form.AllKeys, where would it be?
One other thing to mention, this form successfully saves the data that I'm working with. We just added another button because we'll need to perform a different action with the form elements when the second button is selected, hence my need for detecting the submit button.
Though I've dealt a lot with old school Classic ASP and with Web Forms, I'm less proficient with MVC. So my apologies in advance if this is a duplicate or a noob question.
These are a few of the many SO posts that I read, but I've been unable to solve this problem.
- How do you handle multiple submit buttons in ASP.NET MVC Framework?
- MVC which submit button has been pressed
- Asp.net mvc - Html Submit button not sent with post?
Thanks for your help.
=== Edit 4/24/2015 at 2:46 PM Central ===
Thanks for your suggestions everyone. As Huy Hoang Pham showed in fiddle (thanks for writing that) the pattern that I'm employing should work. I've tried several other suggestions to get this operational, but they failed. I suspect that maybe there is something more flawed in the form that I'm working with. This is a dynamic form where users can add rows via javascript. Though I'm not at liberty to post the entire form.
At any rate, I've programmed a workaround which will tell me what button got pressed, though this isn't pretty. Here it is, but there must be a better way.
First, I added this to my model:
public string ButtonSelected { get; set; }
In the view, I put this in a code block to get the field name.
var hiddenButtonSelectedFieldID = Html.IdFor(m => m.ButtonSelected);
Below that, I put this script in the view.
<script>
$(function () {
$('.submissionButton').on('click', function () {
var buttonId = $(this).prop("id");
$('#@hiddenButtonSelectedFieldID').val(buttonId);
});
});
</script>
And I added this new hidden field above the form buttons.
@Html.HiddenFor(m => m.ButtonSelected, new { @Value = "Save" })
<input type="submit" id="btnSave" name="btnSave" value="Save" class="btn btn-primary btn-sm submissionButton" />
<input type="submit" id="btnConfirmBudget" name="btnConfirm" value="Confirm Budget" class="btn btn-sm btn-success submissionButton" />
Upon posting the form, this successfully returns the selected button in my model. The ButtonSelected property of the model will have "btnSave" or "btnConfirmBudget" depending on what I click. It also works if I click via the Enter key. Personally I dislike this workaround. It's brittle, has a JavaScript dependency, and feels downright hacky. But I've got to be pragmatic and get this piece operational to move on with this project.
I am open to trying additional approaches, but may not be able to respond right away. Again, thanks so much for your help.
=== Edit 4/29/2015 ===
Well, I can't close this question. After recreating the form one element at a time, starting with the submission buttons, I was able to successfully identify the selected submit button until I added a form element that had a custom remote validator. Once that element was added, the submitted button returned null. If I disabled the custom validator in the model, I was able to identify the button. Consequently I removed the previous JavaScript workaround code, and removed the remote validator data annotation from the model. Previously I had written code to validate this form element in the controller action as well, as an extra fallback. So I'm just running with that server side validation routine. If time permits I may post the details from these finding as another SO question. There must be something that I overlooked or implemented incorrectly with that custom remote validator.
A moderator can feel free to close this. Thanks.