Home How to bind MVC checkboxes to model
Reply: 2

How to bind MVC checkboxes to model

andrewb
1#
andrewb Published in 2018-02-13 18:29:42Z

This question already has an answer here:

  • Pass List of Checkboxes into View and Pull out IEnumerable [duplicate] 2 answers
  • Updating a list of objects in mvc4 1 answer

I have a view which outputs a list of questions. The user will select questions they want included in a report and then submit the form.

My view looks like:

@using (Html.BeginForm("Step6", "Home", FormMethod.Post))
{
  @Html.HiddenFor(m => m.EventID)
  @Html.HiddenFor(m => m.CompanyID)
  foreach (var item in Model.Questions)
  {
      <div class="checkbox">
      <input type="checkbox" id="@item.QuestionID" name="QuestionIds" value="@item.Title" />
      <label for="@item.QuestionID">@item.Title</label>
      </div>
  }
  <p><input type="submit" class="btn btn-primary" value="Submit" /></p>
}

Generated HTML looks like:

<div class="checkbox">
    <input type="checkbox" id="12" name="QuestionIds" value="Would you like an account manager to contact you?" />
    <label for="12">Would you like an account manager to contact you?</label>
</div>
<div class="checkbox">
    <input type="checkbox" id="13" name="QuestionIds" value="Comments - please be as detailed as possible." />
    <label for="13">Comments - please be as detailed as possible.</label>
</div>

Question collection:

public class Question
{
    public Guid QuestionID { get; set; }
    public string Title { get; set; }
}

Controller action

    [HttpPost]
    public ActionResult Step6(Models.EventCompanyQuestionnaireQuestions model)
    {
        return View();
    }

The model:

public class EventCompanyQuestionnaireQuestions
{
    public int EventID { get; set; }
    public int CompanyID { get; set; }
    public List<Guid> QuestionIds { get; set; }
}

When the form is submitted the List is an empty, initialized list. The rendered form element is named QuestionIds which matches the model. I need QuestionIds to have the checked checkboxes.

Dai
2#
Dai Reply to 2018-02-13 19:10:57Z

You need to use an indexed expression:

@using (Html.BeginForm("Step6", "Home", FormMethod.Post))
{
    @Html.HiddenFor(m => m.EventID)
    @Html.HiddenFor(m => m.CompanyID)
    for( Int32 i = 0; i < this.Model.Questions.Count; i++ )
    {
    <div class="checkbox">
        @Html.CheckBoxFor( m => m.Questions[i].Selected )
        @Html.LabelFor( m => m.Questions[i].Selected, this.Model.Questions[i].Title )
    </div>
    }
    <p><input type="submit" class="btn btn-primary" value="Submit" /></p>
}

Note that ideally, the <label> should wrap both the <input> and the text. I've also changed <input type="Submit" /> to <button>:

@using (Html.BeginForm("Step6", "Home", FormMethod.Post))
{
    @Html.HiddenFor(m => m.EventID)
    @Html.HiddenFor(m => m.CompanyID)
    for( Int32 i = 0; i < this.Model.Questions.Count; i++ )      {
    <div class="checkbox">
        <label for="@Html.IdFor( m => m.Questions[i].Selected )">
            @Html.CheckBoxFor( m => m.Questions[i].Selected )
            @this.Model.Questions[i].Title
        </label>
        @Html.HiddenFor( m => m.Questions[i].QuestionId );
    </div>
  }
  <p><button type="submit" class="btn btn-primary">Submit</button></p>
}
Tchaps
3#
Tchaps Reply to 2018-02-13 20:19:37Z

Here is my models:

 public class Question
{
    public int QuestionID { get; set; }
    public string Title { get; set; }
    public bool Selected { get; set; }
}

public class EventCompanyQuestionnaireQuestions
{
    public int EventID { get; set; }
    public int CompanyID { get; set; }
    public List<Question> Questions { get; set; }
}

Here is the view:

@using (Html.BeginForm("Edit", "Question", FormMethod.Post))
{
    @Html.HiddenFor(m => m.EventID)
    @Html.HiddenFor(m => m.CompanyID)
    for (int i = 0; i < this.Model.Questions.Count; i++)
    {
    <div class="checkbox">
        @Html.HiddenFor(m => m.Questions[i].QuestionID)
        @Html.CheckBoxFor(m => m.Questions[i].Selected)
        @Html.DisplayFor(m => m.Questions[i].Title)
    </div>
    }
    <p><input type="submit" class="btn btn-primary" value="Submit" /></p>
}

The controller for testing:

 // GET: Question
    public ActionResult Index()
    {
        EventCompanyQuestionnaireQuestions model = new EventCompanyQuestionnaireQuestions
        {
            CompanyID = 1,
            EventID = 2,
            Questions = new List<Question>
            {
                new Question {    QuestionID = 1,   Selected = false,  Title= "What is your name"  },
                new Question {    QuestionID = 2,   Selected = false,  Title= "How old are you"  },
                new Question {    QuestionID = 3,   Selected = false,  Title= "Where are you from"  },
                new Question {    QuestionID = 4,   Selected = false,  Title= "What is your profession"  },
            }
        };
        return View(model);
    }


    [HttpPost]
    public ActionResult Edit(EventCompanyQuestionnaireQuestions model)
    {
        var ids = model.Questions.Where(q => q.Selected).Select(q => q.QuestionID).ToList();

        if(ids!=null && ids.Any())
        {
            foreach (var id in ids)
                Debug.WriteLine(id);
        }

        return View();
    }

Here is my result from Visual studio:

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.35708 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO