follow us in feedly
PHPJavaScriptjQuery

複合検索(絞り込み検索)をPHPとJavaScriptで実装(後編)

複合検索(絞り込み検索)の実装後編ではループ表示とページング機能を作るとともに、JavaScriptとAjax(jQuery)を使用してより使いやすい複合検索(絞り込み検索)フォームにしてみたいと思います。ワードプレスではAjax用のリクエストルートも用意されていますので確認していきます。

2019年3月5日

検索結果のループ表示と固定ページでのページング

検索結果を標準ループで表示

前回『複合検索(絞り込み検索)をPHPとJavaScriptで実装(前編)』までの内容でWP_Queryに与える引数$argsができましたので、あとはループを回すだけになります。記述は以下のようになります。

<?php $the_query = new WP_Query($args); ?>
<ul>
<?php if ($the_query->have_posts()) : ?>
<?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
	<li>
	・
	・
	・
	</li>
<?php endwhile; ?>
</ul>
<?php wp_reset_postdata(); ?>
<?php else : ?>
<p><?php echo esc_html('検索条件にヒットした募集はありませんでした'); ?></p>
<?php endif; ?>
ワードプレスの複合検索(絞り込み検索)フォーム

検索結果の件数はfound_postsプロパティで取り出せますので以下のようになります。

<h2>検索結果(該当<?php echo $the_query->found_posts; ?>件)</h2>

固定ページでページング機能を有効化

ページング機能はプラグインWP-PageNaviを使用していますが、検索結果を表示するページは今回は固定ページですのでpagedというキーに値を渡してあげなくてはなりません。
 三項演算子でややわかりにくいかもしれませんが、get_query_var(‘paged’)があればその値を$pagedに代入し、なければ1を代入するというのが以下の記述です。get_query_var(‘paged’)というのはURLにつく?paged=1などのことで、このページを最初に開いたときはget_query_var(‘paged’)がないので$pagedに1が代入され、2ページ目以降はWP-PageNaviによって$pagedに2、3、4が代入されていきます。

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
	'post_type' => 'career',
	'paged' => $paged,
	'posts_per_page' => 6,
);
	・
	・
	・
<?php $the_query = new WP_Query($args); ?>

プラグインWP-PageNaviの記述は以下のようになります。

<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(array('query' => $the_query)); } ?>

検索フォームにJavaScriptでパラメータを反映

検索結果ページにも検索フォームを設置することで繰り返し検索できるようにします。ただし、その場合は現在選択されている項目が検索フォームに反映されている方が親切でしょう。そこでJavaScriptを使ってURLパラメーターの値を検索フォームに反映させます。

ワードプレスの複合検索(絞り込み検索)フォーム
ワードプレスの複合検索(絞り込み検索)フォーム

例えば上記のように選択されている場合のURLパラメーターは以下のようになっています。

?term1[]=love_koukakurui&term2[]=hall_staff&term3[]=western_food&term4[]=ginza

このURLパラメーターをJavaScriptで取得し該当するチェックボックスにcheckedをつけます。

<script>
'use strict';
{
	if (1 < document.location.search.length) {
		const query = document.location.search.substring(1);
		const parameters = query.split('&');

		const array = [];
		for (let i = 0; i < parameters.length; i++) {
		  const element = parameters[i].split('=');
		   array.push(decodeURIComponent(element[1]));
		}
		// console.log(array); [ "love_koukakurui", "hall_staff", "western_food", "ginza" ]

		array.forEach((value) => {
			document.getElementById(value).setAttribute('checked', 'checked');
			});
  	}
}
</script>

上記のスクリプトは5行目で最初の?を除いた文字列を取得し、区切り文字に&を指定して分割し、さらに区切り文字に=を指定してキーと値に分割し、値の部分だけをarrayに格納しています。この時点で13行目にあるようにarrayの内容は[ “love_koukakurui”, “hall_staff”, “western_food”, “ginza” ]のようになっていますので、あとはforEachで一つずつ取り出して該当するチェックボックスにcheckedをつけています。

