10

Sorry but most of my searches take me to old MVC codes. Any help will be appreciated.

In MVC 6 with tag helpers, how do you code a set of checkboxes:

  • Use tag helper for label so clicking it will toggle the checked value
  • Save (Bind?) the checked value to the IsOptionSelected property
  • Pass these checked values back to Controller after clicking Submit

?

I was able to display the checkboxes with labels correctly, but I do not know how to pass the checked values back to the controller via the model. Right now, IsOptionSelected values are coming back as false.

I was also able to make the html helper for the label work but not for the tag helper. I may be also coding these all wrong so any tips will help!

Here's what I have so far:

Display:

Phone Options Checkboxes

Entity:

public class PhoneOption
{
    public bool IsOptionSelected { get; set; } = false;
    public int OptionId { get; set; }
    public string OptionName { get; set; }
}

Model:

[Display(Name = "Phone Options")]
public IEnumerable<PhoneOption> PhoneOptions { get; set; }

. . . .
PhoneOptions = repository.GetPhoneOptions();

Repository:

public IEnumerable<PhoneOption> GetPhoneOptions()
{
    IEnumerable<PhoneOption> options = new[]
    {
        new PhoneOption { OptionId = 1, OptionName = "Phone Case",       IsOptionSelected = false },  
        new PhoneOption { OptionId = 2, OptionName = "Screen Protector", IsOptionSelected = false },
        new PhoneOption { OptionId = 3, OptionName = "Car Charger",      IsOptionSelected = false },
        new PhoneOption { OptionId = 4, OptionName = "Extra Cable",      IsOptionSelected = false }
    };
    return options;
 }

View:

<div class="form-group">
    <label class="control-label">Phone Options</label>
    <div>
        @foreach (var option in Model.PhoneOptions)
        {
            <div>
                @{ string cbId = "PhoneOption_" + @option.OptionId; }
                <input [email protected] type="checkbox" [email protected] id=@cbId name=@cbId />
                @Html.Label(@cbId.ToString(), @option.OptionName)
                @*This is causing invalid operation exception*@
                @*<label [email protected]()>@option.OptionName</label>*@ 
                <span asp-validation-for=@cbId class="text-danger" role="alert"></span>
            </div>
        }
    </div>    
</div>

Thanks in advance!

4
  • I guess the asp-for is used in a wrong way. Change in the input the [email protected] to asp-for="IsOptionSelected" that will make sure it is binded to the right property in PhoneOption. The same thing in the label [email protected]() is wrong.Check the tutorial here for tag helpers .davepaquette.com/archive/2015/05/18/mvc6-select-tag-helper.aspx Commented Apr 26, 2016 at 14:50
  • Thanks for suggestion, but changing to asp-for="IsOptionSelected" is throwing a syntax error since it is not in the main model. It is part of the Model.PhoneOption option foreach iteration. asp-for=option.IsOptionSelected also will not work. And yes, I already read the tutorial before but it did not cover the checkbox list like what I am trying to do. Commented Apr 26, 2016 at 17:49
  • 1
    Ahh I got it. Check this if it helps stackoverflow.com/questions/15375800/… Commented Apr 26, 2016 at 20:05
  • @AmeteGirl. +1 for the helpful link. Commented Apr 26, 2016 at 21:05

2 Answers 2

10

This is finally what I did to make it to work. I am not sure if this is the best way to do it. I had to still use the html helpers because the tag helpers do not work.

Model:

public List<PhoneOption> PhoneOptions { get; set; }
. . .
PhoneOptions = repository.GetPhoneOptions().ToList();

View:

@if (@Model.PhoneOptions != null && @Model.PhoneOptions.Count() > 0)
{
    for (int i = 0; i < @Model.PhoneOptions.Count(); i++)
    {
        <div>
            <input asp-for="@Model.PhoneOptions[i].IsOptionSelected" type="checkbox" />
            <label asp-for="@Model.PhoneOptions[i].IsOptionSelected">@Model.PhoneOptions[i].OptionName</label>

            @*If these are not included, all OptionIds become 0 and all OptionName becomes null*@
            @Html.HiddenFor(x => @Model.PhoneOptions[i].OptionId)
            @Html.HiddenFor(y => @Model.PhoneOptions[i].OptionName)
        </div>
    }    
}

I hope this helps someone else who is having the same checkbox list issues.

UPDATE: I've updated the html helpers to tag helpers above.

Sign up to request clarification or add additional context in comments.

5 Comments

Glad it worked for you.And thanks for posting your solution.
Using tag helpers should work fine - <input asp-for="Model.PhoneOptions[i].IsOptionSelected" type="checkbox" /> so long as you use a for loop and the collection is IList<T> (not IEnumerable<T>
Thanks, @StephenMuecke! I tried it and it worked with a little change - <input asp-for="@Model.PhoneOptions[i].IsOptionSelected" type="checkbox" id="@cbId" />. I still cannot make the tag helper for label to "attach" to the checkbox though. Both this: 1) <label asp-for="@Model.PhoneOptions[i].IsOptionSelected">@Model.PhoneOptions[i].OptionName</label> and 2) <label asp-for="@cbId">@Model.PhoneOptions[i].OptionName</label> are not clickable to toggle the checkbox value. If you know how, that will be great!
You need to remove the id attribute (the fact that its id="@cbId" suggests its not even unique and therefore your creating invalid html. - <input asp-for="@Model.PhoneOptions[i].IsOptionSelected" type="checkbox" /> and <label asp-for="@Model.PhoneOptions[i].IsOptionSelected">@Model.PhoneOptions[i].OptionN‌​ame</label>
@StephenMuecke. That was actually the first thing I tried and initially it did not work. That is why I resorted to the manual id assignment (it is actually unique because it the OptionIds are unique) but not a very elegant solution I know. And now I changed it back to what you also suggested her and now it works! (scratching head). Must be something else I had that prevented the label from attaching to the checkbox. But thanks a lot!
1

This is how the syntax should be in your for each asp-for should be wrapped in a string with quotation marks

 @foreach (var option in Model.PhoneOptions)
        {
            <div>
                @{ string cbId = "PhoneOption_" + @option.OptionId; }
                <input asp-for="@option.IsOptionSelected" type="checkbox" value="@option.IsOptionSelected" id="@cbId" name="@cbId" />
                @Html.Label(@cbId.ToString(), @option.OptionName)
                @*This is causing invalid operation exception*@
                @*<label asp-for="@cbId">@option.OptionName</label>*@ 
                <span asp-validation-for="@cbId" class="text-danger" role="alert"></span>
            </div>
        }

1 Comment

Sorry, I tried this but the IsOptionSelected values are still posting as false in the controller, even if the checkboxes are checked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.