Разбивка на страницы отфильтрованных таблиц в Turbo Frame с использованием Pagy?

Я пытаюсь реализовать нумерацию страниц в своем проекте Rails, используя драгоценный камень Pagy. У меня есть модель Record и индексное представление для отображения моего Records в элементе и форма над таблицей для фильтрации таблицы, которая находится в частичном виде, содержащем в турбо-кадре.

Моя проблема заключается в том, что Pagy изначально разбивает результаты поиска на страницы (определенные как «records#search») внутри турбо-фрейма, но затем, когда я перехожу с одной страницы на другую, он сразу же переходит на эту страницу, как если бы я просматривал нефильтрованные результаты ( Запись.все).

Итак, конкретный сценарий заключается в том, что я нахожусь на маршруте «/records/», но хочу отфильтровать записи, где name == 'foo'. Как только я отфильтрую таблицу, она покажет мне результаты в таблице, где name == 'foo' на странице 1. Затем, если я нажму, чтобы перейти на страницу 2, чтобы увидеть больше отфильтрованных результатов, это будет так, как будто я нахожусь на нефильтрованной странице. 2 и я потеряю свои результаты где name == 'foo'.

Итак, в моем RecordsController у меня есть:

class RecordsController < ApplicationController
  def index
    @pagy, @records = pagy(Record.all, items: 25)
  end

  def search
    records = Record.where('name LIKE ?', "%#{params[:name]}%")
    records = records&.where('type LIKE ?', "%#{params[:type]}%") if params[:type].present?

    render(partial: 'records_table', locals: { records: })
  end
end

В моем index.html.erb для Records:

<h1>Records</h1>

<%= render "record_search_form" %>
<%= render "records_table",
    records: @records %>

<div class = "pag-bar mt-5 pt-5">
  <%== pagy_bootstrap_nav(@pagy) if @pagy.pages > 1 %>
</div>

Внутри record_search_form партиала:

<div style = "margin:0.75rem">
    <%= form_with url: records_search_path, method: :post,
        data: {
                controller:"records-search",
                records_search_target: "form",
                turbo_frame:"records_table"} do |form| %>

        <%= form.text_field :name %>
        <%= form.text_field :type %>

        <%= form.button "Search", class:"btn btn-primary" %>
    <% end %>
</div>

Внутри records_table:

<%= turbo_frame_tag "records_table" do %>
    <table>
            <thead>
            <tr>
                <th>
                    ID
                </th>
                <th>
                    Name
                </th>
                <th>
                    Type
                </th>
            </tr>
            </thead>

            <tbody>
            <% if records.present? %>
                <% records.each do |record| %>
                    <tr>
                        <td><%= record.id %></td>
                        <td><%= record.name %></td>
                        <td><%= record.type %></td>
                    </tr>
                <% end %>
            <% end %>
            </tbody>
        </table>
<% end %>

Я попытался изменить свое действие records#search, чтобы отобразить другой экземпляр Pagy:

def search
    records = Record.where('name LIKE ?', "%#{params[:name]}%")
    records = records&.where('type LIKE ?', "%#{params[:type]}%") if params[:type].present?

    @pagy_results, @results = pagy(records, items: 25)

    render(partial: 'records_table', locals: { records: @results })
  end

А затем включим его в представление следующим образом:

<h1>Records</h1>

<%= render "record_search_form" %>
<%= render "records_table",
    records: @records %>

<div class = "pag-bar mt-5 pt-5">
  <%== pagy_bootstrap_nav(@pagy) if @pagy.pages > 1 %>
</div>

**<div class = "pag-bar mt-5 pt-5">
  <%== pagy_bootstrap_nav(@pagy_search) if @pagy_search.present? && @pagy_search.pages > 1 %>
</div>**

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

Я также попробовал это внутри records#search:

@pagy_search, @response = pagy(records, items: 100, pagy_url_for: 'records/search')

И это тоже не приводит ни к каким изменениям.

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
134
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
# app/controllers/records_controller.rb

class RecordsController < ApplicationController
  def index
    scope = Record.all
    scope = scope.where("name LIKE ?", "%#{params[:name]}%") if params[:name].present?
    scope = scope.where("type LIKE ?", "%#{params[:type]}%") if params[:type].present?

    @pagy, @records = pagy(scope, items: 25)
  end
end

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

target: "_top" – потому что вы хотите, чтобы другие ссылки перемещались за пределами фрейма, а ссылки на страницы находились внутри фрейма.
autoscroll: true — прокручивает вверх результатов поиска.
turbo_action: "advance" — обновляет текущий URL.

# app/views/records/index.html.erb

<%= render "search_form" %>

<%= turbo_frame_tag "records_table", target: "_top", autoscroll: true,
  data: {turbo_action: "advance"} do %>

  <%= render "table", records: @records %>

  <%== pagy_nav(@pagy) %>
<% end %>

Сделайте так, чтобы ссылки на страницы перемещались внутри фрейма по умолчанию:

# config/initializers/pagy.rb

Pagy::DEFAULT[:link_extra] = 'data-turbo-frame = "_self"'

Почти всегда поиск должен представлять собой форму GET:

# app/views/records/_search_form.html.erb

<%= form_with url: records_path, method: :get,
  data: {turbo_frame:"records_table"} do |form| %>

  <%= form.text_field :name, value: params[:name] %>
  <%= form.text_field :type, value: params[:type]%>

  <%= form.button "Search", name: nil %>
<% end %>
<!-- app/views/records/_table.html.erb -->

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <% records.each do |record| %>
      <tr>
        <td><%= record.id %></td>
        <td><%= record.name %></td>
        <td><%= record.type %></td>
      </tr>
    <% end %>
  </tbody>
</table>

Большое спасибо! Кажется, это сработало для меня! Буду обновлять, если что-нибудь еще! Очень благодарен за время, которое вы потратили на написание такого подробного объяснения.

Richard Wright 25.05.2024 00:18

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