I have a single form in ASP.NET MVC (v1) that has 2 input buttons. Each submit button has to be contained within this single form and I need to know which one the user pressed.
I know about the trick to check the FormCollection values which will be returned based on the button pressed. For example, if I have and and the user clicks Button2, I should be able to say Request.Form["Button2"] != null and that will evaluate to true in which case I know that the user clicked that button.
However, this is not working for me. The values of all my buttons is null as non of them are contained within the Request.Form values. Is there a bug in ASP.NET MVC which swallows these values?
Here is my form code:
<% using (Html.BeginForm()) {%>
<% Html.RenderPartial( "EditAreaControl", Model ); %>
<div class="form-layout-command-container">
<div class="form-layout-command-area-alpha"><button type="submit" name="submit1" value="Save">Save</button></div>
<div class="form-layout-command-area-alpha"><button type="submit" name="submit2" value="SaveAndCopy">Save and Create Copy</button></div>
<div class="form-layout-command-area-beta"><%= Html.ActionLink("Cancel", "list") %></div>
</div>
<% } %>
Here is my controller code:
[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Add(FormCollection values )
{
if (values["submit1"] != null)
// always false
if (values["submit2"] != null)
// always false as well
}
From w3schools:
Important: If you use the button element in an HTML form, different browsers will submit different values. Internet Explorer will submit the text between the and tags, while other browsers will submit the content of the value attribute. Use the input element to create buttons in an HTML form.
It seems that this is not standardized. You should stick to
<input type="submit" name="submitButton" value="Save" />
<input type="submit" name="submitButton" value="Cancel" />
I would use inputs of type submit instead of buttons. Non-inputs may not passed back in a form post or at least can be passed back inconsistently. Note that they can have the same name with different values so that you can use the same parameter for any button that submits the form.
<input type="submit" name="submitButton" value="Save" />
<input type="submit" name="submitButton" value="SaveAndCopy" />
public ActionResult Save( string submitButton, ... )
{
if (submitButton == "Save")
{
...
}
else if (submitButton == "SaveAndCopy")
{
...
}
....
}
Using Firebug, I found that the submit buttons were not being sent in the response and because of that, there isn't much I can do on the MVC side. I decided to use a client side hack to populate a hidden input field on the client side which would be passed to the controller values.
I changed the input buttons to be:
<input type="submit" value="Save" onclick="actions.copyValues($(this), $('#submitAction'));" />
<input type="submit" value="Save and Copy" onclick="actions.copyValues($(this), $('#submitAction'));" />
<input type="hidden" id="submitAction" name="submitAction" />
The jquery script simply copies the values:
Actions.prototype.copyValues = function(from, to) {
$(to).val($(from).val());
};
The controller action then looks for the hidden input values:
var request = HttpContext.Request;
return request.Form["submitAction"];
This solves the issue from above but I realize it is not that clean.
Put them in two different forms and you will know which one submitted based on which action was called on the controller.
Related
I am trying to save input (an address) from an html form in order to use in other cshtml pages in my asp.net core web application. I am also using Razor as a template language. I have a web application in which the user will enter an address on one page and then on another page I want to use that input and place it into an api call. My html form is below.
<form method="post" action="/Features">
<p>
Address: <input type="text" name="searchString"/>
<input type="submit" value="Search" />
</p>
</form>
I have previously used sessions but it was for an asp.net project using web forms (I believe) and am not sure if this is the route I should go. The address being entered doesn't need to be kept secure. Thanks for any help.
You have two options here:
Submit the form to your page, store the address in TempData then redirect to the second page where you would use your submitted value (Here you use the Post/Redirect/Get pattern in order to avoid your form being submitted again by mistake via a page reload).
Submit the form directly to the second page.
Going with the first option is recommended.
Page:
<form method="post" asp-page-handler="Features">
<p>
Address: <input type="text" name="searchString"/>
<input type="submit" value="Search" />
</p>
</form>
Handler:
public IActionResult OnPostFeatures(string searchString)
{
TempData["Key"] = searchString;
return RedirectToPage("/SecondPage");
}
Then on your second page you get the searchString in the same way via:
string value = TempData["Key"] as string;
As i said you can also submit your form to the second page where you can do what ever you want with your value. Just be careful of multiple submissions.
Here is a demo to use TempData in Razor page:
cshtml:
<form method="post" asp-page-handler="Features">
<p>
Address: <input type="text" name="searchString"/>
<input type="submit" value="Search" />
</p>
</form>
cshtml.cs:
public IActionResult OnPostFeatures(string searchString) {
TempData["searchString"] = searchString;
xxxxxxx
}
Other Page you want to use searchString:
string searchString=TempData["searchString"];
//TempData.Keep(); can help you keep the value,and you can still use the searchString value in other place
TempData.Keep();
or you can use
string searchString=TempData.Peek("searchString");
So that you can still keep the searchString value
I have two buttons in the same page ( Razor/ ASP.NET Web Pages), how do I check which button I clicked,
so far I have:
if (IsPost)
{
//code block here
}
<input type="submit" value="Update" class="submit" id="btnUpdate" />
<input type="submit" value="Clear" class="submit" id="btnClear" />
the problem is (my low IQ, I know) it executes with any button clicked, only btnUpdate should execute the code block
Note: IS NOT MVC
note2: asp.net shows an example checking which textbox is empty to determine the action when a different button is clicked, is not what I'm looking for
<input type="submit" value="Update" class="submit" id="btnUpdate" name="update" />
<input type="submit" value="Clear" class="submit" id="btnClear" name="clear"/>
attach name attribute to buttons and check which one submitted via
if(IsPost){
if (Request.Form["clear"] != null)
{
//when clear clicked
}
else if (Request.Form["update"] != null)
{
//when update clicked
}
}
Please try this:
if (IsPostBack)
{
if(! string.IsNullOrEmpty(Request.Form["Button2"]))
Response.Write("{Button2 was clicked");
}
remove the "submit" class from your clear button, and change its type to "button"
. This will prevent it from posting the form.
I have a loop that creates some buttons and (is meant to) make a function call when that button is pressed.
foreach (Answer a in qanswers)
{
//Guid answerid = new Guid();
<form method="post" action="">
<div class="float-left">
<input type="submit" value="#a.Answer1" class="submit" style="width:600px" onmousedown="#{saveTest(a, module, user, quest, healthsafety);}">
<br /><br />
</div>
</form>
}
However, it calls the "saveTest" procedure at page load for each button produced, rather than onmousedown/onmouseclick.
Is it possible to change this?
I assume from this that saveTest is a server side function that you are trying to call.
onmousedown is a client side event and can only directly run client side script.
If you wish to call a server side function then you will need to specify an action in the form that the page will post pack to.
Have a look here for more on this
http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform(v=vs.108).aspx
A quickly modified version of your code would be:
foreach (Answer a in qanswers)
{
using (Html.BeginForm("saveTest", "ControllerName"))
{
<div class="float-left">
<input type="submit" value="#a.Answer1" class="submit" style="width:600px")>
<br /><br />
</div>
}
}
The button will submit to the controller and action that has specified in the form. So please check carefully which controller and action you have specified.
using (Html.BeginForm("saveTest", "Controller"))
{
}
This is the way you have to specify your form.
Regards,
Pavan.G
When I use HttpPost shouldn't the form values be hidden in my URL?
Here's the Razor code I'm using to generate a confirm page for payment:
#using (Html.BeginForm("Index", "Checkout", new { amount = Model.PackageCost, currency = "$", itemDescription = Model.PackageDescriptor, type = "digital" }, FormMethod.Post))
{
<input type="submit" value="Confirmar" class="btn primary frmsubmit" />
}
In my HTML, this is generated:
<form action="/Checkout?amount=50¤cy=%24&itemDescription=Paquete%20Gold50%20%7C%2050%24%20(59%20lances)&type=digital" method="post">
<input type="submit" value="Confirmar" class="btn primary frmsubmit" />
</form>
And when I click the Confirm button to submit the form, this is the URL I'm lead to:
http://localhost:5868/Checkout?amount=50¤cy=%24&itemDescription=Paquete%20Gold50%20%7C%2050%24%20%2859%20lances%29&type=digital
So what gives? Why aren't the values being hidden if it's a POST form?
Because those are not the form values, but the route values. The form values are the values of the <input > tags.
I assume you don't want any route values(leave out the third parameter) and instead create <input ...> tags with an appropriate default value. If the normal user should not see them use <input type="hidden"> (This is obviously not a security feature).
You should also use anti request forgery tokens.
I have a page in my C# webbrowser that contains
<input type="submit" value="Sign out">
Since it does not have an id, I am unable to use the webbrowser's htmldocument to get it by an id and invoke its click. How would I click it using htmldocument now?
You can give it your own ID you know, it's doesn't have to be a server control for that. Just do:
<input type="submit" ID="MySubmitButton1" value="Sign out">
You mention you want to call something when it is clicked, alternatively just add the onclick event manually:
<input type="submit" onclick="CallMyFunction()" value="Sign out">
Pass 'this' into it if you want to pass the input control into the function:
<input type="submit" onclick="CallMyFunction(this)" value="Sign out">
You probably don't want the submit button to post anything when you call your function as well, so you probably want something like:
<input type="submit" onclick="return CallMyFunction()" value="Sign out">
function CallMyFunction()
{
bool IsFormValid = false;
// Check if form is valid
return IsFormValid;
}
Assuming you don't have control over the HTML page and therefore cannot add an ID to the element, you could use the HtmlDocument.GetElementsByTagName to get all input elements, and then filter that collection by the type and value attributes. Something like:
var firstMatchingSubmit = (from input in myDocument.GetElementsByTagName("input")
where input.GetAttribute("type") == "submit" &&
input.GetAttribute("value") == "Sign out"
select input).FirstOrDefault();
if (firstMatchingSubmit != null)
{
firstMatchingSubmit.RaiseEvent("click");
}
Note that this approach is not appropriate if there are multiple matching elements (only the first one will be clicked).
What about this:
webbrowser1.Document.Forms[0].InvokeMember("submit");
How to handle page with multiple html submit button with no id? How to identify the submit button from 2nd row.Multiple html buttons