Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC6 syntax for multiple checkbox form

I am building an ASP.NET MVC6 web application (ASP.net Core 1.0) and want a simple form which contains multiple checkboxes for a single property, allowing multiple selections. Lets say for argument's sake I want the user to check one or more checkboxes from a list of colours (Red, Blue, green, yellow etc).

I have three questions related to this...

1) What data type should the Colours property be in my view model (string, string[], bool[], List<String>, something else)? is SelectList still a valid thing in MVC6?

3) What is the correct syntax in my View for representing a list of checkboxes in the form? Should I be using the new Tag helpers feature here?

4) What should the input parameters be for my controller action? In asp.net 4.x it would be a FormCollection but not sure if that is still valid?

like image 690
Martin Kearn Avatar asked Oct 31 '22 08:10

Martin Kearn


1 Answers

I've just implemented something very similar:

Checkbox Model

public class CheckboxModel
{
    public int Value { get; set; }
    public string Text { get; set; }
    public bool Checked { get; set; }
}

ViewModel

public class MyViewModel
{
   public MyViewModel()
   {
       // populate checkbox collection with defaults here (or in your controller)
   }
   [AtLeastOneRequired(ErrorMessage = "Please check at least one checkbox.")]
   public class List<CheckboxModel> Checkboxes { get; set; }
}

View

@for (var i = 0; i < Model.Checkboxes.Count; i++)
{
    <div class="checkbox-inline">
        <input type="checkbox" asp-for="@Model.Checkboxes[i].Checked"/>
        <input type="hidden" asp-for="@Model.Checkboxes[i].Text" />
        <input type="hidden" asp-for="@Model.Checkboxes[i].Value" />
        <label asp-for="@Model.Checkboxes[i].Checked">@Model.Checkboxes[i].Text</label>
    </div>
}

I'd love to know if there's a tider way to do the view portion of this in MVC6, but I haven't found one yet.

Custom Validation Attribute

public class AtLeastOneRequiredAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        var vm = (MyViewModel) context.ObjectInstance;
        if (vm.Checkboxes.Any(v => v.Checked))
        {
            return ValidationResult.Success;
        }

        return new ValidationResult(ErrorMessage);
    }
}

The Controller Action is simply:

public async Task<IActionResult> MyControllerAction(MyViewModel vm)

I know this is an old question, but hopefully this answer helps someone else.

like image 148
Town Avatar answered Nov 11 '22 16:11

Town