Фильтрация и сортировка данных

Фильтрация и сортировка данных #

Проблема отображения большого объёма данных #

В рамках данной работы рассмотрим типичные сценарии работы с большими наборами данных. Ключевая особенность заключается в том, что невозможно предоставлять пользователю сразу большой набор данных:

  • Большой объём данных долго обрабатывает система (как на сервере, так и на клиенте), что делает работу пользователя с системой неудобной.
  • Пользователю неудобно работать с очень большими документами.
  • Системы хотят самостоятельно обрабатывать свои данные и не делиться этими данными с другими системами.

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

HTML-формы #

Для обеспечения передачи данных от пользователя к веб-приложению используются интерактивные элементы, формы. Каждая форма состоит из нескольких полей, в которые пользователь может вводить данные, выбирать элементы из списка и т.д.

Формы описываются с помощью HTML-элемента form, который включает в себя ряд элементов input, textarea, button, описывающие конкретные поля ввода и интерактивные элемента. В рамках одного HTML-документа может находится несколько форм, предлагающие пользователю выполнить разные действия.

Для указания URI-адреса, который должен обработать данные, переданные с формы, используется атрибут action элемента form. По умолчанию данный адрес совпадает с адресом самого HTML-документа. Для большинства форм данное поведение является удобным и дополнительно определять путь не нужно.

Формы могут посылать GET и POST-запросы. Для указания HTTP-метода, который будет послан, используется атрибут method. По умолчанию форма будет отправлять GET-запрос. Это поведение необходимо использовать в данной практической работе.

При использовании GET-запросов данные с формы передаются в формате параметров, записанных в строку запроса. Названием параметра зачастую выступает название поля ввода, а значением — данные, которые указал или не указал пользователь.

Вы можете посмотреть на примеры форм на следующих страницах:

Сценарий фильтрации, сортировки #

В рамках данного сценария разработчику необходимо предоставить пользователю интерактивные элементы для ввода данных рядом с отображаемым списком элементов. Решение задач фильтрации и сортировки не должно изменять внутреннее состояние приложения, а влиять только на выводимые пользователю данные. Таким образом для отправки данных веб-приложению необходимо использовать GET-запросы.

Рассмотрим принципиальную последовательность действий, которые позволят пользователю выполнить фильтрацию или сортировку отображаемых данных:

sequenceDiagram autonumber actor user as Пользователь participant brow as Браузер participant serv as Сервер user ->> brow : Открывает ссылку
на документ со списком brow ->> serv : Выполняет GET-запрос
документа по ссылке serv ->> brow : HTML-документ
с данными и формой brow ->> user : Отображает полученный документ user ->> brow : Пользователь заполняет
поля формы и нажимает
кнопку «Применить» brow ->> serv : Посылает GET-запрос
с параметрами формы serv ->> brow : HTML-документ с данными
и заполненной формой brow ->> user : Отображает документ
с нужной страницей

Ключевые особенности подхода:

  • Для указания параметров фильтрации используются HTML-формы, интерактивные элементы.
  • Данные с формы передаётся на сервер с помощью GET-запроса, а не POST-запроса.
  • Данные с формы не должны «пропадать» после передачи их пользователю. Т.е. если пользователь указал какие-то параметры внутри формы, то они снова должны быть показаны пользователю.
  • Пользователь может скопировать ссылку и поделиться ей с другими пользователями, чтобы они увидели такой же результат фильтрации.
  • Пользователь может открыть несколько вкладок с одним сайтом и применить разные параметры фильтрации и сортировки для отображения одних и тех же данных.

Данные с формы передаются в качестве параметров маршрута: https://some.dev/list?owner=maria&version=15

Взаимодействие с постраничным выводом #

Оба подхода по фильтрации и по постраничному выводу используют одинаковый способ передачи данных от пользователя — параметры URI. Необходимо сохранять параметры фильтрации при переходе между различными страницами в выдаче отфильтрованного списка. В тоже время при изменении параметров фильтрации не стоит сохранять порядковый номер отображаемой страницы с данными.

