Question

I want to pass other value when checkBox is clicked. my code is as below

    foreach (var item in Model) {

              <td>
                    @Html.CheckBox("Project", false, new { item.ProjectId})
                </td>
}

Controller is

        [HttpPost]
        public ActionResult Test(FormCollection collection)
        {
            var test = collection["Project"];  }

in Var test i am getting True or False

Is there any way to get ProjectId??

Was it helpful?

Solution

The CheckBox and CheckBoxFor helpers are meant for bool and bool? properties (In fact, if you look at the source code you will see they force a casting of the property value to bool?. Check the method InputHelper here in the source code).

In the case of the CheckBox helper, the output will be something like this:

<input id="Foo" name="Foo" type="checkbox" value="true">
<input name="Foo" type="hidden" value="false">

As you can see, the values are hardcoded to true/false boolean values. You could override the value attribute but that would only apply to the checkbox and not to the hidden field with the value for when the checkbox is unchecked. Using the helper with non-boolean fields would also lead you to trouble because of the casting to bool? I mentioned above.

One possible solution would be to manually create the desired html. (You need to be carefull with the name attribute here as it is what the MVC model binder will use to populate your model). Writing something like this in your view:

<input id="Foo" name="Foo" type="checkbox" value="@item.ProjectId">
@* you could add another hidden input for when the checkbox is not checked *@

If you are using the model metadata or if you have complex bindings, this may be a problem as you would need to manually set the html attributes and be careful with the name attribute.

Another option is to create your own html helper. This could allow you to use other types not just booleans and should expect a value for when the checkbox has been checked. The idea is to create something like this:

public static class CustomHelpers
{
    public static MvcHtmlString CheckBoxNonBooleanFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object checkedValue)
    {
        var fieldName = ExpressionHelper.GetExpressionText(expression);
        var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
        var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);

        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        var value = metadata.Model;

        TagBuilder tag = new TagBuilder("input");
        tag.Attributes.Add("name", fullBindingName);
        tag.Attributes.Add("id", fieldId);
        tag.Attributes.Add("type", "checkbox");
        tag.Attributes.Add("value", (checkedValue ?? true).ToString());
        if ((checkedValue != null && checkedValue.Equals(value))
            ||(checkedValue == null && value == null ))
        {
            tag.Attributes.Add("checked", "checked");
        }

        var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
        foreach (var key in validationAttributes.Keys)
        {
            tag.Attributes.Add(key, validationAttributes[key].ToString());
        }

        return new MvcHtmlString(tag.ToString());
    }
} 

This helper can be used in your view as in the following example (Don´t forget to include your helper namespace into the views namespaces settings of the web.config in the views folder):

@Html.CheckBoxNonBooleanFor(m => m.Foo, 132)

And it will generate the following html, taking care of things like the metadata attributes, the name, the checked attribute, etc for you.

<input id="Foo" name="Foo" type="checkbox" value="132" data-val="true" data-val-number="The field Foo must be a number.">

If needed, you could easily extend it adding another parameter uncheckedValue that will add a hidden input field with the desired value for when the checkbox remains unchecked. You could also add the htmlAttributes parameter to allow you passing additional random html attributes.

As a final comment, just double check that radio buttons won´t be a fit for your requirements, as you could easily have multiple radio buttons for the same field with different int values.

OTHER TIPS

I'm assuming you want the projectid given a checkbox is checked?

<td>
    @Html.Hidden("projectId", item.ProjectId)
    @Html.CheckBox("selected", false)
</td>

[HttpPost]
public ActionResult Test(int projectId, bool selected)
{
    if (selected)
    {
        ///use your projectId
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top