Как сделать сортировку и фильтрацию данных одновременно?

у меня такой код

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>
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
619
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте отладить его, проверив, передается ли 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());
    }

Мой код выше работает. Я хочу иметь возможность фильтровать данные и сортировать эти отфильтрованные данные, например, по цене. На данный момент я могу фильтровать данные. Но если я нажимаю отсортировать, то фильтрация сбрасывается и отображаются все товары, а не те, которые я отфильтровал.

Betsq9 15.12.2020 17:10

Как вы называете это из передней части. Похоже, вы не передаете строку поиска при нажатии на сортировку.

Sunny 15.12.2020 17:47
Ответ принят как подходящий

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 16.12.2020 08:44

@Betsq9 Я обновил свой ответ, посмотри.

mj1313 17.12.2020 09:13

Один вопрос var filtercars = co_cars.Intersect(ma_cars); filtercars = co_cars.Intersect(purposeFor); Правильно ли я добавляю фильтры?

Betsq9 17.12.2020 12:27

@Betsq9 Вам нужно взять перекресток на основе предыдущего. var filtercars = co_cars.Intersect(ma_cars); filtercars = filtercars.Intersect(purposeFor);

mj1313 18.12.2020 02:29

Другие вопросы по теме