Vikas
Vikas

Reputation: 24322

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!

Upvotes: 9

Views: 16843

Answers (10)

Yasser-Farag
Yasser-Farag

Reputation: 582

To get checkbox value even it is true or false

var boolValue = bool.Parse(collection.GetValues("checkboxID")[0])

Upvotes: 0

bluwater2001
bluwater2001

Reputation: 7959

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
      }
 }

Upvotes: 0

ShaneGray
ShaneGray

Reputation: 571

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 :)

Upvotes: 1

Mindstorm Interactive
Mindstorm Interactive

Reputation: 629

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.

Upvotes: 1

mansachs
mansachs

Reputation: 1

Easier just to check whether AttemptedValue.Contains("true") - it will, if it's checked, not if it's unchecked....

Upvotes: 0

DucDigital
DucDigital

Reputation: 4622

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! :)

Upvotes: 0

RailRhoad
RailRhoad

Reputation: 2128

I know this isn't the elegant one but this is what I did:

collection["response"].Replace("true,false", "true").Split(',').ToList();

Upvotes: 2

Vikas
Vikas

Reputation: 24322

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.

Upvotes: 0

Funka
Funka

Reputation: 4278

In your example, when you submit form with true,true,true,false,false and you get

true,false,true,false,true,false,false,false
it 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!

Upvotes: 1

zihotki
zihotki

Reputation: 5191

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.

Upvotes: 0

Related Questions