Blog スタッフブログ

WEB制作

[WordPress]Ajaxで予測検索を表示

フリーワード検索に一致する記事リンクをajaxで表示する方法をご紹介します。

通常、検索フォーム→リザルト画面→記事詳細という手順で進みますが、予測検索を表示することで検索フォーム→記事詳細と手順を省略できます。

手順

検索フォームの記述

<form id="searchForm" role="search" method="get" action="/">
  <input type="hidden" value="news" name="post_type" id="post_type" />
  <input id="searchformInput" type="text" placeholder="検索ワードを入力してください" value="<?php echo get_search_query(); ?>" name="s" />
  <!--予測検索の表示場所-->
  <div id="searchResults">
  </div>
  <input class="searchBtn" type="submit" value="検索">
</form>

通常通りのフリーワード検索フォームに予測検索用の表示場所を追加しています。

<div id="searchResults"></div>

の中に予測検索の内容が表示されます。

予測検索の表示処理

jQuery(document).ready(function($) {
    var searchInput = $('#searchformInput'); // 検索入力フィールドのID
    var resultsContainer = $('#searchResults'); // 検索結果を表示するコンテナのID
    var searchResultsVisible = false;

    searchInput.on('input', function() {
        var searchTerm = $(this).val();
        if (searchTerm.length > 0) {
            $.ajax({
                url: ajax_object.ajaxurl,
                method: 'POST',
                data: {
                    action: 'instant_search',// 予測検索の処理を行うアクション名
                    term: searchTerm // 入力されたキーワード
                },
                beforeSend: function() {
                    resultsContainer.html('検索中...');
                }
            }).done(function(data) {
                resultsContainer.html(data);
                if (!searchResultsVisible) {
                    resultsContainer.show();
                    searchResultsVisible = true;
                }
            }).fail(function() {
                resultsContainer.html('エラーが発生しました');
            });
        } else {
            resultsContainer.empty();
            resultsContainer.hide();
            searchResultsVisible = false;
        }
    });
});

事前にjQueryを読み込みます。

Javascriptのファイルを用意して以下を記述します。

入力したワードに部分一致もしくは完全一致する記事を表示します。

検索内容の中身

function instant_search() {
  // 検索キーワードを取得
  $term = $_POST['term']; 
  $args = array(
      'post_type' => 'news',
      's' => $term,
  );
  $query = new WP_Query($args);

  // 検索結果がある場合
  if ($query->have_posts()) {
    echo '<div class="searchInstant">';
    echo '<ul>';
    while ($query->have_posts()) {
      $query->the_post();
      // 検索結果の表示を実装
      // ここでは、投稿タイトルとリンクを出力しています
      echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
    }
    echo '</ul>';
    echo '</div>';
  } else {
    // 検索結果がない場合の表示を実装
    echo '<div class="text">';
    echo '該当する結果候補はありませんでした。';
    echo '</div>';
  }
  wp_reset_postdata(); // クエリのリセット
  wp_die(); // 処理を終了
}
add_action('wp_ajax_instant_search', 'instant_search');
add_action('wp_ajax_nopriv_instant_search', 'instant_search');

function include_news_in_search( $query ) {
  if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
    $query->set( 'post_type', array( 'post', 'news' ) ); // 'news'を検索対象に含める
  }
}
add_action( 'pre_get_posts', 'include_news_in_search' );

カスタム投稿のnewsを検索対象に含めています。

if ($query->have_posts()) { の中に表示する内容を記述します。

後はデザインに応じてCSSで見た目を整えて完了です。