0

I'm using a checkbox to handle allow Ordering function, which generates HTML code below:

@using (Html.BeginForm("EditFarm", "CustomerManagement", FormMethod.Post))
{
  @Html.AntiForgeryToken()
  @Html.ValidationSummary(true)
  @Html.HiddenFor(model => model.AllowOrder)

 <div>
   <label for="allowOrder">Allow Ordering</label>
   <br />
   <input type="checkbox" id="allowOrder" name="AllowOrder" value="true" @(Model.AllowOrder ? "checked" : "") />
 </div>
....
}

The problem is checkbox AllowerOrder always pass true value to Controller even when it's unchecked

This is code in Controller:

public ActionResult EditFarm([Bind(Include = "Id, ERPCustomerCode, ERPId, CategoryId, Size, Large, OtherId, AllowOrder")] NewFarm farm)
        {
           ...
        }

Tried the debug, received model always have AllowerOrder = true. enter image description here

Is there any issue in my code? Any help would be appreciated! Thanks!

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
vyclarks
  • 854
  • 2
  • 15
  • 39
  • On top of Yauhen's comment, your checkbox doesn't seem bound to `AllowOrder`. This one is more likely bound to it: `@Html.HiddenFor(model => model.AllowOrder)` – Rafalon Mar 19 '19 at 07:43
  • 1
    You should use `@Html.CheckboxFor`. Check [here](https://stackoverflow.com/questions/12674572/proper-usage-of-net-mvc-html-checkboxfor) – Chetan Mar 19 '19 at 07:45
  • Most likely `@Html.HiddenFor(model => model.AllowOrder)` overrides the checkbox value because it generates ``. Note that both elements have same `name` attribute. – Tetsuya Yamamoto Mar 19 '19 at 07:46
  • This is because value is "true" which is sent in post. bind the value attribute to your model property i.e. AllowOrder – Kumar Lachhani Mar 19 '19 at 07:48
  • @KumarLachhani would you please show me by code? thought it's already `bound by '@(Model.AllowOrder ? "checked" : "")` – vyclarks Mar 19 '19 at 07:53
  • @TetsuyaYamamoto so I deleted `@Html.HiddenFor(model => model.AllowOrder)` but it doesn't work then – vyclarks Mar 19 '19 at 07:55
  • 1
    I recommend using `@Html.CheckBoxFor`, what thing doesn't work? Is that related to `checked` attribute? I think just putting `name` attribute with `input` element is not enough to bind checkbox value for viewmodel property. – Tetsuya Yamamoto Mar 19 '19 at 07:56
  • 1
    Agree with @TetsuyaYamamoto, a. Delete @Html.HiddenFor(model => model.AllowOrder) b. Use @Html.CheckBoxFor instead of `````` – Robin Ding Mar 19 '19 at 07:58
  • @TetsuyaYamamoto Oh thanks, I've just tried using `@Html.CheckBoxFor `, and it works now. But it seems like `` should work cause I used to use it for ` – vyclarks Mar 19 '19 at 08:05
  • could ya make an official answer for me to vote it as right one? Thank you so much. @TetsuyaYamamoto – vyclarks Mar 19 '19 at 08:06

1 Answers1

1

The most possible cause is you're binding to AllowOrder property using HiddenFor helper before using <input type="checkbox" />, which will generate input elements in this order:

<input name="AllowOrder" type="hidden" ... />

<input type="checkbox" id="allowOrder" name="AllowOrder" value="true" ... />

Since there are 2 input elements with same name attribute value, only the first <input> element will bound to viewmodel property, which contains true value in your case. Instead of creating checkbox manually with <input> tag and hidden field separately, you should use @Html.CheckBoxFor() helper and toggle checked attribute using a helper function below or use ternary operator:

public object SetChecked(bool value)
{
    if (value)
    {
        return new { id = "allowOrder", @checked = "checked" };
    }
    else
    {
        return new { id = "allowOrder" };
    }
}

Checkbox

@* alternative 1 *@

@Html.CheckBoxFor(model => model.AllowOrder, @(SetChecked(Model.AllowOrder)))

@* alternative 2 *@

@Html.CheckBoxFor(model => model.AllowOrder, new { id = "allowOrder", @checked = @(Model.AllowOrder ? "checked" : "") })

Note: checked is a C# keyword, hence it needs to be escaped with @ to set it as HTML attribute of rendered <input type="checkbox" />.

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • Note that the `SetChecked` function (as you wrote it) is only usable for one checkbox, as you set the `id` without a parameter. Hence I would rather use the second alternative, or add an `id` parameter. – Rafalon Mar 19 '19 at 13:08