MVC3 input submit - asp.net-mvc-3

I have an Index page in an MVC3 C#.Net web app. The Index View of my Proposal Model contains an input submit button:
<input type="submit" name="Create" id="Create" value="Create New Proposal" style="width: 200px" />
When the button is clicked, I want to invoke the Create View on the Proposal Model. However, I can't get any method in the Proposal Controller to fire when clicking on the "create New" input button. Can I call the Index Post method? The Proposal Create get method? Any ideas?

You need your submit button inside a form and an overloaded ActionResult in your controller which uses the HttpPost attribute.
Something like...
Controller
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// do stuff with model
}
View
#using(Html.BeginForm())
{
<input type="submit" value="Go" />
}
That would render a form and post it to the Index action result in your controller.

Try using an HTML Helper like #Html.BeginForm. See here for clues: http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform.aspx
In your case try this:
#using (Html.BeginForm("Create", "Proposal")){
......
<input type="submit" value="Submit" />
}

You have to write a post method and then use this for displaying your View
#using (Html.BeginForm("YourAction", "Controller", "FormMethod.Post"))
{
//your View code display
}

Related

Formcollection doesn't extract data from form MVC

I have trouble with formcollection.
I have some form in view, and two submit buttons both with unique name="". On debug I get on controller in formcollection all data except "name" of submitted button... I don't know why, 'cos I use this in other forms and there it works good. So I look at the code, but I couldn't find any differencies in using formcollection on not working formcol and working formcol. I tried rename buttons, move them, add referencies which I thought that could help... Nothing. On every submit skip my condition because it give me back only "false" and formcollection my "upload" or "save" button on onclick doesn't contain...
So I would like to ask you for help with this. Can you tell me where could be an error? Thanks to all!
This is in controller:
[HttpPost]
public ActionResult EditUser(EditUserVM model, int id, FormCollection c)
{
//c["upload"] is everytime set to null, 'cos c does't contain it
if (c["upload"] != null)
{
//.... some code
return RedirectToAction("Index", "Home");
}
if (ModelState.IsValid)
{
//.... next code
}
return View("EditUser", model);
}
This is in View:
#model PrukazOnline.ViewModels.EditUserVM
#{
ViewBag.Title = "EditUser";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>
#using (Html.BeginForm("EditUser", "User", null, FormMethod.Post, new { #class = "form-horizontal", id = "formstep", enctype = "multipart/form-data" }))
{
#*Here is some code - #Html.TextBoxFor(x => x.something) and #Html.ValidationMessageFor(x => x.something) - all of these are in formcollection*#
.
.
.
.
<div>
<input type="submit" value="Nahrát" class="upl" name="upload" id="upload" />
</div>
<div class="submit_buttons">
<input type="submit" name="save" id="save" value="Uložit" />
</div>
}
Issue is in multiple submit inputs in single form. There will only clicked button in FormCollection.
I suppose you try to vary form processing base on clicked button, in this case it's better to use different Actions for each button like this:
View:
<div>
<input type="submit" value="Nahrát" class="upl" name="upload" id="upload" />
</div>
<div class="submit_buttons">
<input type="submit" name="save" id="save" value="Uložit" />
</div>
Controller:
[HttpParamAction]
[HttpPost]
public ActionResult Upload(EditUserVM model)
{
...
}
[HttpParamAction]
[HttpPost]
public ActionResult Save(EditUserVM model)
{
...
}

Portlet:actionurl is not going to #Actionmapping in controller

