у меня такой код
public async Task<IActionResult> Index(string[] searchString, string sortOrder)
{
ViewBag.CurrentFilter = searchString;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.PriceSortParm = sortOrder == "Price" ? "Price desc" : "Price";
var cosmetics = from s in db.Cosmetics
select s;
//Sorting logic
switch (sortOrder)
{
case "Name desc":
cosmetics = cosmetics.OrderByDescending(s => s.Name);
break;
case "Price":
cosmetics = cosmetics.OrderBy(s => s.Price);
break;
case "Price desc":
cosmetics = cosmetics.OrderByDescending(s => s.Price);
break;
default:
cosmetics = cosmetics.OrderBy(s => s.Name);
break;
}
//Filter data logic
if (searchString.Length != 0)
{
var li = new List<Cosmetic>();
foreach (string ss in searchString)
{
List<Cosmetic> ll = cosmetics.Where(c => c.Name.Contains(ss)).ToList();
li.AddRange(ll);
}
return View(li);
}
return View(await cosmetics.ToListAsync());
}
Я хочу, чтобы фильтрация и сортировка данных работали вместе. Пробовал их подключать, но результат был такой, что отображались все товары вне зависимости от того, что я передал в "string[]searchString"
Обновлять
Данные фильтра:
<form asp-action = "Index" method = "get">
<input class = "form-control col-md-8 d-inline-block align-middle" type = "checkbox" name = "searchString" placeholder = "Find" value = "A" />
<input class = "form-control col-md-8 d-inline-block align-middle" type = "checkbox" name = "searchString" placeholder = "Find" value = "B" />
<input class = "btn btn-info" type = "submit" value = "Search" />
</form>
Сортировка:
<a class = "m-1" asp-action = "Index" asp-route-sortOrder = "@ViewBag.NameSortParm" asp-route-searchString = "@ViewBag.CurrentFilter">Name</a>
<a class = "m-1" asp-action = "Index" asp-route-sortOrder = "@ViewBag.PriceSortParm" asp-route-searchString = "@ViewBag.CurrentFilter">Price</a>
Попробуйте отладить его, проверив, передается ли searchString вашему контроллеру. Кроме того, проверьте обновленный код, чтобы его было легче читать.
public async Task<IActionResult> Index(string[] searchString, string sortOrder)
{
ViewBag.CurrentFilter = searchString;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.PriceSortParm = sortOrder == "Price" ? "Price desc" : "Price";
var cosmetics = from s in db.Cosmetics
select s;
//Filter data logic
if (searchString.Length != 0)
{
cosmetics = cometics.Where(c => searchString.Any(s => s.Contains(c.Name)));
}
//Sorting logic
switch (sortOrder)
{
case "Name desc":
cosmetics = cosmetics.OrderByDescending(s => s.Name);
break;
case "Price":
cosmetics = cosmetics.OrderBy(s => s.Price);
break;
case "Price desc":
cosmetics = cosmetics.OrderByDescending(s => s.Price);
break;
default:
cosmetics = cosmetics.OrderBy(s => s.Name);
break;
}
return View(await cosmetics.ToListAsync());
}
Как вы называете это из передней части. Похоже, вы не передаете строку поиска при нажатии на сортировку.
searchString
— это массив строк, который нельзя преобразовать в asp-route-searchString
. Я предлагаю вам получить два searchString отдельно.
Фильтр:
<form id = "my_form" asp-action = "Index" method = "get">
<input class = "form-control col-md-8 d-inline-block align-middle" type = "checkbox" name = "searchString1" placeholder = "Find" value = "A" />
<input class = "form-control col-md-8 d-inline-block align-middle" type = "checkbox" name = "searchString2" placeholder = "Find" value = "B" />
<input class = "btn btn-info" type = "submit" value = "Search" />
</form>
Сортировка:
<a class = "m-1" asp-action = "Index" asp-route-sortOrder = "@ViewBag.NameSortParm" asp-route-searchString1 = "@ViewBag.CurrentFilter1" asp-route-searchString2 = "@ViewBag.CurrentFilter2">Name</a>
<a class = "m-1" asp-action = "Index" asp-route-sortOrder = "@ViewBag.PriceSortParm" asp-route-searchString1 = "@ViewBag.CurrentFilter1" asp-route-searchString2 = "@ViewBag.CurrentFilter2">Price</a>
Контроллер:
public IActionResult Index(string searchString1, string searchString2, string sortOrder)
{
ViewBag.CurrentFilter1 = searchString1;
ViewBag.CurrentFilter2 = searchString2;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.PriceSortParm = sortOrder == "Price" ? "Price desc" : "Price";
//filter and sort
}
Обновлять:
Если у вас другие условия фильтрации, я думаю, что javasript может удовлетворить их. Вы можете получить фильтр и условие сортировки в js, а затем вручную добавить их как строку запроса к URL-адресу.
Я сделал пример на основе этого, вы можете обратиться к приведенным ниже кодам:
Модель:
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string Manufacturer { get; set; }
public string Price { get; set; }
}
Вид:
@model IEnumerable<Car>
@{
ViewData["Title"] = "Home Page";
}
<form id = "my_form" asp-action = "Index" method = "get">
<label>Color:</label>
<input type = "checkbox" name = "color" value = "black" /><span>Black</span>
<input type = "checkbox" name = "color" value = "white" /><span>White</span>
<br />
<label>Manufacturer:</label>
<input type = "checkbox" name = "manufacturer" value = "A" /><span>A</span>
<input type = "checkbox" name = "manufacturer" value = "B" /><span>B</span>
<input type = "checkbox" name = "manufacturer" value = "C" /><span>C</span>
<input type = "checkbox" name = "manufacturer" value = "D" /><span>D</span>
<input class = "btn btn-info float-right" type = "submit" value = "Search" />
</form>
<table class = "table">
<thead>
<tr>
<th>
<a class = "sort" id = "sortname" data-sortorder = "@ViewBag.NameSortParm" href = "javascript:void(0)" >@Html.DisplayNameFor(model => model.Name)</a>
</th>
<th>
@Html.DisplayNameFor(model => model.Color)
</th>
<th>
@Html.DisplayNameFor(model => model.Manufacturer)
</th>
<th>
<a class = "sort" id = "sortprice" data-sortorder = "@ViewBag.PriceSortParm" href = "javascript:void(0)" >@Html.DisplayNameFor(model => model.Price)</a>
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Color)
</td>
<td>
@Html.DisplayFor(modelItem => item.Manufacturer)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
</tr>
}
</tbody>
</table>
@section scripts{
<script>
var color = @Html.Raw(Json.Serialize(ViewBag.color));
var manufacturer = @Html.Raw(Json.Serialize(ViewBag.manufacturer));
$(function () {
var checkoptions = [];
checkoptions = color.concat(manufacturer);
$('input[type=checkbox]').each(function () {
if (checkoptions.includes(this.value)) {
$(this).prop("checked", true);
}
});
})
$(".sort").click(function () {
var sortorder = $(this).data('sortorder');
var link = "/Home/Index?";
color.forEach(function (value) {
link += "color = " + value + "&";
});
manufacturer.forEach(function (value) {
link += "manufacturer = " + value + "&";
});
link += "sortOrder = " + sortorder;
window.location.href = link;
})
</script>
}
Контроллер:
public IActionResult Index(string[] color, string[] manufacturer, string sortOrder)
{
ViewBag.color = color;
ViewBag.manufacturer = manufacturer;
ViewBag.NameSortParm = string.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
ViewBag.PriceSortParm = sortOrder == "Price" ? "Price_desc" : "Price";
var cars = _context.Car.ToList();
var co_cars = new List<Car>();
var ma_cars = new List<Car>();
if (color.Length != 0)
{
foreach (string co in color)
{
var colorfiltercars = _context.Car.Where(c => c.Color.Contains(co)).ToList();
co_cars.AddRange(colorfiltercars);
}
}
else
{
co_cars = cars;
}
if (manufacturer.Length != 0)
{
foreach (string ma in manufacturer)
{
var manufacturerfiltercars = _context.Car.Where(c => c.Manufacturer.Contains(ma)).ToList();
ma_cars.AddRange(manufacturerfiltercars);
}
}
else
{
ma_cars = cars;
}
var filtercars = co_cars.Intersect(ma_cars);
switch (sortOrder)
{
case "Name_desc":
filtercars = filtercars.OrderByDescending(s => s.Name);
break;
case "Price":
filtercars = filtercars.OrderBy(s => int.Parse(s.Price));
break;
case "Price_desc":
filtercars = filtercars.OrderByDescending(s => int.Parse(s.Price));
break;
default:
filtercars = filtercars.OrderBy(s => s.Name);
break;
}
return View(filtercars.ToList());
}
И источник данных:
Результат:
В качестве примера я привел 2 флажка, они могут быть бесконечными. Я хочу сделать эти галочки как фильтры в интернет-магазинах. Например, фильтровать по цвету, производителю, году выпуска и все это одновременно. Можете ли вы сказать мне, как это сделать по-другому?
@Betsq9 Я обновил свой ответ, посмотри.
Один вопрос var filtercars = co_cars.Intersect(ma_cars); filtercars = co_cars.Intersect(purposeFor);
Правильно ли я добавляю фильтры?
@Betsq9 Вам нужно взять перекресток на основе предыдущего. var filtercars = co_cars.Intersect(ma_cars); filtercars = filtercars.Intersect(purposeFor);
Мой код выше работает. Я хочу иметь возможность фильтровать данные и сортировать эти отфильтрованные данные, например, по цене. На данный момент я могу фильтровать данные. Но если я нажимаю отсортировать, то фильтрация сбрасывается и отображаются все товары, а не те, которые я отфильтровал.