Alex Cserődi
Alex Cserődi

Reputation: 25

Asp.net mvc how to pass multiple checkbox values to controller

Im working on an application which can download emails. In my view if checkbox/checkboxes are checked, i want to pass an ID to controller to download this messages. I will try to explain with code:

    @using (Html.BeginForm("DownloadData", "Messages", FormMethod.Post))
    {
        <table class="table table-bordered table-hover">
            @for (int i = 0; i < Model.Count; i++)
            {
            <tr>
                <td><input type="checkbox"       
                 name="selectedIds[@i].messageID"/></td>
                <td>@Model[i].messageFrom</td>
                <td>@Model[i].messageSubject</td>
                <td>@Model[i].messageDate</td>
            </tr>
            }
        </table>
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Download" />
        </div>
    }

The @i in name="selectedIds[@i].messageID" doesnt going to be good because its increasing and if i check: 1st the 2nd and the 4th message, it will add only the first two elements to my list.

The controller:

    [HttpPost]
    public ActionResult DownloadData(List<MessagesModels> selectedIds)
    {
       return View(...);
    }

The model:

    public class MessagesModels
    {
    public int messageID { get; set; }
    public string messageSubject { get; set; }
    ...
    }

I think it isnt hard, but cant find the sollution. Thanks for those who can help!

Upvotes: 2

Views: 9712

Answers (1)

Joe
Joe

Reputation: 3761

To avoid changing your message model just for this view (or if you are unable to begin with) I would recommend creating a new model for this view to handle selecting like this:

public class MessageSelectionViewModel
{
  public MessagesModels Message { get; set; }
  public bool IsSelected { get; set; }
}

Your view would now be a list of these new view objects so would look more like this:

<td>@Html.CheckBoxFor(item => item[i].IsSelected)</td>
<td style="display:none;">@Html.HiddenFor(item => item[i].Message.Id)</td>
<td>@Model[i].Message.messageFrom</td>
<td>@Model[i].Message.messageSubject</td>
<td>@Model[i].Message.messageDate</td>

Your post method would become:

[HttpPost]
public ActionResult DownloadData(IEnumerable<MessageSelectionViewModel> selectedMessages)
{
  foreach (int messageId in selectedMessages.Where(m => m.IsSelected == true).Select(m => m.Message.Id))
  {
  }
  return View(...);
}

Of course if it's not a big deal you could save some time and effort and just add IsSelected to your model like Stephen suggested.

Upvotes: 3

Related Questions