【WordPressテーマの作り方 第17回】Ajaxで投稿一覧を非同期に切り替える方法

目次

🔄 ページリロードなしで快適に!Ajaxフィルターの導入

第16回では、GETパラメータを使った投稿一覧の絞り込みと並び替えを紹介しました。
今回はそれをさらに進化させて、ページをリロードせずに条件に応じた一覧を表示する「AjaxフィルターUI」を実装します!

「ボタンを押すたびにページが切り替わるのが気になる」
「もっと滑らかに絞り込みたい!」
──そんな悩みを解消するのが今回のテーマです。

✅ 今回のゴール

  • JavaScript(jQuery or vanilla)を使ってAjax通信を行う
  • ユーザーが選んだ条件(カテゴリや価格帯など)を非同期で送信
  • WP_Query を使って条件に合った投稿一覧HTMLを生成して返却
  • JSで返ってきたHTMLを一覧部分に差し替え

⚙️ 実装全体の流れ

graph TD
  A[フォームUI] --> B[JSがsubmitを検知]
  B --> C[AjaxでGETリクエスト送信]
  C --> D[functions.phpで処理]
  D --> E[WP_Queryで投稿取得]
  E --> F[部分テンプレートでHTML生成]
  F --> G[JSが受信 → DOM差し替え]

🧩 HTMLフォーム(前回のUIを流用)

例)セレクトボックスと送信ボタン

<form id="filterForm" class="p-filterForm">
  <label>
    カテゴリー:
    <?php
    wp_dropdown_categories([
      'show_option_all' => 'すべて',
      'name' => 'cat',
      'taxonomy' => 'product_category',
    ]);
    ?>
  </label>

  <label>
    並び順:
    <select name="sort">
      <option value="">選択してください</option>
      <option value="asc">価格が安い順</option>
      <option value="desc">価格が高い順</option>
    </select>
  </label>

  <button type="submit">絞り込む</button>
</form>

<div id="ajaxResult"></div>

🧠 JavaScriptでAjax送信

document.getElementById('filterForm').addEventListener('submit', function (e) {
  e.preventDefault();
  const formData = new FormData(this);
  const params = new URLSearchParams(formData).toString();

  fetch(`/wp-admin/admin-ajax.php?action=filter_products&${params}`, {
    method: 'GET',
  })
    .then(res => res.text())
    .then(html => {
      document.getElementById('ajaxResult').innerHTML = html;
    });
});

🧩 PHP側の処理(functions.php)

add_action('wp_ajax_filter_products', 'ajax_filter_products');
add_action('wp_ajax_nopriv_filter_products', 'ajax_filter_products');

function ajax_filter_products() {
  $args = [
    'post_type'      => 'product',
    'posts_per_page' => -1,
  ];

  // 並び順
  if (!empty($_GET['sort'])) {
    $args['meta_key'] = 'price';
    $args['orderby'] = 'meta_value_num';
    $args['order'] = ($_GET['sort'] === 'desc') ? 'DESC' : 'ASC';
  }

  // カテゴリ
  if (!empty($_GET['cat'])) {
    $args['tax_query'][] = [
      'taxonomy' => 'product_category',
      'field'    => 'term_id',
      'terms'    => intval($_GET['cat']),
    ];
  }

  $query = new WP_Query($args);

  if ($query->have_posts()) :
    echo '<ul class="p-productList">';
    while ($query->have_posts()) : $query->the_post();
      echo '<li><a href="' . get_permalink() . '">';
      echo '<h4>' . get_the_title() . '</h4>';
      echo '<p>価格:' . get_field('price') . '円</p>';
      echo '</a></li>';
    endwhile;
    echo '</ul>';
  else :
    echo '<p>該当する商品は見つかりませんでした。</p>';
  endif;

  wp_die(); // 終了
}

💡 実装のポイント

  • fetch APIはGET形式でURLに条件を付加
  • WP側は admin-ajax.php を使ってデータ取得
  • HTMLは完全なテンプレートで返すことでJS側の処理が簡単に

✅ まとめ

  • Ajaxならページ遷移なしで一覧を切り替えられる
  • UXを損なわずに「サクサク動く」UIが作れる
  • 絞り込み条件をHTMLに反映したり、URLにも出したいなら pushState の応用も検討

🔮 次回予告

次回「第18回」では、
セレクトボックスやチェックボックスに加えて、複数条件のチェックボックス(AND/OR) を組み合わせて使う方法にチャレンジします!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Web制作会社勤務、業界歴10年以上。現場を走り回ってきた制作者。
これからWeb制作を学ぶ人に寄り添いながら、実務で役立つ知識をわかりやすくシェアします。
「ゼロぐらいから学べる!」をモットーに、あなたの“がんばろ”を応援します!

目次