Ajax(jQuery)で絞り込み後の該当件数をリアルタイム表示

Ajax(jQuery)の記述

複合検索(絞り込み検索)の場合は、選択する組み合わせによってヒットする件数がかなり変わります。特に総件数が多くない場合は該当0件もありえます。したがって、ユーザーをがっかりさせないためにも検索ボタンを押す前に何件ヒットしているかを表示するのがよいでしょう。

ワードプレスの複合検索(絞り込み検索)フォーム
ワードプレスの複合検索(絞り込み検索)フォーム
<div id="search-result-count">上記選択での該当件数:<span></span>件</div>

ページを再読み込みせずに該当件数を更新させますのでAjaxを使います。今回はjQueryで記述しました。フォームのチェックボックスのいずれかが選択あるいは解除されるたびにAjaxが走り件数が更新されます。
 以下にAjaxの記述を載せましたが、今回のデータの送信先は/ajaxでアクセスできる固定ページとしています(※ワードプレスでAjaxを使用する場合、/wp-admin/admin-ajax.phpにデータを送信するのが正式なやり方です)。10行目のserialize()はフォームの値をURLパラメーターと同じクエリの形に整えてくれますので、/ajaxではこれまで作成したスクリプトをそのまま使うことができます。Ajax通信に成功すると件数が数値で返ってきますので、13行目にあるように件数を表示する要素内にその値を入れてあげます。

■main.js
<script>
'use strict';
{
	const $form = $('#form1');
	const $count = $('#search-result-count span');
	$form.change(() => {
		$.ajax({
			url: '/ajax',
			type: 'POST',
			data: $form.serialize()
			})
		.done((response) => {
			$count.text(response);
			})
		.fail((response) => {
			$count.text('Security check');
			})
	})
}
</script>

送信先(任意の固定ページ)のPHPの記述

/ajaxでアクセスできる固定ページの記述は以下になります。省略している部分は別記事でご説明したURLパラメーターからWP_Queryの引数$argsを作るスクリプトです。
 6〜10行目にかけては何も選択されていない場合の件数、つまり総件数を取得するようにしています。これは最初に検索ページにアクセスした際(何も選択されていない場合)に総件数を表示するためです。

■page-ajax.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
	・
	・
	・
if(!isset($_POST['term1']) && !isset($_POST['term2']) && !isset($_POST['term3']) && !isset($_POST['term4'])) {
  $res = wp_count_posts('career')->publish;
  echo $res;
  exit;
}

$the_query = new WP_Query($args);
$res = $the_query->found_posts;
echo $res;
exit;
}

以下は/wp-admin/admin-ajax.phpにデータを送信する場合の記述です。ご参考ください。

■送信元のphpファイル内にjQueryで記述した場合
<script>
'use strict';
{
  const $form = $('#form1');
  const $count = $('#search-result-count span');
	$form.change(() => {
    $.ajax({
        url: '<?php echo admin_url('admin-ajax.php'); ?>',
        type: 'POST',
        data: $form.serialize() + '&action=career_search' + '&_wpnonce=<?php $nonce = wp_create_nonce( 'career_search' ); echo $nonce; ?>'
        })
     .done((response) => {
          $count.text(response);
	    })
     .fail((response) => {
          $count.text('Security check');
	    })
  })
}
</script>
■functions.php
function career_search(){

  if ($_SERVER['REQUEST_METHOD'] === 'POST') {

	  $nonce = $_POST['_wpnonce'];
	  if (!wp_verify_nonce($nonce, 'career_search')) {
	      die('Security check');
	  }
		・
		・
		・
  }
}
add_action('wp_ajax_career_search', 'career_search');
add_action('wp_ajax_nopriv_career_search', 'career_search');

以上で「複合検索(絞り込み検索)をPHPとJavaScriptで実装(後編)」の解説を終わります。

このエントリーをはてなブックマークに追加