KKS
KKS

Reputation: 3630

The checkbox doesn't update the bool property from false to true in mvc application

The ViewModel has the following code:

public List<MarketingCode> MarketingCodes { get; set; }

Where MarketingCode is of type:

public class MarketingCode
{

    public bool selected
    {
        get;
        set;
    }
    public MarketingOptionCode name { get; set; }
    public string Line { get; set; }
    public string value { get; set; }

    [Flags]//Indicates that an enumeration can be treated as a bit field; i.e., as a set of flags
    public enum MarketingOptionCode
    {

        Email = 1,

        Post = 2,

        SMS = 3,

        Telephone = 4
    }

}

My view has following code to render CheckBoxList:

 @for (int i = 0; i < Model.MarketingCodes.Count(); i++)
                                    {
                                        var name = @Model.MarketingCodes[i].name.ToString();
                                        <label for="@Model.MarketingCodes[i].name" class="checkbox inlineblock">
                                            @Html.CheckBoxFor(model => model.MarketingCodes[i].selected, new { name = @Model.MarketingCodes[i].name.ToString(), @id = @Model.MarketingCodes[i].name.ToString() }) **@* This works totally fine, even if you click the label, the checkbox will be checked. *@**

                                            @Model.MarketingCodes[i].name
                                        </label>
                                    }

As you can see the CheckBoxes are bind with the selected property but it doesn't get update to true when CheckBox is clicked! The same approach works fine if there is only a single CheckBox. But as such I am using a loop it is not working when I read the value of the property MarketingCodes in my controller, all the selected property is false.

The controller code where I am fetching the values from UI:

I have written this private function to call when the index get method fires and also when the post method fires because the viewmodel was not holding any values when the form was posted. And I guess this is the point where all the selected property is set to false.

 private static void BindMarketingOptions(PersonalDetailsIndexViewModel viewModel)
    {
        viewModel.MarketingCodes = new[] { 

            new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.Email, Line= "line1", value="value1" },
            new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.Post, Line= "line2", value="value2"  },
                new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.SMS,Line= "line3", value="value3"  },
                    new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.Telephone, Line= "line4", value="value4"  }
                    }.ToList();
    }

I have changed the above method to the following to make my selected property work:

private static void BindMarketingOptions(PersonalDetailsIndexViewModel viewModel)
    {
        if (viewModel.MarketingCodes == null)
        {
            viewModel.MarketingCodes = new[] { 

            new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.Email, Line= "line1", value="value1"},
            new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.Post, Line= "line2", value="value2"},
                new Bike.ViewModels.MarketingCode { name = AQuoteBike.ViewModels.MarketingCode.MarketingOptionCode.SMS,Line= "line3", value="value3"},
                    new Bike.ViewModels.MarketingCode { name = Bike.ViewModels.MarketingCode.MarketingOptionCode.Telephone, Line= "line4", value="value4"}
                    }.ToList();
        }
        for (var i = 0; i < viewModel.MarketingCodes.Count(); i++)
        {
            viewModel.MarketingCodes[i].selected = viewModel.MarketingCodes[i].selected;
        }


    }
BindMarketingOptions(viewModel);
for (var i = 0; i <= viewModel.MarketingCodes.Count(); i++)
                {
                    UserField userField = new UserField();
                    if (viewModel.MarketingCodes[i].selected)  //<--FALSE FOR ALL THE CHECKBOXES
                    {
                        userField.Line = viewModel.MarketingCodes[i].Line;
                        userField.Type = viewModel.MarketingCodes[i].name.ToString();
                        userField.Value = viewModel.MarketingCodes[i].value;  
                        BikeQuote.BikeRisk.UserFields.Add(userField);
                    }
                }

Upvotes: 0

Views: 2238

Answers (2)

KKS
KKS

Reputation: 3630

The answer can be seen in the question itself. Overriding the name of the checkbox was not an issue, instead I want to override the name so that for attribute of label works with the name of the checkbox. So, if a user clicks the label, the checkbox is clicked. The actual problem was the way I was binding the data to the MarketingCodes property. I have given the old version as well as the updated version. And it works fine now.

Upvotes: 0

James
James

Reputation: 82136

You are changing the name property of each checkbox - which is what the default model binder uses to try bind the data to your model, best let MVC generate that for you e.g.

@for (int i = 0; i < Model.MarketingCodes.Count(); i++)
{
    ...
    Html.CheckBoxFor(model => model.MarketingCodes[i].selected);
    ...
}

Upvotes: 2

Related Questions