0

I have the following GET and POST action methods:-

public ActionResult Create(int visitid)
{
    VisitLabResult vlr = new VisitLabResult();
    vlr.DateTaken = DateTime.Now;
    ViewBag.LabTestID = new SelectList(repository.FindAllLabTest(), "LabTestID", "Description");

    return View();
} 

//
// POST: /VisitLabResult/Create

[HttpPost]
public ActionResult Create(VisitLabResult visitlabresult, int visitid)
{
    try
    {
        if (ModelState.IsValid)
        {
            visitlabresult.VisitID = visitid;
            repository.AddVisitLabResult(visitlabresult);
            repository.Save();
            return RedirectToAction("Edit", "Visit", new { id = visitid });
        }
    }
    catch (DbUpdateException) {

        ModelState.AddModelError(string.Empty, "The Same test Type might have been already created,, go back to the Visit page to see the avilalbe Lab Tests");

    }
    ViewBag.LabTestID = new SelectList(repository.FindAllLabTest(), "LabTestID", "Description", visitlabresult.LabTestID);

    return View(visitlabresult);
}

Currently the view display the associated fields to create only one object,, but how i can define list of objects instead of one object to be able to quickly add for example 10 objects at the same “Create” request. My Create view look like:-

@model Medical.Models.VisitLabResult

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@section scripts{
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
}
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>VisitLabResult</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.LabTestID, "LabTest")
        </div>
        <div class="editor-field">
            @Html.DropDownList("LabTestID", String.Empty)
amit_g
  • 30,880
  • 8
  • 61
  • 118
John John
  • 1
  • 72
  • 238
  • 501

3 Answers3

8

Your viewModel

public class LabResult
{
    public int ResultId { get; set; }
    public string Name { get; set; }
    //rest of the properties
}

Your controller

public class LabController : Controller
{
    //
    // GET: /Lab/ns

    public ActionResult Index()
    {
        var lst = new List<LabResult>();
        lst.Add(new LabResult() { Name = "Pravin", ResultId = 1 });
        lst.Add(new LabResult() { Name = "Pradeep", ResultId = 2 });

        return View(lst);
    }

    [HttpPost]
    public ActionResult EditAll(ICollection<LabResult> results)
    {
        //savr results here
        return RedirectToAction("Index");
    }

}

Your view

@model IList<MvcApplication2.Models.LabResult>
@using (Html.BeginForm("EditAll", "Lab", FormMethod.Post))
{
    <table>
        <tr>
            <th>
                ResultId
            </th>
            <th>
                Name
            </th>
        </tr>
        @for (int item = 0; item < Model.Count(); item++)
        {
            <tr>
                <td>
                    @Html.TextBoxFor(modelItem => Model[item].ResultId)
                </td>
                <td>
                    @Html.TextBoxFor(modelItem => Model[item].Name)
                </td>
            </tr>
        }
    </table>
    <input type="submit" value="Edit All" />
}

Your view will be rendered as follows, this array based naming convention makes it possible for Defaultbinder to convert it into ICollection as a first parameter of action EditAll

<tr>
<td>
        <input name="[0].ResultId" type="text" value="1" />
    </td>
    <td>
        <input name="[0].Name" type="text" value="Pravin" />
    </td>
    </tr>
    <tr>
    <td>
        <input name="[1].ResultId" type="text" value="2" />
    </td>
    <td>
        <input name="[1].Name" type="text" value="Pradeep" />
    </td>
    </tr>
Pravin Pawar
  • 2,559
  • 3
  • 34
  • 40
0

If I understand your question correctly,

you want to change your view to be a list of your model object @model List, then using a loop or however you wish to do it, create however many editors you need to for each object

then in your controller your receiving parameter of create will be a list of your model instead too.

AwDogsGo2Heaven
  • 952
  • 11
  • 26
0

AddRoleViewModel :

namespace Course.Repository.ViewModeles {
    public class AddRoleViewModel {

      public string? Id{ get; set; }
      public string Name { get; set; }

    }
}

UsersInfoViewModel

namespace Course.Repository.ViewModeles {
    public class UsersInfoViewModel {
      public string UserId { get; set; }
      public string UserName { get; set; }
      public bool IsSelected { get; set; }

    }
}

UsersInRoleViewModel

 namespace Course.Repository.ViewModeles {
    public class UsersInRoleViewModel {
        public UsersInRoleViewModel()
        {
            UsersInfo = new List<UsersInfoViewModel>();
        }
        public AddRoleViewModel role { get; set; }
        public IList<UsersInfoViewModel> UsersInfo { get; set; }
    }
}

HttpGet

  [HttpGet]
    public IActionResult EditUserRole(string roleId)
    {
        var role = _accountService.GetRoleById(roleId).Result;
        var usersInRole=_accountService.UsersInRole(role.Name).Result;
        if(role==null || usersInRole == null)
        {
            return RedirectToAction(nameof(Index));
        }
        UsersInRoleViewModel usersInRoleView = new UsersInRoleViewModel()
        {
            role = role,
            UsersInfo = usersInRole
        };

        return View(usersInRoleView);
    }

HttpPost

  [HttpPost]
    public IActionResult EditUserRole(UsersInRoleViewModel model,string roleId)
    {
        return View();
    }

View

@model UsersInRoleViewModel;
@{
    ViewData["Title"] = "Edit Users Role";
}
@if (Model is null)
{
    <div class="card roles">
        <div class="card-body">
            <h3 class="card-text">Not Avaliable Update Role at Moment</h3>
            <a asp-area="" asp-controller="Admistration" asp-action="Index" class="btn btn-danger" class="card-link">Cancel</a>
        </div>
    </div>
}
else
{
    <div class="card roles">
        <div class="card-body">
            <h3 class="card-text">@Model.role.Name</h3>
            <form method="post" asp-action="EditUserRole" asp-controller="Admistration" asp-route-roleId="@Model.role.Id" style="margin-top:20px">
                <div>
                    <input asp-for="@Model.role.Id" hidden />
                    <input asp-for="@Model.role.Name" hidden />
                </div>
                @if (Model.UsersInfo.Any())
                {
                    for (int i = 0; i < Model.UsersInfo.Count; i++)
                    {
                        <div class="form-group">
                            <input asp-for="@Model.UsersInfo[i].UserName" hidden />
                            <input asp-for="@Model.UsersInfo[i].UserId" hidden />
                        </div>
                        <div class="form-check" style="margin-top:5px">
                            <input class="form-check-input" type="checkbox" asp-for="@Model.UsersInfo[i].IsSelected" id="defaultCheck1" />
                            <label asp-for="@Model.UsersInfo[i].UserName" class="form-check-label" for="defaultCheck1">
                                @Model.UsersInfo[i].UserName
                            </label>
                        </div>
                    }
                    <div class="form-group" style="margin-top:20px">
                        <input type="submit" value="Edit" class="btn btn-primary" style="background-color: #006df0" />
                        <a asp-area="" asp-controller="Admistration" asp-action="Index" class="btn btn-danger" class="card-link">Cancel</a>
                    </div>
                }
            </form>
        </div>
    </div>
}
@section Scripts{
    <partial name="_ValidationScriptsPartial" />
}
Ragab Mohamad
  • 371
  • 2
  • 4