ハシウェブ

Web制作、プログラミングに関する情報を発信するブログ

WordPressでAjaxを使って投稿を検索する方法【jQuery】

WordPressでAjaxを使って投稿を検索する方法【jQuery】

「WordPressで再読み込みせずに検索をしたい」

「WordPressでAjaxを使うにはどうしたらいいの?」

悩み

こんな悩みにお答えします。

じつは、WordPressでPHPだけを使った検索機能を実装すると検索のたびに送信、再読み込みをすることになり動作が遅延してしまいます。

これをjQueryのAjax(非同期通信)を使うことにより、以下のような再読み込みをすることなくリアルタイムに気持ちのよい検索機能を実装することができます。

0 300
投稿ID:

この記事では、上記の動作をつくるためのHTML、PHP、jQueryの実装方法を解説します。

記事を読み終えると、WordPressでAjaxを使った検索機能を実装することができます。
実際につくった機能はシンプルなもので、そのまま使う機会はあまりないとは思いますが、アレンジ次第ではいろいろなことに応用することもできます。

目次
  1. WordPressでAjaxを使って投稿を検索する方法
    1. HTMLで検索フォーム、表示場所を決める
    2. jQueryにAjaxを設定する
    3. PHPで検索条件、検索結果の表示をつくる
  2. まとめ

WordPressでAjaxを使って投稿を検索する方法

実際の案件でカスタムフィールドを使った数値検索機能をつくったのですが、カスタムフィールドの解説も必要になりそうなので、投稿IDで検索する機能をつくっていきます。
あまり実用性はないかもしれませんが、いろいろな検索にアレンジしてみてください。

今回はinputのrangeとnumberを使って、数値を変更すると同時に検索を実行させます。

WordPressでのjQuery導入については、以下の記事にて解説しています。

【WordPress】jQueryの導入手順(読み込み、使い方)【JavaScript】

「jQuery」のはじめかたについて知りたいですか?この記事では「jQuery」の使い方(読み込み、書き方、チェック方法)について解説しています。あわせて、WordPressでの使い方についても解説します。ぜひご覧ください。

HTMLで検索フォーム、表示場所を決める

検索するためのHTMLのformパーツと、検索結果を表示させるタグを設定しておきます。

デフォルト値が不要な場合は、valueは空でもかまいません。

<div>0 <input id="js-range" max="1000" min="0" step="1" type="range" value="<?php the_ID(); ?>"> 1000</div>
<div>投稿ID: <input id="js-number" max="1000" min="0" step="1" type="number" value="<?php the_ID(); ?>"></div>

<div id="js-results" class="results"></div>

jQueryにAjaxを設定する

footerの下あたりにJavaScriptを書いていきます。

サンプルでつくったものをそのまま書いていますが、もっとシンプルな書き方でいいと思います。

let、const、varの使い分けができておらず、まったく使っていません。
動作は問題ないですが、そのあたりうまいことやってください。

<script>
jQuery(function(){
  jQuery(document).ready( function(){
    getDisplay( <?php the_ID(); ?> );
  });
  

  //rangeとnumberの同期
  inputSync( "#js-range", "#js-number" );
  //numberとrangeの同期
  inputSync( "#js-number", "#js-range" );
});

function inputSync( input , output ){
  tagInput = jQuery( input );
  tagOutput = jQuery( output );
  
  tagInput.on("input change", function(){
    val = jQuery(this).val();
    //console.log(val);

    tagInput.val( val );
    tagOutput.val( val );

    getDisplay( val );
  });

}

function getDisplay( val ){
  ajaxUrl = "<?php echo esc_url( admin_url( 'admin-ajax.php', __FILE__ ) ); ?>";

  jQuery.ajax({
    type: "POST",
    url: ajaxUrl,
    data: {
      "action": "searchResults",
      "nonce": "<?php echo wp_create_nonce( "my-ajax-nonce" ); ?>",
      "name":  val
    },
    success: function( response ) {
      //console.log( "成功しました:" + response );
      jQuery("#js-results").stop().html( response );
    }

  });
}
</script>

コードごとに解説します。

jQuery(document).ready( function(){
  getDisplay( <?php the_ID(); ?> );
});

読み込み時に実行する内容を書きます。
読み込み時にデフォルト値がいらない場合はこれがなくても大丈夫です。
【 getDisplay() 】は、Ajaxの内容になります。

//rangeとnumberの同期
inputSync( "#js-range", "#js-number" );
//numberとrangeの同期
inputSync( "#js-number", "#js-range" );

