【WordPress】Ajaxでチェックボックスを使ったリアルタイム絞り込み検索を実装する方法

【WordPress】Ajaxでチェックボックスを使ったリアルタイム絞り込み検索を実装する方法 WordPress

WordPressのサイトで、チェックボックスを使った絞り込み検索をリアルタイムで反映させる方法を紹介します。Ajaxを利用することで、ページをリロードせずに検索結果を動的に更新できます。

スポンサーリンク

チェックボックスの絞り込み検索とは?

チェックボックスを使った絞り込み検索とは、ユーザーが特定のカテゴリーやタグを選択することで、リアルタイムに検索結果を反映させる仕組みです。Ajaxを活用することで、ページをリロードせずに検索結果を更新し、ユーザー体験を向上させることができます。

フロントエンドの実装(HTML)

まず、検索フィルター用のチェックボックスと、検索結果を表示するエリアを作成します。

検索フィルター用のチェックボックスと結果表示エリア
<form id="filter-form">
  <div>
    <label><input type="checkbox" class="filter-checkbox" name="category[]" value="1"> カテゴリ1</label>
    <label><input type="checkbox" class="filter-checkbox" name="category[]" value="2"> カテゴリ2</label>
    <label><input type="checkbox" class="filter-checkbox" name="category[]" value="3"> カテゴリ3</label>
  </div>
</form>

<div id="search-results">
  <!-- 検索結果をここに表示 -->
</div>

JavaScript(Ajax処理)

次に、チェックボックスの変更を検知し、選択されたカテゴリーをAjaxで送信するスクリプトを作成します。

ajax-filter.js:チェック変更を検知してAjax送信
jQuery(document).ready(function ($) {
  $('.filter-checkbox').on('change', function () {
    let selectedCategories = [];

    $('.filter-checkbox:checked').each(function () {
      selectedCategories.push($(this).val());
    });

    $.ajax({
      url: ajax_object.ajaxurl,
      type: 'POST',
      data: {
        action: 'filter_posts',
        categories: selectedCategories
      },
      beforeSend: function () {
        $('#search-results').html('<p>検索中...</p>');
      },
      success: function (response) {
        $('#search-results').html(response);
      }
    });
  });
});

PHP(Ajaxリクエストの処理)

WordPress側でAjaxリクエストを処理し、該当する投稿を取得して表示する処理を追加します。

functions.php:選択カテゴリーで絞り込んだ投稿を返す
function filter_posts()
{
  $args = array(
    'post_type' => 'post',
    'posts_per_page' => -1
  );

  if (!empty($_POST['categories'])) {
    // term_idは必ず整数に揃えてからtax_queryに渡す
    $category_ids = array_map('intval', (array) $_POST['categories']);

    $args['tax_query'] = array(
      array(
        'taxonomy' => 'category',
        'field'    => 'term_id',
        'terms'    => $category_ids,
        'operator' => 'IN'
      )
    );
  }

  $query = new WP_Query($args);

  if ($query->have_posts()) {
    while ($query->have_posts()) {
      $query->the_post();
      echo '<h2><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></h2>';
    }
  } else {
    echo '<p>該当する記事がありません。</p>';
  }

  wp_die();
}

add_action('wp_ajax_filter_posts', 'filter_posts');
add_action('wp_ajax_nopriv_filter_posts', 'filter_posts');
入力値のサニタイズと出力エスケープを忘れずに
$_POST['categories']はブラウザから送られてくる値のため、array_map('intval', ...)で必ず整数の配列に揃えてからtax_queryに渡します。また、get_permalink()get_the_title()を直接echoする場合はesc_url()esc_html()で出力時にエスケープするのが安全な書き方です。

wp_localize_script でAjax URLを設定

functions.php に以下のコードを追加し、JavaScriptがajaxurlを認識できるようにします。

functions.php:スクリプトの読み込みとAjax URLの受け渡し
function enqueue_ajax_filter_script()
{
  wp_enqueue_script('ajax-filter', get_stylesheet_directory_uri() . '/js/ajax-filter.js', array('jquery'), null, true);
  wp_localize_script('ajax-filter', 'ajax_object', array('ajaxurl' => admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'enqueue_ajax_filter_script');
get_template_directory_uri() は親テーマのURLを返す
子テーマ環境でget_template_directory_uri()を使うと、URLが親テーマを指してしまいajax-filter.jsが404になります。子テーマのURLを正しく取得するにはget_stylesheet_directory_uri()を使ってください。

関連記事

よくある質問(FAQ)

Q複数のチェックボックスの値をJavaScriptでまとめて取得するには?
A$('.filter-checkbox:checked').each()でチェック済みの要素をループし、$(this).val()を配列に追加します。changeイベントのたびにこの配列を作り直してAjaxで送信します。
Qチェックボックスが1つも選択されていない場合の挙動は?
A本記事のPHPハンドラーでは$_POST['categories']が空の場合tax_queryを追加しないため、全件(posts_per_page => -1)が表示されます。特定のカテゴリーのみに絞りたい・未選択時は空にしたい場合は、条件分岐を追加してください。
Qカテゴリー以外(タグやカスタムタクソノミー)で絞り込むには?
Atax_query'taxonomy''post_tag'や独自のタクソノミー名に変更するだけで対応できます。複数のタクソノミーを同時に絞り込みたい場合は、tax_queryの配列に条件を追加し、'relation' => 'AND'を指定します。

まとめ

この方法を使用すると、WordPressサイトでリアルタイムのAjax絞り込み検索を実装できます。子テーマ環境でのURL取得、入力値のサニタイズ、出力時のエスケープの3点を押さえて、安全に実装しましょう。