I am using Liferay portal-6 with Spring-3.
In my portlet, first it goes to the #Rendermapping without params and displays the default jsp,
when I click on a button I am passing the actionurl, but its not going to the corresponding #Actionmapping.
My searchForm.jsp looks like this:
<portlet:actionURL var="showSearchResultsUrl">
<portlet:param name="myaction" value="searchResults" />
</portlet:actionURL>
<form:form id="searchForm" name="searchForm" commandName="patientStoryForm" method="POST" action="${showSearchResultsUrl}" enctype="multipart/form-data" >
<input type="button" name="search_btn" value="Search"/></td>
</form:form>
My controller is like this:
#Controller(value = "searchPatientStoryController")
#RequestMapping(value = "VIEW")
#SessionAttributes(types = PatientStoryForm.class)
public class SearchPatientStoryController {
#RenderMapping
public String showSearchForm(RenderResponse response, Model model) {
return "searchForm";
}
#RenderMapping(params = "myaction=searchResultsForm")
public String showSearchResultsForm(RenderResponse response, Model model) {
return "searchResultsForm";
}
#ActionMapping(params = "myaction=searchResults")
public void searchResults(
#ModelAttribute(value = "patientStoryForm") PatientStoryForm patientStoryForm,
BindingResult bindingResult, ActionResponse response, ActionRequest request,
SessionStatus sessionStatus, Model model) {
response.setRenderParameter("myaction", "searchResultsForm");
}
}
When I click on button in searchForm.jsp it is supposed to go to #Actionmapping but it is not going.
Please help me.
Thanks in advance.
You would need to submit the form in order to invoke the associated action method.
However, in the jsp code, I see the below code which indicates that it is just a button.
<input type="button" name="search_btn" value="Search"/>
In order to submit the form, you can do either of the following ways:
Use a submit button instead of a normal form button like this:
<input type="submit" name="search_btn" value="Search"/>
Invoke a javascript function on click event of the button and submit the form:
<script type="text/javascript">
function submitForm(form){
var actionUrl = '<portlet:actionURL var="showSearchResultsUrl"><portlet:param name="myaction" value="searchResults"/></portlet:actionURL>';
form.action = actionUrl;
form.submit();
}
</script>
and
<input type="button" name="search_btn" value="Search" onclick="javascript:submitForm(this.form)"/>
Can you try replacing your actionURL like the following
<portlet:actionURL name="searchResults" var="showSearchResultsUrl">
<portlet:param name="myaction" value="searchResults" />
</portlet:actionURL>
You need to set the action of your form, something like this:
<form:form action="<%=showSearchResultsUrl%>" id="searchForm" name="searchForm" commandName="patientStoryForm" method="POST" action="${showSearchResultsUrl}" enctype="multipart/form-data" >
<input type="button" name="search_btn" value="Search"/></td>
This way your action name will be "myaction" with the value "searchResults" as your mapping on the controller side.

ASP.Net MVC3: how to send different values for same field?

How can I send to action of controller different values for same field? Which input parameters should I define in action? And how can I show url with different values of identical fields in querystring? I want to get such url: site.com/directory?metro=2&metro=3
Thanks!
Here's an example of how this would be done in the case of checkboxes. Note that you wouldn't see the same querystring parameter repeated in the case of a GET request. Instead you would see "?metros=1,3" if checkboxes 1 and 3 were checked.
HTML
<form action="http://site.com/directory" method="get">
<input type='checkbox' name='metros' value='1' />
<input type='checkbox' name='metros' value='2' />
<input type='checkbox' name='metros' value='3' />
</form>
Controller
public class DirectoryController : Controller {
public ActionResult Index(IEnumerable<int> metros) {
foreach (var metro in metros) {
// do something
}
return View();
}
}

ASP.NET MVC 3 Multiple Submit Inputs in One Form

