Вопрос или проблема
Я использую пользовательский класс 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 для динамического обновления ссылок пагинации с учетом поисковых параметров.