Используя WP_List_Table и search_box(): Как пагинировать найденные результаты поиска при отправке методом «Post»?

Вопрос или проблема

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

Форма поиска также добавлена с помощью

$my_list_table_instance->search_box( 'Поиск', 'search_id' );

и она работает отлично, но только для первой страницы.

Внутри формы у меня есть два скрытых поля для пагинации:

// Вывод списка и формы
$page  = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRIPPED );
$paged = filter_input( INPUT_GET, 'paged', FILTER_SANITIZE_NUMBER_INT );
echo '<form method="post" id="list-hotels-form">';
printf( '<input type="hidden" name="page" value="%s" />', $page );
printf( '<input type="hidden" name="paged" value="%d" />', $paged );
$hotel_table->prepare_items();
$hotel_table->search_box( __( 'Поиск отелей', 'uruk' ), 'search_id' );
$hotel_table->display();
echo '</form>';
// ...

Проблема

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

Мой вопрос(ы)

  • Как я могу добавить аргумент запроса к ссылкам пагинации, когда присутствует поисковой термин? Метод set_pagination_args() не позволяет добавлять пользовательские аргументы к ссылкам пагинации.
  • Лучше отправить форму методом get (как рекомендовано здесь) с самого начала и заново сформировать значение action формы? В противном случае значение action становится слишком длинным, так как реферер добавляется каждый раз.

С этой проблемой я тоже столкнулся и предлагаю решение

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

if($("#listing-tbl").length) {
        if($("#search-search-input").length) {
            var search_string = $("#search-search-input").val();
            if(search_string != "") {
                $("#listing-tbll .pagination-links a").each(function() {
                    this.href = this.href + "&s=" + search_string;
                });
            }
        }
    }

Ответ или решение

Для решения проблемы с пагинацией и поиском в кастомном классе WP_List_Table в WordPress, когда данные отправляются методом POST, можно воспользоваться следующим подходом.

Шаг 1: Изменение метода отправки формы

Рекомендуется использовать метод GET вместо POST. Это позволит вам легко добавлять параметры запроса в URL и поддерживать состояние поиска при пагинации. Измените вашу форму следующим образом:

// List and form output
$page  = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRIPPED );
$paged = filter_input( INPUT_GET, 'paged', FILTER_SANITIZE_NUMBER_INT );
$search_query = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );

echo '<form method="get" id="list-hotels-form">';
printf('<input type="hidden" name="page" value="%s" />', esc_attr($page));
printf('<input type="hidden" name="paged" value="%d" />', esc_attr($paged));
printf('<input type="text" name="s" value="%s" placeholder="%s" />', esc_attr($search_query), esc_attr(__('Search Hotels', 'uruk')));
$hotel_table->prepare_items();
$hotel_table->display();
echo '</form>';

Шаг 2: Поддержка состояния поиска

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

Шаг 3: Настройка пагинации

Вам нужно будет переопределить методы pagination() или get_columns() в вашем классе WP_List_Table, чтобы настроить пагинацию и добавить туда параметры поиска.

Вот пример, как это сделать, изменяя метод pagination():

public function pagination($which) {
    if ( 'top' == $which ) {
        $this->screen = get_current_screen();
        $this->set_pagination_args();

        // Добавляем поисковый запрос к пагинационным ссылкам
        $pagination_args = $this->get_pagination_args();
        $pagination_args['s'] = filter_input(INPUT_GET, 's', FILTER_SANITIZE_STRING);

        // Выводим пагинацию
        // Здесь вам понадобится конструкция, подобная стандартной, но с учетом новых параметров
        $this->display_tablenav($which);
    }
}

Шаг 4: Обновление ссылок с помощью JavaScript

Если вы все же хотите использовать POST, как вы упомянули ранее и не хотите, чтобы поисковые параметры обрабатывались из URL, вы можете использовать JavaScript/jQuery для динамического обновления ссылок пагинации.

Вот пример кода, который обновляет ссылки при выполнении поиска:

jQuery(document).ready(function($) {
    if($("#listing-tbl").length) {
        $("#search-search-input").on('input', function() {
            var search_string = $(this).val();
            $("#listing-tbl .pagination-links a").each(function() {
                var url = new URL(this.href);
                if (search_string) {
                    url.searchParams.set('s', search_string);
                } else {
                    url.searchParams.delete('s');
                }
                this.href = url.toString();
            });
        });
    }
});

Заключение

Таким образом, рекомендуется использовать метод GET, поскольку он значительно упрощает работу с параметрами URL, в том числе с поиском и пагинацией. Однако, если вы решите продолжать использовать метод POST, вы можете использовать JavaScript для динамического обновления ссылок пагинации с учетом поисковых параметров.

Оцените материал
Добавить комментарий

Капча загружается...