【 inputSync() 】は、第1引数に入力、変更された数値を、第2引数へ同期し出力します。
同時にAjaxも実行します。
これはオリジナルなのでまったく別の書き方でかまいません。

rangeを変更したとき、numberを変更したとき、どちらでも同じ動作になるようにしています。

function inputSync( input , output ){
  tagInput = jQuery( input );
  tagOutput = jQuery( output );
  
  tagInput.on("input change", function(){
    val = jQuery(this).val();
    //console.log(val);

    tagInput.val( val );
    tagOutput.val( val );

    getDisplay( val );
  });
}

【 inputSync() 】の、第1引数の要素が「input」または「change」されたときに動作します。
「input」だけだとIEでうまく動かなかったので、「change」とどちらかで動くようにしています。
「change」だけだとキーボード1文字入力ごとに実行されず、動きがイマイチです。

第1引数の要素から取得した数値を、第2引数の要素へ出力します。

同時に【 getDisplay() 】へも出力します。

function getDisplay( val ){
  ajaxUrl = "<?php echo esc_url( admin_url( 'admin-ajax.php', __FILE__ ) ); ?>";

  jQuery.ajax({
    type: "POST",
    url: ajaxUrl,
    data: {
      "action": "searchResults",
      "nonce": "<?php echo wp_create_nonce( "my-ajax-nonce" ); ?>",
      "name":  val
    },
    success: function( response ) {
      //console.log( "成功しました:" + response );
      jQuery("#js-results").stop().html( response );
    }

  });
}

【 getDisplay() 】は、まず第1引数で数値を取得します。

admin-ajax.phpを読み込みます。

dataのactionに、PHPで設定した関数名「searchResults」を指定します。

dataのnonceに、wp_create_nonceを指定します。
ここはセキュリティのための設定です。

dataのnameに、取得した数値を設定し、Ajaxで送信します。

Ajax送信が成功し、データが返ってきたあとの処理を「success」に書いていきます。
responseが返ってきたデータです。

【 #js-results 】に、responseをHTML形式で出力します。

PHPで検索条件、検索結果の表示をつくる

functions.phpに検索条件を指定し、実際に表示させたい形式でHTMLタグを書きます。

ここではいきなりフックに書いていますが、はじめにWordPressのテンプレートで検索条件が正しく動作し、検索結果が正しく表示できることを確認してからフックにあてはめたほうがわかりやすいです。

Ajaxがうまくいっていないのか、PHPの検索がうまくいっていないのか、失敗したときの原因の切り分けができるようにしておくことが大事です。

function searchResults(){
	if( $_POST["name"] ){
		$num = $_POST["name"];
	}
	
	$nonce = $_REQUEST["nonce"];
	if ( wp_verify_nonce( $nonce, "my-ajax-nonce" ) ) {

/* 検索条件設定 ↓ ************************************************* */
		$args["post_type"] = "blog";
		$args["posts_per_page"] = 1;
		$args["post__in"][] = "";

		if( isset( $num ) || $num > 0 ){
			$args["post__in"][] = $num;
		}
/* 検索条件設定 ↑ ************************************************* */

		$query = new WP_Query( $args );

		if ( $query->have_posts() ) :
			while ( $query->have_posts() ):
				$query->the_post();

/* 検索結果表示 ↓ ************************************************* */
?>
		<dl class="box-archive">
			<dd>
				<a href="<?php the_permalink(); ?>">
					<picture>
						<img src="<?php echo wp_get_attachment_image_src( $attachment_id )[0]; ?>" width="400" height="210" alt="<?php the_title(); ?>" loading="lazy">
					</picture>
				</a>
			</dd>
			<dd>
				<time><?php the_time("Y.m.d"); ?></time>
			</dd>
			<dt>
				<?php the_title(); ?>
			</dt>
		</dl>
<?php
/* 検索結果表示 ↑ ************************************************* */
			endwhile;
		else:
?>
	<p>投稿がありません</p>
<?php
		endif;
		wp_reset_postdata();

	}
	die();
}
add_action( "wp_ajax_searchResults", "searchResults" );
add_action( "wp_ajax_nopriv_searchResults", "searchResults" );

WordPressでAjaxを使って投稿を検索する方法の例

以下の記事を参考にさせていただきました。

まとめ

WordPressでAjaxを使って投稿を検索する方法を解説しました。

  • HTMLで検索フォーム、表示場所を決める
  • jQueryにAjaxを設定する
  • PHPで検索条件、検索結果の表示をつくる

WordPressでAjaxを使うことで、再読み込みをすることなくリアルタイムに気持ちのよい検索機能を実装することができます。