MVC action on submit button press - asp.net-mvc

I have a site that searches through a db and pages the results. I want to make it so whenever there is a new search the page index defaults to 1. To do this I want to pass a flag when the submit button is pressed to tell the controller to modify the page index. I thought you might be able to pass the value with the onclick attribute but haven't had any success.
Here is my code for the search text box and submit button (without my failed attempt at using the onclick attribute).
Find: #Html.TextBox("SearchString", ViewBag.CurrentSearch as string)
<input type = "submit" value = "Search"/ >

this answer is supplied to address your original question in order to not require major refactoring (see final comment for my suggestion). so, use a hidden input as such:
Find: #Html.TextBox("SearchString", ViewBag.CurrentSearch as string)
<input type="hidden" name="lastSearchValue" ViewBag.LastSearch as string />
<input type = "submit" value = "Search"/ >
then, when you POST the form, check to see if the value of lastSearchValue and SearchString are the same, if so do what you need to do. if i understand your reasoning, then the final step would be to set ViewBag.LastSearch to the value of the last set ViewBag.CurrentSearch.
A better solution would be to use a SearchViewModel to encapsulate all of this logic in a self contained way. This gives the benefit of not having disparate logic spread across different concerns.

You could use a hidden input:
Find: #Html.TextBox("SearchString", ViewBag.CurrentSearch as string)
<input type="hidden" name="resetPageIndex" value="true" />
<input type = "submit" value = "Search"/ >
The input value will get sent with the form submission. You'll have to update the POST parameter accepted by your controller accordingly.

You can pass the flag as a hidden input on the form:
#Html.Hidden("FlagValue", Your_Flag_Value);
Find: #Html.TextBox("SearchString", ViewBag.CurrentSearch as string)
<input type = "submit" value = "Search"/ >

Related

Dynamic Form in ASP.NET MVC3 Razor

