検索結果をリアルタイムで表示させるサイトをいくつか見たことがあって、かっこいいなぁと思っていました。
そこでwordpressで実装できないかなと思って、やってみたら意外と簡単に実装でき、実際にこのサイトにも組み込んでいます。
ナビゲーションの「Search」をクリックすると下の画面と同じモーダルが開くので、試してみてください。
実際に実装した方法を説明していきます。
実装した機能
実装した機能は以下のものです。
- 1文字入力ごとにリアルタイムで検索結果を表示
- 検索結果に合致する最新3件の記事表示
- 検索結果に合致する記事総数の表示
- 検索結果がない場合に検索結果がない旨の表示
検索結果がない場合、通常は「検索する」ボタンをクリックして検索結果画面に遷移してからやっと分かることですが、遷移する前に検索結果がないことが分かるのは使い勝手がいいです。
また記事総数の表示も先に分かるので絞り込みがやりやすくなります。
実装したコード
実装したコードの説明の前にどのように実装したかを説明していきます。
利用したのはwordpressの検索ページのテンプレートsearch.phpです。
wordpressは「https:〇〇/?s=キーワード」で検索結果が表示され、その時に使用されるのがsearch.phpです。
このページに独自のURLパラメータを追加してアクセスしたときには、通常の検索結果とは別のhtmlを返すように設定をし、そのhtmlをjavascript取得して、表示するといった流れで、今回のリアルタイム表示は実装しました。
search.php
<?php if(isset($_GET['quickview'])): ?>
<?php
$keyword = $_GET['s'];
$args = array(
'post_type' => array('post','custon_post'), // 検索するページ属性
'paged' => 1,
'posts_per_page'=> 3, // 表示する件数
's' => $keyword,
'orderby'=>'date'
);
$custom_query = new WP_Query( $args );
if ($custom_query->have_posts()) :
?>
<p><?php echo $wp_query->found_posts; ?>件見つかりました。</p>
<?php while ($custom_query->have_posts() ): $custom_query->the_post();?>
<article>
<!-- アイキャッチ画像 -->
<?php if(has_post_thumbnail()): ?>
<a href="<?php the_permalink(); ?>">
<img src="<?php the_post_thumbnail_url( 'medium' ); ?>" alt="<?php the_title()?>"/>
</a>
<?php endif; ?>
<!-- 記事タイトル -->
<h2><a href="<?php the_permalink(); ?>"><?php the_title()?></a></h2>
</article>
<?php endwhile; ?>
<?php else: ?>
<p>検索結果が見つかりません。</p>
<?php endif; ?>
<?php else: ?>
<!-- 通常の検索結果画面 -->
<?php endif; ?>
最初の「if(isset($_GET['quickview']))」で条件分岐していますが、URLパラメータに「quickview」があった場合にはリアルタイム表示用のhtmlを表示するように条件分岐しています。
つまり「https:〇〇/?s=キーワード&quickview=1」といった感じでアクセスすると通常とは違う検索結果が表示されます。
「通常の検索結果画面」とある箇所には、通常の検索結果ページのためのコードを書きますが、今回は割愛しています。
下記の説明は「コードをポップアップで見る」をクリックして確認してください。行数はポップアップしたページに対応して説明しています。
5行目のpost_typeで検索するページのpost_typeを設定しています。
固定ページも検索に追加した場合は'post'を追加したり、カスタム投稿タイプを新たに追加したり、適宜変更します。
7行目が表示する記事件数になります。
12行目の「if ($custom_query->have_posts()) :」に対応する「else」は27行目になり、検索結果がない場合は「検索結果が見つかりません。」と表示されるようになっています。
13行目の「$wp_query->found_posts;」で検索結果に合致する記事総数を表示しています。
html(検索フォーム)
<form>
<input type="text" name="s" class="keyword-input">
<button type="submit" class="keyword-submit">検索</button>
</form>
<!-- 検索結果がリアルタイムで表示されるエリア -->
<div class="quickview">
</div>
<!-- END 検索結果がリアルタイムで表示されるエリア -->
検索フォームの分かりやすくコードは簡素化しています。
<div class="quickview">内に「https:〇〇/?s=キーワード&quickview=1」にアクセスして取得したhtmlを挿入します。
javascript
const input = document.querySelector('.keyword-input');
const quickview = document.querySelector('.quickview');
const getQuickSearch = (keyword) =>{
if( keyword == '' || keyword == null || keyword == undefined ){
quickview.innerHTML = '';
}else{
const url = '/?s='+keyword+'&quickview=1';
const req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
quickview.innerHTML = req.responseText;
}
}
}
req.open('GET',url, true);
req.send(null);
}
}
input.addEventListener('keyup',()=>{
getQuickSearch(input.value);
});
input.addEventListener('change',()=>{
getQuickSearch(input.value);
});
javascriptのコードもそこまで多くなく、やっていることはXMLHttpRequestで取得したhtmlを<div class="quickview">内に表示するということだけをやっています。
下記の説明は「コードをポップアップで見る」をクリックして確認してください。行数はポップアップしたページに対応して説明しています。
5行目、inputに何も入っていないときはquickviewの要素内を空にしています。
7行目、取得する検索結果ページのURLです。
「s=keyword」とすることで、入力したキーワードを検索した場合の検索結果になります。keywordはgetQuickSearch関数の引数なので実際は、input.valueでフォームに入れた値になります。
リアルタイム表示用でアクセスするので、「quickview=1」のURLパラメータが付いています。
keyupとchangeどちらのイベントでもgetQuickSearch関数が発火するようにしています。
やってみたら、意外に簡単に実装できました。
リアルタイムで検索結果が表示されるって、インタラクティブ感が出て、なんとなくかっこいいので、ぜひ実装してみてください!