I have been reviewing possible ways to return a View's @model information which is of type IEnumerable back to the controller, so that if I sort/filter on a query from database, I can refine the return each iteration without restarting with a fresh full list being returned. All the ways show you need to POST back based on model[index] which works if you are inside a for loop. But I am working with sending the collection back from an @HTML.ActionLink within a table's header section, so there is no possible indexing available.
My WebAPI setup is based on this where they show how to sort and filter. I am trying to make it a little more complex in that after I filter a list based on my original DB query, I will then be able to sort (from a clickable-actionLink on a table's header column) from that filtered list; where as currently it would just sort from a fresh complete list.
The only way I can think of to do this is pass back (by a POST) to the controller the updated list of the customClass.
@Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, companyListIds = Model.???? })
A better option (based on comments from Tacud) which would require a smaller POST URL would be by returning a list of the id properties only which can then be applied to a query. But its still a list and still needs to be sent back without an index from and ActionLink. This will help keep track and allow me to continue drilling down to a smaller and smaller list.
Below is parts of my model class, the index Action from the controller, and the index view. Model namespace:
public class Company
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Controller Namespace:
public async Task<IActionResult> Index(ICollection<int> prev, string orderBy , string searchCategory ="", string searchString = "")
{
List<string> Categories = new List<string>() { "Name", "City", "State", "Zip", "Contact Person" };
ViewBag.searchCategory = new SelectList(Categories);
ViewBag.sortByName = orderBy == null ? "name" : orderBy == "name" ? "namedesc" : "name";
ViewBag.sortByCity = orderBy == "city" ? "citydesc" : "city";
ViewBag.sortByState = orderBy == "state" ? "statedesc" : "state";
ViewBag.companyIndex = companyList.Count==0 ? await _context.Company.ToListAsync() : companyList ;
List<Company> resultSet = new List<Company>(ViewBag.companyIndex);
if (!String.IsNullOrEmpty(searchCategory) && !String.IsNullOrEmpty(searchString))
{
switch (searchCategory)
{
.....
}
}
switch (orderBy)
{
....
}
return View(resultSet);
}
View namespace:
@model IEnumerable<Laier_It.Models.Company> <p> @using (Html.BeginForm() { <p> Search By: @Html.DropDownList("SearchCategory", "") Search For: @Html.TextBox("SearchString") <input type="submit" value="Filter" /> </p> } <table class="table "> <thead> <tr> <th> @Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, companyList = Model }) </th> <th> @Html.DisplayNameFor(model => model.Address) </th> <th> @Html.ActionLink("City", "Index", new { orderBy = ViewBag.sortByCity, companyList = Model }) </th> <th> @Html.ActionLink("State", "Index", new { orderBy = ViewBag.sortByState, companyList = Model }) </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Address) </td> <td> @Html.DisplayFor(modelItem => item.City) </td> <td> @Html.DisplayFor(modelItem => item.State) </td> </tr> } </tbody> </table>