Lord-David
Lord-David

Reputation: 545

Handling Checkbox values in MVC 4

I have a check box inside a form in my MVC view like below :

<div class="row" style="width: 98%;">
  <div class="col-md-1" style="width: 22%;">Active</div>
  <div class="col-md-1" style="width: 23%;">
    <input type="checkbox" ID="chb_Active" style="color: #428bca;">
  </div>
  <div class="col-md-1" style="width: 22%;">Inactive</div>
  <div class="col-md-1" style="width: 23%;">
    <input type="checkbox" ID="chb_Inactive" style="color: #428bca;">
  </div>
  <div class="col-md-1" style="width: 20%;"></div>                          
</div>

On my controller the ActionResult method looks like below.

public ActionResult MethodName(string submit, FormCollection collection) 
{
  bool chb_Active = Convert.ToBoolean(collection["chb_Active"]);
  bool chb_Inactive = Convert.ToBoolean(collection["chb_Inactive"]);
  //Some other operations
  //The return view
}

This is how I handled all my other controls(like dropdownlist) which works fine and gets the selected values.

The problem arises with checkboxes values, they are always set to False even thou I checked or unchecked them they always return a False.

I'm new to MVC please help or point me to the right direction. I have tried without the FormCollection and form still no positive results.

Most of the archives relating to this are not helpful in this situation as their checkboxes have values in them.

Upvotes: 1

Views: 1314

Answers (2)

dav_i
dav_i

Reputation: 28097

Form inputs are not picked up on the id attribute but the name attribute.

Changing your inputs to read:

<input type="checkbox" name="chb_Active" ...

will allow the data to be posted back to the controller. You also should add a value attribute and a hidden input as per Ben Griffiths' answer.


A better way to do this

The more MVC-y way to do this is to use View Models.

Create a folder /ViewModels/ControllerName and put a class in that (it doesn't actually have to be in this folder, but it's nice to follow the convention followed by views):

public class MethodNameViewModel
{
    public bool Active { get; set; }
    public bool Inactive { get; set; }
}

In view you can now do

@model ProjectName.ViewModels.ControllerName.MethodNameViewModel

<div class="row" style="width: 98%;">
    <div class="col-md-1" style="width: 22%;">
        @Html.DisplayNameFor(x => x.Active)
    </div>
    <div class="col-md-1" style="width: 23%;">
        @Html.EditorFor(x => x.Active, new { style = "color: #428bca" })
    </div>

    @* Same for other field *@

Then your post action becomes:

[HttpPost]
public ActionResult MethodName(MethodNameViewModel methodNameViewModel) 
{
    var active = methodNameViewModel.Active;
    var inactive = methodNameViewModel.Inactive

    // ... etc
 }

Upvotes: 4

Ben Griffiths
Ben Griffiths

Reputation: 1696

There are two issues here:

Firstly, your HTML inputs need a name attribute - not just an id - because it is the name which is used as the key in the form collection.

Secondly, they need a value. This is trickier, and is an age-old problem with checkboxes. By default, a browser will submit the value associated with a checkbox if it is checked, and will not submit anything if it is unchecked. Therefore, in order to make a checkbox submit true when checked and false when not checked, you need to do this:

<input type="checkbox" ID="chb_Active" name="chb_Active" value="true" style="color: #428bca;">
<input type="hidden" name="chb_Active" value="false">

(and similarly for your other checkbox, if you want to have two of them).

Using this setup, false will be posted back as the value of the chb_Active property of the form if the checkbox is not checked. If it is checked, then both false and true will be posted back, and ASP.NET will automatically pick out true for you if you use its model-binding feature, like so:

public ActionResult MethodName(string submit, bool chb_Active) {
    // ...
}

Upvotes: 4

Related Questions