I have the following form
<form name="SearchForm" method="post" id="SearchForm" action="/Search/">
And the following button
<input type="button" onclick="javascript:document.SearchForm.submit();" class="btn-leftsearch">
On clicking this button, the form submits and calls this method
[HttpPost]
public ActionResult Index(string querystring)
{
return View();
}
Of course querystring is null. I want to pass querystring or preferably something else representing the fields in the form to the controller. I have tried playing with the action attribute in the form tag. I have tried to add the data to the onclick method in the button. Nothing is working. All I want to do is pass some data like this
Search?pri=all&amenity=pool etc
In the controller I would have something like
[HttpPost]
public ActionResult Index(string pri, List<string> amenities)
{
...
}
Can someone tell me how I can pass this data to the view?
I would like to suggest you that you can use the following code snip to resolve you problem.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection collection)
{
string valueFromNameTextBox = collection["name"];
}
on the collection please put the name of the search text box. You wil get the actual entered value.
You can index into this collection with the names of all the inputs on the form.
Related
I have a scaffold list type table in my view. Above to the table, I have two checkboxes also. When I click on Edit link I need to pass the selected Id as well as the CheckBoxes' value also.
I can use ActionLink to pass the primary key value like
#Html.ActionLink("Action","Controller", new { id=#item.Id })
I can get the CheckBoxes Value by wrapping them into a Html.Beginform like,
#using(Html.BeginForm("Action","Controller",FormMethod="Post"){
<input type="checkbox" name="Check" value="1" />
<input type="checkbox" name="Check" value="2" />
-- table
<input type="Submit" value="Edit"/>
and in my controller, I can handle this like
[HttpPost]
Public ActionResult Edit(IEnumerable<string> check)
{ }
Here, I need to get both the Primary key value as well as Checkboxes' value, I tried in these two ways, and I could get any one of these only. Can anyone help me to get both the values? Thanks in advance.
You can include id in the action parameter. Like
[HttpPost]
Public ActionResult Edit(IEnumerable<string> check, int id)
{ }
Also, you will need to post the form using a submit button not the action link.
So, for sending the id, you will need to put it in a hidden field and it will automatically be sent on post.
Make sure you name the hidden field the same as the parameter name i.e. "id".
Edit
Do like this:
Take a hidden field in form: like this:
<input type="hidden" id="hf" value="TEst" name="hid" />
Then take a edit button in each row and make it call a javascript function. Like below:
<button type="button" onclick="clickfunc(#item.UniqueId)">Edit</button>
Next Come in Javascript and set hidden field and then do a form submit. Like below:
#section scripts{
<script type="text/javascript">
function clickfunc(id) {
$("#hf").val(id);
$('form').submit();
}
</script>
}
Now you get the values in your controller action. In my example it looks like:
public ActionResult EditTry(string hid)
{
return View();
}
You will get selected value in "check" string
To get the name type jquery on submit button click and store it in hidden field and access the hidden field from form collection
var getval = $("#Check option:selected").text();
$("#hdnText").val(getval);
This is controller Code:
[HttpPost]
Public ActionResult Edit(string check, FormCollection collection)
{
string strText = collection["hdnText"].ToString();
string strValue = check;
}
I have created view page in MVC like
<%using (Html.BeginForm())
{ %>
<%=LabelHelpers.Label("firstname", "FirstName:")%>
<br/>
<%=Html.TextBox("firstname")%>
<br/><br/>
<%=LabelHelpers.Label("lastname", "Lastname:")%>
<br/>
<%=Html.TextBox("lastname")%>
<br/><br/>
<input type="Button" value="Register"/>
<%} %>
Here I want to write Buttonclick Event ...How and Where should i write?
Your input is of type button - these don't do anything without additional client side code.
If you want to handle the 'event' on the server in a similar way that you would have in ASP.NET, you should convert it to a submit button. Assuming your controller is called 'Account' and your action is called 'Register' your current code would look something like this:
public ViewResult Register()
{
return View();
}
You want to start by passing a model to the view:
public ViewResult Register()
{
var registerModel = new RegisterModel();
return View(registerModel);
}
Your current view is using loosely typed inputs. Since you're passing it a model you can use strongly typed views. Your model should look something like this:
public class RegisterMode
{
public string Firstname { get; set; }
public string Surname { get; set; }
}
To use strongly typed views, change your view to look like this:
<%using (Html.BeginForm())
{ %>
<%=Html.LabelFor(x => x.Firstname)%>
<br/>
<%=Html.TextBoxFor(x => x.Firstname)%>
<br/><br/>
<%=Html.LabelFor(x => x.Surname)%>
<br/>
<%=Html.TextBoxFor(x => x.Surname)%>
<br/><br/>
<input type="submit" value="Register"/>
<%} %>
What we've done is told the view to build labels and text boxes for your RegisterModel type. This will allow the model values to be automatically mapped when you POST the form to the controller.
Do accept the post, we need to add a new Action to the controller, with the same name, but accepting a parameter of type RegisterModel:
public ActionResult Register(RegisterModel model)
{
// do something with the model, such as inserting it into the database.
// model.Firstname will contain the value of the firstname textbox
// model.Surname will contain the value of the surnaem textbox
return RedirectToAction("Success");
}
One last thing to do, to be safe, is to add the [HttpGet] and [HttpPost] attributes to your controller actions to control the methods they accept:
[HttpGet]
public ViewResult Register()
and
[HttpPost]
public ActionResult Register(RegisterModel model)
I suggest you read up on MVC at http://www.asp.net/mvc and read the NerdDinner tutorial chapter in Professional MVC (available for free online in PDF format).
joining to the question, want to make it more concrete
i have a form, the form already has a submit button, but i need to bind an additional action to another button.
yes, i do know that MVC does not support events 'cause HTML forms doesn't support them.
so the solution i've came to is to create to hidden inputs inside the form and bind an 'onclick' event (jquery 'live' method) to every... oh, what the hell? here is the code:
html:
<input type="hidden" id="SenderControlID" name="SenderControlID" value="-1" />
<input type="hidden" id="SenderControlValue" name="SenderControlValue" value="-1" />
js:
if ($('#SenderControlID')[0]) {
$('input[type="submit"], input[type="button"], input[type="checkbox"], input[type="radio"]').live('click', function () {
$('#SenderControlID').val($(this).attr('name'));
$('#SenderControlValue').val($(this).val());
});
}
but maybe there is more elegant solution?
Which of these two scenario's is best practice in ASP.NET MVC?
1 Post to self
In the view you use
using (Html.BeginForm) {
...
}
And in the controller you have
[HttpGet]
public ActionResult Edit(int id)
[HttpPost]
public ActionResult Edit(EditModel model)
2 Post from Edit to Save
In the view you use
using (Html.BeginForm("Save", "ControllerName")) {
And in the controller you have
[HttpGet]
public ActionResult Edit(int id)
[HttpPost]
public ActionResult Save(EditModel model)
Summary
I can see the benefits of each of these, the former gives you a more restful style, with the same address being used in conjunction with the correct HTTP verb (GET, POST, PUT, DELETE and so on). The latter has a URL schema that makes each address very specific.
Which is the correct way to do this?
For a RESTful controller:
// return an HTML form for editing a specific entity
public ActionResult Edit(int id) { }
// find and update a specific entity
[HttpPut]
public ActionResult Update(EditModel userView) { }
And in the View:
<% using (Html.BeginForm<HomeController>(c => c.Update(null))) {%>
<%: Html.HttpMethodOverride(HttpVerbs.Put) %>
<%: Html.EditorForModel() %>
<input type="submit" value="Save" />
<% } %>
Post to the same action.
Otherwise if validation fails in Save you would need to redirect to Edit. You would have to store errormessages in Tempdata and repopulate ModelState from it.
I prefer to use Edit/Update as I think it makes it clearer on what the action is doing. Stephen Walther has some good suggestions for standard action names using that convention.
I don't think it really maters but I would say being consistent throughout all your controllers is more important.
As a side note, if REST is a requirement of yours then I believe the following is more true to a RESTfull app:
[HttpGet]
public ActionResult Customer(int id) {
//return customer details
}
[HttpPut]
public ActionResult Customer(Customer cust) {
//update customer
}
[HttpPost]
public ActionResult Customer(Customer cust) {
//insert new customer
}
If REST ins't required then I'd go with Edit/Update convention
I have a edit View - Product/Edit/1
1 being the Id of the Product.How can I set the action of the edit post in the View to the POST edit action
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int Id, FormCollection collection)
The form tag is prepopulated as
but I want to set it to /Product/Edit/1
I am using this
<%using (Html.BeginForm()){ %>
but know its not right.Can someone help me how to set the form action using the htmlhelper class extension method to the Url in the browser
If you look at the intellisense for creating a Form with the HtmlHelper you will see there are parameters for specifying routeValues (of type object). Here you can specify the ID.
Your Edit View will be strongly typed with your Product object so you can specify Model.ID.
<% using (Html.BeginForm("Edit", "Product", new { Id = Model.ID } %>
...
I have forms in my page a get and a post and i want add pager on my get form .. so i cant page through the results..
The problem that i am having is when i move to the second page it does not display anything..
I am using this library for paging ..
http://stephenwalther.com/Blog/archive/2008/09/18/asp-net-mvc-tip-44-create-a-pager-html-helper.aspx
this my actions code.
[AcceptVerbs("GET")]
public ActionResult SearchByAttraction()
{
return View();
}
[AcceptVerbs("POST")]
public ActionResult SearchByAttraction(int? id, FormCollection form)
{....
}
and this is what i am using on my get form to page through
<%= Html.Pager(ViewData.Model)%> //but when i do this it goes to
this method
[AcceptVerbs("GET")]
public ActionResult SearchByAttraction()
instead of going to this this
[AcceptVerbs("POST")] public ActionResult SearchByAttraction(int? id, FormCollection form)
which sort of makes sence .. but i cant really think of any other way of doing this
Any help would be very appreciated..
Thanx
I'd recommend against doing paging via HTTP POST. Page and search criteria are 2 perfect examples of what querystrings are meant for. Put those values in the query string & have that load up your action args.
Think about this. You can search google for "pies", navigate to page 14, copy the link and send it to your grandma. You can't do that when your paging/search only works with form posts.
Of course it will hit the GET version of SearchByAttraction because using this control you have a links as output.
So what you need to do:
1. make form on the page:
<form id="myForm" action="your/url" method="post">
<input type="hidden" name="page" />
<input type="hidden" name="your_param1" />
<input type="hidden" name="your_param2" />
<input type="hidden" name="your_paramN" />
</form>
2. make changes to pager - it should produce something like that:
<ul id="pager">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
3. add simple javascript function on the page:
<script language="javascript" type="text/javascript">
function submitMyForm(page) {
var form = document.forms["myForm"];
form.elements["page"].value = page;
form.submit();
return false;
}
</script>
And you will be able to hit the POST version, because clicking the link will submit your form on the server using POST request.
Thanx everyone i finally got it working .. just used one form .. and did something like this
Controller Actions
[AcceptVerbs("GET")]
public ActionResult SearchByAttraction()
{
return View();
}
public ActionResult Search(FormCollection form,int? id)
{
var info = _repository.ListByLocation(city, postal, pageIndex, 2);
return View("SearchByAttraction", info);
}
View
<% using (Html.BeginForm("Search", "Home", FormMethod.Get))
{ %>
so it calls the search method every time it does a post..
Try this:
[AcceptVerbs("GET")]
public ActionResult SearchByAttraction(int? id)
{
return View();
}
id should contain the page number you need to display.
If you lose form values using this approach then you'll need to change the Html.Pager method to render each action link as a form submit link.