jQuery で実現する高速キーワード検索とタグ検索(Movable Type 版)- jQuery Search Box

このブログの検索を自作の jQuery プラグイン「jQuery Search Box」に変えてみました。 まだまだイマイチなコードなんですが、とりあえずキーワード検索に加えてタグ検索も出来るようにしたので、記事にしてみます。タグ検索の方は結構お気に入りです。...

このブログの検索を自作の jQuery プラグイン「jQuery Search Box」に変えてみました。

まだまだイマイチなコードなんですが、とりあえずキーワード検索に加えてタグ検索も出来るようにしたので、記事にしてみます。タグ検索の方は結構お気に入りです。

検索用JSONの準備

jQuery Search Box プラグインは、あらかじめ用意された JSON ファイルを読み込み、その内容を検索する仕組みです。

したがって、検索させたい内容をすべて含んだ JSON ファイルが必要となります。Movable Type であれば、スタティックなファイルを自由に書き出せるので、そう言った意味で「Movable Type 版」と言い、以下では MT を前提に説明しますが、他の CMS やスタティックなサイトでも、JSON ファイルが用意できれば問題ありません。

さて、まずは MT でインデックステンプレートを作成します。作成するテンプレートの情報は次のようにします。

テンプレート名
検索用JSON(自由に設定してください)
出力ファイル名
search_data.js(変更しても構いません)
テンプレートの種類
カスタムインデックステンプレート
公開
スタティック(既定)

テンプレートの内容は、次の2パターンを用意しました。

インデックステンプレートの作成(ブログ記事のみの場合)

{"item":[
<mt:entries lastn="0">
<mt:setvarBlock name="item{title}"><mt:entryTitle></mt:setvarBlock>
<mt:setvarBlock name="item{url}"><mt:entryPermalink></mt:setvarBlock>
<mt:setvarBlock name="item{tag}">,<mt:entryTags glue=","><mt:tagName regex_replace="/ | /g","%20"></mt:entryTags>,</mt:setvarBlock>
<mt:setvarBlock name="item{body}"><mt:entryBody remove_html="1" regex_replace="/\n|\t| | /g",""></mt:setvarBlock>
<mt:setvarBlock name="item{more}"><mt:entryMore remove_html="1" regex_replace="/\n|\t| | /g",""></mt:setvarBlock>
<mt:var name="item" to_json="1"><mt:unless __last__>,</mt:unless __last__>
</mt:entries>
]}

インデックステンプレートの作成(ウェブページも含む場合)

{"item":[
<mt:entries lastn="0">
<mt:setvarBlock name="item{title}"><mt:entryTitle></mt:setvarBlock>
<mt:setvarBlock name="item{url}"><mt:entryPermalink></mt:setvarBlock>
<mt:setvarBlock name="item{tag}">,<mt:entryTags glue=","><mt:tagName regex_replace="/ | /g","%20"></mt:entryTags>,</mt:setvarBlock>
<mt:setvarBlock name="item{body}"><mt:entryBody remove_html="1" regex_replace="/\n|\t| | /g",""></mt:setvarBlock>
<mt:setvarBlock name="item{more}"><mt:entryMore remove_html="1" regex_replace="/\n|\t| | /g",""></mt:setvarBlock>
<mt:var name="item" to_json="1">,
</mt:entries>
<mt:pages lastn="0">
<mt:setvarBlock name="item{title}"><mt:pageTitle></mt:setvarBlock>
<mt:setvarBlock name="item{url}"><mt:pagePermalink></mt:setvarBlock>
<mt:setvarBlock name="item{tag}">,<mt:pageTags glue=","><mt:tagName regex_replace="/ | /g","%20"></mt:pageTags>,</mt:setvarBlock>
<mt:setvarBlock name="item{body}"><mt:pageBody remove_html="1" regex_replace="/\n|\t| | /g",""></mt:setvarBlock>
<mt:setvarBlock name="item{more}"><mt:pageMore remove_html="1" regex_replace="/\n|\t| | ",""></mt:setvarBlock>
<mt:var name="item" to_json="1"><mt:unless __last__>,</mt:unless __last__>
</mt:pages>
]}

構文チェック

jQuery 1.4 から、JSON の解釈がより厳密になっているようなので(たぶん)、テンプレートから書き出された JSON の構文が正しいかどうか、一度「JSLint, The JavaScript Code Quality Tool」などでチェックすることをお勧めします。

Strict JSON parsing, using native JSON.parse

jQuery 1.3 and earlier used JavaScript's eval to evaluate incoming JSON. jQuery 1.4 uses the native JSON parser if available. It also validates incoming JSON for validity, so malformed JSON (for instance {foo: "bar"}) will be rejected by jQuery in jQuery.getJSON and when specifying "json" as the dataType of an Ajax request.

jQuery 1.4 Released - Full Release Notes - The 14 Days of jQuery

これを再構築して準備完了です。

jQuery Search Box のダウンロード

※Google Code に移動しました。

ファイルをダウンロードして解凍し、jQuerySearchBox フォルダをサーバーにアップロードします。フォルダ内のそれぞれのファイルのアップロード先はご自由にどうぞ。今は、このブログを前提として、以下のようにアップロードします。

  • ドメインルート/blog
    • js
      • jQuerySearchBox
        • jQuerySearchBox.js
        • loading.gif
        • search_data.js

読み込みと適用

次に、jQuerySearchBox.js を jQuery 本体の後に読み込みます。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/blog/js/jQuerySearchBox/jQuerySearchBox.js"></script>

