Search code examples
razorasp.net-core-mvc

ASP.NET Core MVC returning checked items from a form in a razor view to controller


I am working with a view that shows a list of delisted books (with isActive = false). In this view I have added a column of checkbox against each book . When the form is submitted I want to set all the checked books to become active (isActive = true).

This is the view I am working with :

@model IEnumerable<MvcBooksList.Models.Book>

@{
    ViewData["Title"] = "Delisted Books";
}


@if (Model != null)
{
    @using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post))
    {
        <table class="table">
            <thead>
                <tr>
                    <th>
                        @Html.DisplayNameFor(model => model.BookName)
                    </th>

                    <th>
                        @Html.DisplayNameFor(model => model.Author)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Publisher)
                    </th>
                    <th>
                        Enlist
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.BookName)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Author)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Publisher)
                        </td>
                        <td>
                            @Html.CheckBoxFor(modelItem => item.IsActive)
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        <input type="submit" value="Save" />    <input type = "button" value = "Cancel" onclick = "location.href='@Url.Action("Index","Home")'" />

    }

}
else
{
    <h3>No Books currently delisted</h3>
}

So my question is: how do I process this data in my controller action. As in when I click submit, will the form return IEnumerable of Books with IsActive set to true to the action??

I am trying something like this:

[HttpPost]
public ActionResult DelistedForm(IEnumerable<Book> fromDelist)
{
        foreach (var item in fromDelist)
        {
            if (item.IsActive == true) ;
            // enlist code here 
        }
        return View("~/Views/Home/Index.cshtml");
}

Solution

  • If you only want to pass a list of books which IsActive is true.YOu can add hidden inputs to bind the data of BookName,Author,Publisher.And then change the name attribute of the inputs to correct format when checkbox is checked before form submitting.Here is a demo:

    Action:

    [HttpGet]
            public IActionResult DelistedForm()
            {
                return View(new List<Book> { new Book {  Author="a1", BookName="b1", IsActive=false, Publisher="p1"}, 
                    new Book { Author = "a2", BookName = "b2", IsActive = false, Publisher = "p2" }, 
                    new Book { Author = "a3", BookName = "b3", IsActive = false, Publisher = "p3" } });
            }
            [HttpPost]
            [Route("/Book/DelistedForm")]
            public ActionResult DelistedForm(IEnumerable<Book> fromDelist)
            {
                foreach (var item in fromDelist)
                {
                    if (item.IsActive == true) ;
                    // enlist code here 
                }
                return View("~/Views/Home/Index.cshtml");
            }
    

    View:

    @if (Model != null)
    {
        @using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post,new { @id="myForm"}))
        {
            <table class="table">
                <thead>
                    <tr>
                        <th>
                            @Html.DisplayNameFor(model => model.BookName)
                        </th>
    
                        <th>
                            @Html.DisplayNameFor(model => model.Author)
                        </th>
                        <th>
                            @Html.DisplayNameFor(model => model.Publisher)
                        </th>
                        <th>
                            Enlist
                        </th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model)
                    {
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => item.BookName)
                                @Html.HiddenFor(modelItem => item.BookName)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Author)
                                @Html.HiddenFor(modelItem => item.Author)
    
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Publisher)
                                @Html.HiddenFor(modelItem => item.Publisher)
    
                            </td>
                            <td>
                                @Html.CheckBoxFor(modelItem => item.IsActive)
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
    
            <input type="submit" value="Save" />
            <input type="button" value="Cancel" onclick="location.href='@Url.Action("Index","Home")'" />
    
        }
    
    }
    else
    {
        <h3>No Books currently delisted</h3>
    }
    

    js:

    <script>
            $("#myForm").submit(function () {
                var count = 0;
                $("tbody tr").each(function () {
                    if ($(this).find("#item_IsActive").prop("checked")) {
                        $(this).find("#item_BookName").attr("name", "fromDelist[" + count + "].BookName");
                        $(this).find("#item_Author").attr("name", "fromDelist[" + count + "].Author");
                        $(this).find("#item_Publisher").attr("name", "fromDelist[" + count + "].Publisher");
                        $(this).find("#item_IsActive").attr("name", "fromDelist[" + count + "].IsActive");
                        count++;
                    }
                })
            })
        </script>
    

    result: enter image description here