質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.35%

WordPressでAjaxを使ったリアルタイムな複合検索をおこないたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,188

score 16

以下のように、カスタムフィールドやカテゴリーの選択肢をラジオボタンで選んで、「検索」ボタンをクリックすると該当記事一覧が表示される、いわゆる普通の検索ページがあります。

例)
・カテゴリー(カテゴリー): カテ1 カテ2
・カスタム項目A(カスタムフィールド): カスタムA1 カスタムA2 
・カスタム項目B(カスタムフィールド): カスタムB1 カスタムB2 

これを、ラジオボタンのcheckedが変わるたびに(=選択/選択の変更をトリガーにして)、ボタンを押さなくてもその条件に該当する記事一覧を
その都度リアルタイムに表示させたいです。

まずは該当ページのHTMLですが、

●検索フォーム部分
<form method="get" id="searchform" action="<?php echo esc_url(home_url()); ?>/page/">
<input id="cat01" type="radio" name="cat" value="cat01">
<label for="cat01">カテ1</label>

<input id="cat02" type="radio" name="cat" value="cat02">
<label for="cat02">カテ2</label>

<input id="cus-a1" type="radio" name="cus-a" value="cus-a1">
<label for="cus-a1">カスタムA1</label>

<input id="cus-a2" type="radio" name="cus-a" value="cus-a2">
<label for="cus-a2">カスタムA1</label>

<input id="cus-b1" type="radio" name="cus-b" value="cus-b1">
<label for="cus-b1">カスタムB1</label>

<input id="cus-b2" type="radio" name="cus-b" value="cus-b2">
<label for="cus-b2">カスタムB1</label>
<input type="submit" class="submit" name="submit" id="searchsubmit" value="検索" /></div>
</form>


●検索まわりの部分
$my_cat = $_GET['cat'];
$cus_a = $_GET['cus-a'];
$cus_b = $_GET['cus-b'];

if($cus_a){
    $meta_key[] = array(
        'key'=>'cus_a',
        'value'=> $cus_a,
        'compare'=>'=',
    );
}
if($cus_b){
    $meta_key[] = array(
        'key'=>'cus_b',
        'value'=> $cus_b,
        'compare'=>'=',
    );
}
$meta_key['relation'] = 'AND';

$args = array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    'post_status' => 'publish',
    'paged' => $paged,

    'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => $my_cat,
            'operator' => 'IN'
        ),
    ),
    'meta_query' => $meta_key,
);
$my_result = new WP_Query($args);


●記事一覧表示部分
<div id="search-list" class="search-list">
    <?php if( $my_result->have_posts()): while( $my_result->have_posts()): $my_result->the_post(); ?>
    <div><a href="<?php the_permalink(); ?>"><?php the_title();?></a></div>
    <?php endwhile; endif; wp_reset_postdata(); ?>
</div>

と記述し「検索」ボタンでクリックで正常に記事一覧が取得できている状態です。
ここから、functions.phpにadmin-ajax.phpを読み込むためのコードを以下のように記述しました。

<?php function add_my_ajaxurl() { ?>
    <script>
        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php'); ?>';
    </script>
<?php
}
add_action( 'wp_footer', 'add_my_ajaxurl', 1 );

続いて、同じくfunctions.phpにjsから呼び出すアクションフックを記述しました。
基本はテーマファイルの検索まわりに書いたコードを同じになります。

function my_ajax_get_posts(){
       // 1. 受け渡しするデータ
    $my_cat = $_POST['cat'];
    $cus_a = $_POST['cus-a'];
    $cus_b = $_POST['cus-b'];

    // 2. フォームの値を検索条件にセット
    if($cus_a){
        $meta_key[] = array(
            'key'=>'cus_a',
            'value'=> $cus_a,
            'compare'=>'=',
        );
    }
    if($cus_b){
        $meta_key[] = array(
            'key'=>'cus_b',
            'value'=> $cus_b,
            'compare'=>'=',
        );
    }
    $meta_key['relation'] = 'AND';

    // 3. get_posts オプション
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => -1,
        'post_status' => 'publish',
        'paged' => $paged,

        'tax_query' => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'category',
                'field' => 'slug',
                'terms' => $my_cat,
                'operator' => 'IN'
            ),
        ),
        'meta_query' => $meta_key,
    );

    // 結果取得
    $my_result = new WP_Query($args);
    $response = '';
    $my_result->post_count = count( $my_result->posts );

    // マッチした記事数をセット
    $get_num = $my_result->post_count;


    // 投稿表示
    if($my_result->have_posts()) {
        while($my_result->have_posts()){
            $my_result->the_post();
            $response .= get_template_part('loop-posts'); // テーマファイルで記述したループと同じコードを記述したテンプレートファイル
        };
    } else {
        $response .= get_template_part('none');
    }
    //wp_reset_postdata();
    echo $response;
    exit;
}
add_action( 'wp_ajax_my_get_posts', 'my_get_posts' );
add_action( 'wp_ajax_nopriv_my_get_posts', 'my_get_posts' );

最後にfooter.phpにjsで以下のように記述しています。

<script>
// strictモード(厳格モード)」で実行
'use strict';

jQuery(function($){
    // 1. 出力するクラスを設定
    var resultArea = $('.archive-search-section');

    // 2. ラジオボタンの変更をトリガーに
    $('input[name="post-select-type1"] , input[name="post-select-type2"]').change(function() {

    // 3. 出力するクラスの投稿を全削除
    resultArea.children().remove();

    // 4. ajax
    $.ajax({
        type: 'POST',
        url: ajaxurl,
        dataType: "html",
        data: {
            // actionでアクションフックを実行
            action : 'my_get_posts',
        },
        success: function( response ) {
            console.log( response );
            resultArea.html( response ); 
        },
        error: function(){
                    console.log("Ajax処理エラー" );
        },
        complete: function(){
                    console.log( "Ajax処理終了" );
        }
    });
    });
});
</script>

としています。

これでラジオボタンを選択/変更すると、対象クラス内のコードが正常に消えるのですが、該当する記事一覧が表示されず「0」と、数字のゼロが表示されるだけです。コンソールログを見ると「Ajax処理終了」と出ているので、動作自体は問題がないようです。

これはどこに問題があるのでしょうか?教えてください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+4

admin-ajax 側で POST 変数を受けるのであれば、POST リクエストを送る際に data で必要なデータを渡してください。

data: {
  // actionでアクションフックを実行
  action: 'my_get_posts',
  cat: ..., // 適宜値を入れてください.
  'cus-a': ...,
  'cus-b': ...
},

追記前

get_template_part 関数は値を返しません。
変数に代入するためには ob_start/ob_get_clean などを使用する必要があります。

ob_start();
get_template_part( 'loop-posts' );
$response .= ob_get_clean();

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/30 17:57

    ありがとうございます。回答いただいた内容にしてみましたが、動きませんでした。そうなると値の受け渡しが出来ていない可能性がありますね。もう少し調べてみます。

    キャンセル

  • 2019/07/31 09:14

    ありがとうございます、出来ました!なるほど、dataの中に渡す値もセットしないといけなかったんですね。勉強になりました!

    キャンセル

+1

関数名をmy_ajax_get_postsからmy_get_postsに変えてみてはどうでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/30 11:32

    これでだめなら、my_get_posts関数の中の各ステップで出力される内容をvar_dump()とdie()で出力してconsole.logで確認してみましょう。

    キャンセル

  • 2019/07/30 17:57

    ありがとうございます。確かに関数名が違っていましたね、失礼しました。修正してみましたがやはり改善されず。ご教示いただいた通り、各ステップの内容を確認してみたいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る