さて、いよいよプラグインを実行するわけですが、jQuerySearchBox.js では、検索ボックス(input:text)と検索ボタン(input:button)が自動で生成されます(オプションで既存の要素を使うことも可能)。したがって、検索ボックスと検索ボタンを入れるボックスだけ用意して、そのボックス(セレクタ)に対して実行すればOKです。

このブログでは、dd#search_content の中に検索ボックスを表示したいので、その場合は、次のようなコードを読み込んだファイルより後に記述することになります。

$('#search_content').jQuerySearchBox({
 // オプション設定(下記参照)
});

オプション設定

さて、このプラグインを実行するには、いくつかのオプションを設定する必要があります。デフォルトのままで良いものは省略してOKです(以下のそれぞれの値がデフォルト値です)。

searchBoxCreate : true

falseに設定すると、検索ボックスと検索ボタンは生成されません。

searchTextID : "search_text"

searchBoxCreate : false にした場合は、jQuerySearchBox.js で利用する検索ボックス(input:text)の id 属性値を指定します。

searchBtnID : "search_submit"

searchBoxCreate : false にした場合は、jQuerySearchBox.js で利用する検索ボタン(input:button)の id 属性値を指定します。

searchBtn : "Search"

自動で生成される検索ボタンのテキストを指定します。

closeBtn : "Close"

検索結果一覧の一番下に、その一覧を閉じるボタンが表示されます。そのテキストを指定します。

loadingImgPath : "/jQuerySearchBox/loading.gif"

アップロードしたローディング中の画像のパスを表示します。ドメインルートからの絶対パスか、絶対URLで指定してください。

searchDataPath : "/jQuerySearchBox/search_data.js"

MT のインデックステンプレートで書き出した search_data.js のパスを表示します。ドメインルートからの絶対パスか、絶対URLで指定してください。

searchTagsClass : "search_tags"

タグ検索も利用する場合、各ダグの a 要素に付けられている class 名を指定します。タグ検索については後述します。

resultID : "search_result"

検索結果を表示させるボックスの id 属性値を指定します。

resultBox : "<div id='search_result_box'/>"

上記の検索結果を表示させるボックス(#resultID)に入れる、検索結果一覧を表示するボックスを html で指定します。id 属性の指定を忘れないように注意してください。上記の resultID とこの resultBox の関係をみると次のようになります。

<div id="search_result">
 <div id='search_result_box'>この中に一覧を表示</div>
</div>

このように、ここで html を指定するようにしたのは、この部分を自由に入れ子にしたり出来た方が、ブログのデザインやCSSを変更しなくても済むからです。実際に、このブログでは以下のようにしています。

resultBox : '<div id="search_result_wrapper" class="content"><div id="search_result_box" class="contentBody"></div></div>',

なお、このコード中の #search_result_wrapper も後で指定します。

resultBoxID : "search_result_box"

上記の resultBox で指定した html の id 属性値を指定します。

resultWraperID : ""

デフォルトは空ですが、上記の例の、このブログの場合のように、resultBox が入れ子になるときは、一番外側の要素に id を付け、その id 属性値を resultWraperID に指定します。

このブログの場合は、resultWraperID : 'search_result_wrapper' となります。

resultBoxInsert : "prepend" // prepend,append,html

検索結果を表示する方法を指定します。

  • prepend : resultID で指定した要素に、元々ある内容は残したまま、その先頭に挿入します。
  • append : resultID で指定した要素に、元々ある内容は残したまま、その最後に追加します。
  • html : resultID で指定した要素の内容を上書きして表示します。

cookie : false

true を指定すると、ページを移動しても検索キーワードが検索ボックスの中に残ります。約15時間保存されます。

cache : false

true を指定すると、search_data.js をキャッシュします。

limitFields : null

limitFields オプションに連想配列を指定すると、検索対象を限定するためのセレクトボックスが生成されます。詳細は、以下の記事をご覧ください。

絞り込みも可能な高速タグ検索

このタグ検索はちょっとウリかもしれません。個人的にはすごく気に入っています。

デモはこのブログのタグ検索そのものですが(2010-08-18現在)、まず、タグクラウド(このブログの場合はタグリスト)でタグをクリックすると、

searchTags01.png

検索結果に、「今クリックしたタグ(画像ではmovabletype)が付いた記事に付いている他のタグ」が表示されます。

searchTags02.png

この一覧のタグをクリックすると、複数のタグで絞り込むことが出来ます。

タグ検索用にタグクラウドを修正

このタグ検索を利用するには、タグ検索の a 要素に「search_tags」という class を追加するか、もともと付いている class があれば、その class 属性値を searchTagsClass オプションで指定します。

<a class="search_tags" href="<$mt:TagSearchLink$>"><$mt:TagName$></a>

これで設置完了です。

ちょっと覚えておいて

読み込み完了前の処理にも対応しました。

この jQuery Search Box は、非同期で search_data.js を読み込んでいます。そして、読み込みが完了した時点で、検索ボックス等のクリックイベントが付与されます。クリックしてから検索データを読み込むわけではないので、より高速な検索が出来るようになっていると思います。

その反面、万が一、search_data.js の読み込みが完了する前に検索ボタンがクリックされた場合、検索ボタンを生成するパターンの場合(searchBoxCreate : true)は何も起こりませんし、元からある検索ボタンに適用させた場合searchBoxCreate : falseは、元のボタンのときの動作になります。

したがって、JavaScript off の環境でも確実に検索機能を実行させたい場合は、searchBoxCreate : false にして、MT のデフォルトの検索機能に対して searchTextID と searchBtnID の2つのオプションをしていして、処理を上書きした方がいいかも知れません。

以上です。

Published 2010-08-19
Updated 2019-06-25

「プラグイン」カテゴリの記事一覧