I am currently having an issue with multiple action buttons being in the same form.
The first button would perform verification while the second button would save profile. The third would simple redirect the user out of the page, but they are still required to go through controller some tracking purposes. Last button is delete. Because they are placed together and I do need ModelBinding passed through POST, it's impossible to separate them into multiple forms.
Currently, in order to differentiate which action is being clicked, I have a hidden input in my form and onclick, javascript would update the hidden input so that it will be passed back to the controller.
The reason I did this was because for some weird reasons, FormCollection doesn't want to hold my submit values. I tried accessing buttons in controller via
formCollection["verify"]
But it turns out to be null. Both id and name of the input submit is set to verify.
I also tried a lot of other suggestions like this and this but to no avail. Is there a better approach to my problem without using javascript to alter hidden inputs?
The best approach is to have separate actions handling the different button calls as explained in this article.
If you want to have one ugly action doing all the stuff then you could give your submit buttons names:
#using (Html.BeginForm())
{
... input fields for the model
<button type="submit" name="btn" value="verify">Verify data</button>
<button type="submit" name="btn" value="save">Save data</button>   
<button type="submit" name="btn" value="redirect">Redirect</button>
}
You don't need any hidden fields or javascript. And then in your controller action you would check for the value of the btn parameter (which obviously will be part of you view model):
[HttpPost]
public ActionResult Foo(MyViewsModel model)
{
if (model.Btn == "verify")
{
// the Verify button was clicked
}
else if (model.Btn == "save")
{
// the Save button was clicked
}
else if (model.Btn == "redirect")
{
// the Redirect button was clicked
}
else
{
// ??? throw
}
...
}
Of course if you follow my advice and separate your actions (as outlined in the article):
#using (Html.BeginForm("Action", "Home"))
{
... input fields for the model
<input type="submit" name="verify" value="Verify data" />
<input type="submit" name="save" value="Save data" />
<input type="submit" name="redirect" value="Redirect" />
}
and then:
[HttpParamAction]
[HttpPost]
public ActionResult Verify(MyViewModel model)
{
...
}
[HttpParamAction]
[HttpPost]
public ActionResult Save(MyViewModel model)
{
...
}
[HttpParamAction]
[HttpPost]
public ActionResult Redirect(MyViewModel model)
{
...
}
which is a far cleaner code which doesn't violate the Single Responsibility Principle.
I do something slightly different;
<input type="submit" name="submit" value="Save Draft" />
<input type="submit" name="submit" value="Publish" />
Then you can get at the values using;
FormCollection["submit"]
Thanks,
Matt
<input type="submit" name="nameONE" />
<input type="submit" name="nameTWO" />
[HttpPost, ActionName("OrginalActionName")]
[FormValueRequired("nameONE")]
public ActionResult WhateverYouWantONE(type name)
{
code...
}
[HttpPost, ActionName("OrginalActionName")]
[FormValueRequired("nameTWO")]
public ActionResult WhateverYouWantTWO(type name)
{
code...
}

MVC3 - Understanding POST with a button

How does one obtain the form data after submitting it?
<form target="_self" runat="server">
<p>
<select id="BLAHBLAH2">
<option>2010</option>
<option>2011</option>
<option>2012</option>
<option>2013</option>
</select>
<input type="submit" runat="server" value="Change Year" />
</p>
</form>
This hits the controller's Index method. But, there's nothing in Request.Form. Why?
Second, can I use
<input type="button" instead of type=submit? That is, without introducing ajax via onclick.
Finally, how do I submit to a different method in the controller, e.g. Create?
Try removing those runat server tags. They should not be used in ASP.NET MVC. Also your select doesn't have a name. If an input element doesn't have a name it won't submit anything. Also your option tags must have value attributes which indicates what value will be sent to the server if this options is selected:
<form action="/Home/Create" method="post">
<p>
<select id="BLAHBLAH2" name="BLAHBLAH2">
<option value="2010">2010</option>
<option value="2011">2011</option>
<option value="2012">2012</option>
<option value="2013">2013</option>
</select>
<input type="submit" value="Change Year" />
</p>
</form>
But the correct way to generate forms in ASP.NET MVC is to use HTML helpers. Depending on the view engine you are using the syntax might be different. Here's an example with the Razor view engine:
#model MyViewModel
#using (Html.BeginForm("Create", "Home"))
{
<p>
#Html.DropDownListFor(x => x.SelectedYear, Model.Years)
<input type="submit" value="Change Year" />
</p>
}
Here you have a strongly typed view to some given view model:
public class MyViewModel
{
public string SelectedYear { get; set; }
public IEnumerable<SelectListItem> Years
{
get
{
return Enumerable
.Range(2010, 4)
.Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
}
}
}
which is populated by some controller action that will render this view:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Create(MyViewModel model)
{
... model.SelectedYear will contain the selected year
}
}
None of your <option> tags have a value:
...
<option value="2010">2010</option>
...
As noted by David, runat="server" is most definitely a WebForms thing, so you can 86 that.
If you want to submit to a different method on your controller you just need to specify the URL for that method.
Easy way using Html.BeginForm:
#using (Html.BeginForm("AnotherAction", "ControllerName")) {
<!-- Your magic form here -->
}
Using Url.Action
<form action="#Url.Action("AnotherAction")" method="POST">
<!-- Your magic form here -->
</form>
You can also use
In Controller
int Value = Convert.ToInt32(Request["BLAHBLAH2"]); //To retrieve this int value
In .cshtml file use
<select id="IDxxx" name="BLAHBLAH2">
//Request[""] will retrieve the VALUE for the html object ,whose "name" you request.

Resources