Автозаполнение или автоподсказка из списка заголовков записей

15 июл. 2012 г., 19:05:42
Просмотры: 21.1K
Голосов: 13

Я хочу добавить функцию автозаполнения или автоподсказки в (поисковую) форму:

Когда пользователь начинает вводить текст, форма должна предлагать заголовки записей, содержащие совпадающий текст.

Также я хотел бы отображать некоторые метаданные (число), которые я сохранил для каждой пользовательской записи. Пример:

Если я введу "A", должны появиться подсказки "Яблоки (13), Трубкозубы (51), Астронавты (21)" и т.д.

3
Комментарии

Как называется мета-поле? Пожалуйста, добавьте код, который показывает точно, как вы добавили мета-поле. Спасибо.

kaiser kaiser
15 июл. 2012 г. 20:08:21

Я предположил, что мета-поле было специально добавлено (через добавление метабокса) или это пользовательская переменная записи, к которой можно получить доступ через get_post_meta (если не ошибаюсь)

Barry Carlyon Barry Carlyon
15 июл. 2012 г. 20:15:31

Я еще не добавил мета-поле.

marctain marctain
15 июл. 2012 г. 20:15:34
Все ответы на вопрос 1
10
19

Да, это возможно.

Вы можете использовать jQuery Auto Suggest, который включен в WordPress http://codex.wordpress.org/Function_Reference/wp_enqueue_script

С его помощью можно создать форму, которая выполняет Ajax-запрос к обработчику URL Ajax. К которому вы можете подключиться через add_action. http://codex.wordpress.org/AJAX_in_Plugins

Таким образом, можно выполнить Ajax-поиск, а затем на стороне действия просто выполнить get_posts для сопоставления заголовков или сырой SQL-запрос. И вернуть то, что требуется.

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

Редактирование: Вот пример, что-то вроде этого должно работать, не тестировал, просто написал навскидку. Обновление: Экранировать введенный текст, ограничить по типу записи и только опубликованным записям.

Редактирование 2012-11-21: исправлена опечатка в примере кода.

add_action('wp_enqueue_scripts', 'se_wp_enqueue_scripts');
function se_wp_enqueue_scripts() {
    wp_enqueue_script('suggest');
}

add_action('wp_head', 'se_wp_head');
function se_wp_head() {
?>
<script type="text/javascript">
    var se_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';

    jQuery(document).ready(function() {
        jQuery('#se_search_element_id').suggest(se_ajax_url + '?action=se_lookup');
    });
</script>
<?php
}

add_action('wp_ajax_se_lookup', 'se_lookup');
add_action('wp_ajax_nopriv_se_lookup', 'se_lookup');

function se_lookup() {
    global $wpdb;

    $search = like_escape($_REQUEST['q']);

    $query = 'SELECT ID,post_title FROM ' . $wpdb->posts . '
        WHERE post_title LIKE \'' . $search . '%\'
        AND post_type = \'post_type_name\'
        AND post_status = \'publish\'
        ORDER BY post_title ASC';
    foreach ($wpdb->get_results($query) as $row) {
        $post_title = $row->post_title;
        $id = $row->ID;

        $meta = get_post_meta($id, 'YOUR_METANAME', TRUE);

        echo $post_title . ' (' . $meta . ')' . "\n";
    }
    die();
}
15 июл. 2012 г. 19:39:06
Комментарии

Вау, спасибо, Барри! Я попробую, это нужно вставить в functions.php, верно? Я изменю необходимые части и посмотрю, что получится

marctain marctain
15 июл. 2012 г. 19:58:33

Теоретически да, в functions.php. Я бы поместил это в плагин, чтобы не мешалось. Если вставлять прямо в functions.php, то можно провести оптимизацию, так как часть этого кода может быть применена к уже существующим функциям в functions.php (зависит от темы, конечно)

Barry Carlyon Barry Carlyon
15 июл. 2012 г. 19:59:35

Обновил код, включив like_escape. Я не использую % в начале, потому что нужно искать посты, заголовки которых начинаются с введенной буквы. Это не глобальное совпадение. Мой рабочий код использует $_REQUEST['q'] без дополнительных параметров для jQuery suggest. Q имитирует то, что используют поисковые системы.

Barry Carlyon Barry Carlyon
15 июл. 2012 г. 20:07:57

Это работает... почти! Я должен был уточнить, что хотел получить данные из произвольного типа записи (custom-post-type), сейчас отредактирую свой вопрос.

marctain marctain
15 июл. 2012 г. 20:07:57

@BarryCarlyon Пожалуйста, не редактируйте каждую мелочь. Если вы сделаете 10 правок, вопрос автоматически станет "вики сообщества", и вы потеряете все очки репутации. А нам нужно больше пользователей с хорошими ответами и минимальным уровнем репутации для таких задач, как редактирование, добавление вики и т.д. И кстати, exit; всегда быстрее, чем die(); :)

kaiser kaiser
15 июл. 2012 г. 20:10:29

Последнее замечание: Не сохраняйте переменные, которые используете только один раз ($id = $row->ID). Используйте их напрямую.

kaiser kaiser
15 июл. 2012 г. 20:11:55

@kaiser в документации WordPress: http://codex.wordpress.org/AJAX_in_Plugins указано, что для этого следует использовать die();. В противном случае я бы согласился

Barry Carlyon Barry Carlyon
15 июл. 2012 г. 20:12:24

Привычка делать $x = $row->x, обычно в моих циклах выполняется гораздо больше действий

Barry Carlyon Barry Carlyon
15 июл. 2012 г. 20:13:23

Отлично! Просто из любопытства, есть ли способ настроить это так, чтобы можно было напрямую передавать тип записи для получения? У меня есть несколько разных типов записей, для которых это может понадобиться. Сейчас рассматриваю вариант установки transient при настройке текстового поля с последующим его получением в этом скрипте...

Kaji Kaji
14 февр. 2015 г. 08:43:52

Конечно, просто замените "AND post_type = \'post_type_name\'" на код для получения post_type_name из $_REQUEST (с соответствующей экранизацией) и убедитесь, что ваша форма поиска включает скрытое поле с вашим значением. Например: "<input type="hidden" name="post_type" value="somename" />" и подставьте это в запрос

Barry Carlyon Barry Carlyon
14 февр. 2015 г. 13:25:57
Показать остальные 5 комментариев