I have a small problem.
I want to have dropdown list with some objects. After clicking on one I want to add it to list with textfield for naming it. I don't want to limit quantity of this fields. I want to receive in controller ID (stored in dropdown list) and name (given by user) for each selected item. How can I do it?
I was thinking about storing it in some fields as a text, and parsing in cotroller but I think it's not elegant.
EDIT.
Ok, Thansk for your help, but it's not working for me correctly.
I generate html like this:
<input type="hidden" value="96" name="Inputs[0].Key">
<input type="text" name="Inputs[0].Value">
In my controller I'm receiving this dictionary. The problem is that quantity of elements is correct, but all values are null. What is wrong here?
The best way to go about this is by using array-style model binding.
So, for each element you wish to name you create a hidden field to store the drop down value plus a text field to store the user-given name. You name them as follows:
<input type="hidden" name="element[0].Key" /><input type="text" name="name[0].Value" />
increasing the index value each time. This is easily achieved with a bit of JavaScript. You then create an action method which takes a KeyValuePair<string, string>[] as a parameter. You will then be able to parse through your values no problem with a loop or LINQ expression.
Use IEnumerable<KeyPairValue<string,string>> MySelectedItem = new List<KeyPairValue<string,string>>(); on model, and when adding it to the list, name it like an array:
MySelectedItem[1].Key, MySelectedItem[1].Value, MySelectedItem[2].Key...
(I haven't tested this, but it should work)
Edit: check out this blog post with better explanation on how to do it: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

How to mimic MVC's checkbox -> bool model binding?

I've got an editor template which renders out a checkbox:
#Html.CheckBoxFor(model => model.Follow)
Which renders something like this:
<input checked="checked" data-val="true" data-val-required="The Follow field is required." id="Follow" name="Follow" type="checkbox" value="true" />
<input name="Follow" type="hidden" value="false" />
AFAIK the hidden field is something to do with catering when an unchecked box isn't sent to the server or something.
Anyway, if i take a look at the Request.Form["Follow"] when the checkbox is checked, i see a value of "true,false".
How do i coerce a bool from this value? Do i simply ignore the second field? (e.g the hidden field).
I'm doing this is a base controller (protected method, invoked from child controller), so i don't have a strongly-typed view model, only the raw Request object.
Can anyone help? Or alternatively, if someone could point me to where in the MVC source code this happens, i could take a look myself, but not sure where to start looking.
You are correct the hidden field is just so the form will be submitted to the server. Because if the form had just checkboxes that are not checked then nothing will be submitted and the server would not know to set them to false.
You only require 1 hidden field per form, you do not need one per checkbox. But if your making your own control it is hard to tell if a hidden textbox is already on the field or not. If you know you are always going to have a textbox or select list etc somewhere else on your forms you do not need a hidden textbox at all
You can rename your hidden textbox to anything name it "dummy" or something different to the checkbox name so Request.Form["Follow"]; will only return the value of the check box not need to split. You never need to check the value of the "hidden textbox".
On a side note you shouldn't be using Request.Form["Follow"] you Action method should have a parameter like this instead "bool? follow"
MVC helper renders checkbox input control with two input fields, the checkbox and the hidden, because the browser do not send a value for checkbox input field if the checkbox is not selected. If you do not use auto mapping, you need to parse the input value that you receve from your form.
Use this simple rule to detect the checkbox:
var rawFollow = Request.Form["Follow"];
if (rawFollow.Contains("true"))
{
// do something
}
As far as i know, the extra hidden field is because if the checkbox is NOT checked, that input will not be submitted with the form and therefore we need the hidden field with the value of false.
So the only solution is can think of is this:
var rawFollow = Request.Form["Follow"];
var rawFollows = rawFollow.Split(',');
if (rawFollows.Count() > 1)
{
rawFollow = rawFollows[0];
}
But this seems hacky (and what about the order of the elements on the page, what if for some reason the hidden field was FIRST, then it would always evaluate to false), which is why i'm wondering how the MVC source does this.

Setting the value of a textbox to a user entered value

How can I set the value of a textbox to user entered value.
For ex
<input type = "text" name = "somename" value = "">
If the user enters "3" then it should become
<input type = "text" name = "somename" value = "3">
All I want is that when I process the textbox for value in a servlet, I should be able to get the value 3 for that textbox. well, there is more to it as David says. The textbox is part of a cart application and it denotes quantity of an item. What I want to do is to be able to take the value of any item and store it in the database. I will have a default value of 1 for every textbox. But when I POST the data, I want it to post the value entered by the user and not the default value
The value in the textbox is automatically transferred to the server when you submit the form as somename=3 (or whatever value).
However, if you want to actually update the value attribute of the element, you could use jQuery to do something like:
HTML
<input id="name" type="text" name="somename" value="">
jQuery
$('#name').change(function(){
$(this).attr('value',$(this).val());
});
Javascript
(untested, but might work if you don't want to use jQuery)
<input type="text" name="somename" value="" onchange="this.attributes['value'] = this.value;">

asp.net MVC checkbox headache!

I have seen lots of questions relating to this topic.
I am using asp.net MVC 1.0
Problem area
If I use
<%= Html.CheckBox("Status", true) %>
Then why It renders like
<input checked="checked" id="Status" name="Status" type="checkbox" value="true" /><input name="Status" type="hidden" value="false" />
I put this in foreach loop and I have 5 rows.
when I submit form with true,true,true,false,false
then I get true,false,true,false,true,false,false,false
i.e. for false => false.
for true => true,false
If I use
<input type="checkbox" value="true" name="Status" checked="checked" />
Then I don't get unchecked one's.
so how do I overcome form this problem?
Please don't post answer with using loop in formcollection object and checking each key!
I know this isn't the elegant one but this is what I did:
collection["response"].Replace("true,false", "true").Split(',').ToList();
In your example, when you submit form with true,true,true,false,false and you get
true,false,true,false,true,false,false,falseit is interesting to note that you are not actually getting eight values back, but five arrays that merely looks like this is the case because all of the values are joined.
I know you asked to not get a loop for your answer, but I can use one to demonstrate what is really happening here:
foreach (string key in postedForm.AllKeys) {
// "value" will contain a joined/comma-separated list of ALL values,
// including something like "true,false" for a checked checkbox.
string value = postedForm[key].GetValue;
// "values" will be an array, where you can access its first element,
// e.g., values[0], to get the actual intended value.
string[] values = postedForm.GetValues(key);
}
So, for your checked boxes, you'll get a values array with two elements, and for unchecked boxes, you'll get just a single-element array.
Thus, to answer your question how do you overcome this problem, the answer lies in using GetValues rather than GetValue, and thinking of your posted fields as arrays rather than strings.
Best of luck!
Personally I think having to check for "true,false" everywhere on the server is a pain. I wrote a jquery fix that will remove the extra hidden field created by the Html.Checkbox helper when a box is checked, then add it back if the box is unchecked. Server values will always be "true" or "false". Checkbox lists are kind of subjective in how you want them to act, which I discuss, but I'm removing "false" from the value set, which means the form value will be excluded if all boxes in the list are unchecked.
http://www.mindstorminteractive.com/blog/?p=386
I've had pretty good success using this technique. Please let me know if you try it out and have issues.
You'll have to do your own model binding for the CheckBox values.
Get the list of values from the FormCollection or Request.Form for that CheckBox id and replace true,false with true:
string chkBoxString = Request.Form["checkboxID"].Replace("true,false", "true")
Now you have a list of whether a CheckBox was selected or not.... do the rest yourself :)
It renders so because default binder requires the FormCollection to have a value for nonnullable parameters. Using this technique we are sure that the value will be sent even the checkbox is not checked (by default the value sent only when it's checked). If you use this controller method with just one html input you'll get error on form post with unchecked checkbox (value of checkbox will not be posted and binder will not know what to use for value of isItemSelected):
public ActionResult SomeActionMethod(bool isItemSelected)
You can try use something like this with just one html input:
public ActionResult SomeActionMethod(bool? isItemSelected)
But in this case isItemSelected will be null or will be true. And it will never become false.
Well there are couple of ways you can do based on your requirement.
I use this method.
<input type="checkbox" value="<%= item.ID %>" name="check" checked="checked")" />
This is may checkboxes.
On server side I will also have array of ID's of item in the model.
So I check it whether it is in array
var strArray = form["checkbox"]; //Request.form["checkbox"] or "FormCollection form" in action parameter; array of ID's in comma separated string.
Different people have different tests.
this was intended to use for just just simple CheckBox, what you want is checkboxList, which is not yet cover in the API of ASP.net MVC
If you looking for some thing like checkboxlist, maybe you should write your own helper, provide you understand HTML well..
That's it! :)
Easier just to check whether AttemptedValue.Contains("true") - it will, if it's checked, not if it's unchecked....
in the View :
<input id="radio5" type="checkbox" name="rb_abc" value="5"/>
Controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult YourForm(FormCollection fc)
{
if (fc["rb_abc"] == "on")
{
//Hey .. you have selected a Radio Button.. just kidding.. its a CheckBox
}
}
To get checkbox value even it is true or false
var boolValue = bool.Parse(collection.GetValues("checkboxID")[0])

How can I get Html.CheckBox() as boolean during POST in custom IModelBinder?

I am using Html.CheckBox(). The resulting HTML is:
<input id="IsMultiGraph" name="IsMultiGraph" value="true" type="checkbox">
<input name="IsMultiGraph" value="false" type="hidden">
On the server I have an Action which is accepting the form post information and using a custom IModelBinder to bind the form results to one of my models. Here is a snippet of the code I am running in the IModelBinder:
bool isMultiGraph;
if (!bool.TryParse(bindingContext.HttpContext.Request["IsMultiGraph"], out isMultiGraph))
bindingContext.ModelState.AddModelError("IsMultiGraph", "Invalid boolean for \"IsMultiGraph\""); //this should not ever happen unless someone is programatically posting
result.IsMultiGraph = isMultiGraph;
The problem is that since Html.CheckBox() is rendering a checkbox as well as a hidden input field if I change the state of the textbox the postback value is doubled (ie. "true,false").
I understand why this is done and I'm looking for the best way to parse the current value of the CheckBox during a postback (checked = true, unchecked = false). Is there another helper method in MVC for this or should I just write my own?
One way is to use the GetValues method of the NameValueCollection class in order to get the first value of the array property like this:
bindingContext.HttpContext.Request.Form.GetValues("IsMultiGraph")[0]

Resources