Reputation: 39
I want to filter products in my e-commerce project, but I have a problem: I want my filtering to change dynamically, I choose a brand from the selected list and the necessary filtering is done. When the second filter is done, my first filter is reset and the last filtering becomes valid.
I need such a URL structure:
/?SelectedVendor=Asus&SelectedMemory=4+GB
FilterViewModel.cs
public class FilterViewModel
{
public List<string> Vendors { get; set; }
public List<string> Memories { get; set; }
public string SelectedVendor { get; set; }
public string SelectedMemory { get; set; }
}
CategoryController.cs
[HttpGet]
public ViewResult Gaming(int productPage = 1, FilterViewModel model=null)
{
ProductListViewModel productList = new ProductListViewModel()
{
Products =
_productService.GetProductsByCategoryId(1).OrderBy(p => p.Id).Skip((productPage - 1) * pageSize).Take(pageSize),
FilterTypes = new FilterViewModel()
{
Vendors = _productService.Products.Select(I => I.Vendor).Distinct().OrderBy(I => I).ToList(),
Memories = _productService.Products.Select(I => I.MemoryCapacity).Distinct().OrderBy(I => I).ToList(),
}
};
if (!string.IsNullOrEmpty(model.SelectedVendor))
{
productList.Products = productList.Products.Where(I => I.Vendor.Contains(model.SelectedVendor));
productList.FilterTypes.Memories = productList.Products.Select(I => I.MemoryCapacity).Distinct()
.OrderBy(I => I).ToList();
}
if (!string.IsNullOrEmpty(model.SelectedMemory))
{
productList.Products = productList.Products.Where(I => I.MemoryCapacity == model.SelectedMemory);
}
return View(productList);
}
FilterPartial.cshtml
<div class="col-md-3">
<div class="filter filter-first">
<h6 class="font-weight-bold">Brand</h6>
<form method="get" asp-controller="@controllerName" asp-action="@actionName">
@foreach (var vendor in Model.Vendors)
{
<div class="mt-2 mb-2 pl-2">
<input type="submit" value="@vendor" asp-for="SelectedVendor"/>
</div>
}
<h6 class="font-weight-bold">Memory</h6>
@foreach (var memory in Model.Memories)
{
<div class="mt-2 mb-2 pl-2">
<input type="submit" asp-for="SelectedMemory" value="@memory"/>
</div>
}
</form>
</div>
</div>
Upvotes: 0
Views: 1842
Reputation: 18189
Here is a demo to pass both SelectedVendor and SelectedMemory to action:
TestFilter.cshtml:
@await Html.PartialAsync("Partial", Model.FilterTypes)
<script>
function addSelectedVendor(i) {
$("#SelectedVendor").val($(i).val());
$("#form1").submit();
}
function addSelectedMemory(i) {
$("#SelectedMemory").val($(i).val());
$("#form1").submit();
}
</script>
Partial.cshtml:
<form id="form1" method="get" asp-controller="Test" asp-action="TestFilter">
@foreach (var vendor in Model.Vendors)
{
<div class="mt-2 mb-2 pl-2">
<input type="button" value="@vendor" onclick="addSelectedVendor(this)" />
</div>
}
<h6 class="font-weight-bold">Memory</h6>
@foreach (var memory in Model.Memories)
{
<div class="mt-2 mb-2 pl-2">
<input type="button" value="@memory" onclick="addSelectedMemory(this)" />
</div>
}
<input hidden asp-for="SelectedVendor"/>
<input hidden asp-for="SelectedMemory"/>
</form>
TestController(I use fake data to test):
[HttpGet]
public IActionResult TestFilter(FilterViewModel model)
{
ProductListViewModel productList = new ProductListViewModel { FilterTypes=new FilterViewModel()};
productList.FilterTypes.Vendors = new List<string> { "Apple", "Asus", "Dell", "Lenovo", "MSI" };
productList.FilterTypes.Memories = new List<string> { "16GB", "4GB", "8GB"};
return View(productList);
}
Upvotes: 1
Reputation: 87
You can filter by list in your get method.
you should change get method like that
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = DbSet;
if (filter != null) query = query.Where(filter);
if (includeProperties != null)
foreach (var includeProperty in includeProperties.Split
(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
query = query.Include(includeProperty);
if (orderBy != null)
return orderBy(query).ToList();
return query.ToList();
}
Upvotes: 0