Таким образом при формировании ссылок на другие страницы выдачи следует управлять только лишь параметром, указывающим на номер отображаемой страницы. В нашем случае им выступает параметр page. Другие же параметры не должны изменяться.

Класс Uri предоставляет необходимые возможности по изменению только целевого параметра.

Получение параметров запроса #

Обработка параметров, пришедших с формы, не отличается от обработки параметров, которые присылаются для реализации постраничного вывода.

Проблема нумерации элементов #

При использовании следующих подходов невозможно использовать метод withIndex для получения уникального номера элемента:

  • фильтрации;
  • частичной выборки;
  • сортировки.

Вместо этого необходимо:

  1. Добавить порядковый или уникальный номер внутрь элемента списка.
  2. При создании элемента необходимо использовать очередной номер из счётчика.
  3. Счётчик необходимо расположить внутри класса-списка.

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

Задача № 1. Реализация фильтрации списка треугольников #

Реализуйте фильтрацию списка добавленных треугольников по следующим критериям:

  • Минимальная длина наименьшей стороны треугольника.
  • Максимальная длина наибольшей стороны треугольника.

При отсутствии значения аргумента данный фильтр применяться не должен.

Поход к реализации:

  1. Реализуйте отображение формы на странице со списком документов.
    1. С помощью шаблона формы из Bootstrap добавьте на страницу вывода списка треугольников форму, состоящую из двух полей ввода и кнопки для отправки данных.
    2. Для каждого поля ввода укажите его уникальное имя (атрибут name), а также определитесь с типом компонента (атрибут type) , который наиболее точно позволит пользователю ввести корректные данные.
    3. Убедитесь, что данные, которые пользователь ввёл в форму, передаются обработчику HTTP-запроса в формате параметров запроса. Самый простой способ — заполнить поля формы и отправить её веб-приложению. Поля формы должны передаться с помощью параметров HTTP-запроса.
  2. Отобразите параметры, которые ввёл пользователь на HTML-документе. Это необходимо, чтобы пользователь смог исправить свой некорректный ввод.
    1. Модифицируйте модель (класс ViewModel) так, чтобы она хранила в себе параметры, которые пользователь указал с помощью формы. Данные параметры будет удобно описать как строковые типы, способные принимать null-значения, т.к. пользователь может не передать их или передать их в неправильном формате.
    2. Модифицируйте шаблон HTML-документа таким образом, чтобы он использовал передаваемые через модель данные. Атрибут value полей ввода позволяет установить изначальное значение.
    3. Обработайте параметры запроса в HTTP-обработчике и передайте их модели, чтобы их можно было отобразить пользователю в HTML-документе.
  3. Отфильтруйте данные, отображаемые пользователю.
    1. По возможности преобразуйте данные, которые передал пользователь, из строкового значения в вещественные числа. В рамках данной практической считаем, что пользователь введёт данные в корректном формате. В случае ошибочного значения просто преобразуйте строку к null-значению. Это будет совпадать с ситуацией, когда пользователь ничего не указал в поле ввода.
    2. Сформируйте метод у класса Triangles, возвращающий список отфильтрованных треугольников согласно данным, приходящим от пользователя. Данный метод должен принимать в качестве аргументов 2 вещественных числа, способных принимать null-значения. При наличии значения и у каждого из параметров, он должен учитываться при фильтрации элементов.
    3. Используйте данный метод для формирования списка данных для отображения пользователю.

Задача № 2. Поддержка фильтрации и постраничного вывода #

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

Задача № 3. Реализация сортировки #

К форме фильтрации данных добавьте ещё 1 поле, с помощью которого пользователь может управлять сортировкой данных в списке. Данное поле должно содержать следующие варианты сортировки:

  • По порядку добавления с увеличением номера.
  • По порядку добавления с уменьшением номера.
  • Сначала самые большие по площади.
  • Сначала самые маленькие по площади.
  • Сначала самые большие по периметру.
  • Сначала самые маленькие по периметру.

Для кодирования возможных вариантов рекомендуется использовать классы-перечисления.

© A. M. Васильев, 2023, CC BY-SA 4.0, andrey@crafted.su