JavaScript で入力補完を行う suggest.js を Ajax 対応する
Webアプリケーションで、途中まで入力したら候補を
リストで表示する処理を実装したかったのですが、
いかんせん、JavaScriptの知識はほとんどゼロ。
いろいろ探し回ってみると、suggest.jsという
ライブラリを見つけました。
残念ながら、suggest.jsは変換候補を事前にJavaScriptに仕込んでおく
必要があるようで、今回はデータベースに登録されている候補から
選択させたかったので、若干要件にあいません。
さらに調べてみると、suggest_ajax.jsというsuggest.jsを
ajax対応する拡張スクリプトを見つけました。
早速使用してみたのですが・・・suggest.jsがバージョンアップの際、
オブジェクト名を変更されたようで動きません。
覚悟を決めて、自分でajax対応することにしました。
suggest.jsに変更を加えないように書いたスクリプトがコチラ。
■search.js
blogへの登録時、エラーになるので、open、evalの始めの文字は全角にしてます。
function createXmlHttpRequest() {
var xmlhttp = false;
if( window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if(window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlhttp;
}
var xmlhttp = 0;
var sg = null;
function initSuggest(suggest_obj) {
sg = suggest_obj;
//区切り文字を変更
sg.delim = '、';
//検索ロジックを上書きして、何もしないように変更
sg._search = function (text) { return 0; };
//検索時のフック関数を指定
sg.hookBeforeSearch = getList;
}
//HTTP通信
function stateChange() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var rst = xmlhttp.responseText;
//受け取ったデータを配列に変換し、格納
sg.candidateList = eval(rst);
//データ件数取得
var list_count = sg.candidateList.length;
//候補リストインデックスを一旦削除
sg.suggestIndexList = [];
//検索結果が取得できている場合
if (list_count != 0) {
//インデックスを作成する
for (i = 0; i < list_count; i++){
sg.suggestIndexList.push(i);
}
//リストの表示
sg.createSuggestArea(sg.candidateList);
}
}
}
function getList (text) {
if (sg == null){
return [];
}
sg.candidateList = [];
if (! xmlhttp) xmlhttp = createXmlHttpRequest();
if (! xmlhttp || xmlhttp.readyState == 1 ||
xmlhttp.readyState == 2 || xmlhttp.readyState == 3){
return [];
}
var query = encodeURI(text);
//webサーバへ問い合わせ
xmlhttp.open("GET", "search.php?" + query, true);
xmlhttp.onreadystatechange = stateChange;
xmlhttp.send(null);
}
サンプルのhtml
■index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>候補出力サンプル</title>
<style type="text/css">
<!--
#suggest {
position: absolute;
background-color: #FFFFFF;
border: 1px solid #CCCCFF;
width: 252px;
}
#suggest div {
padding: 1px;
display: block;
width: 250px;
overflow: hidden;
white-space: nowrap;
}
#suggest div.select{
color: #FFFFFF;
background-color: #3366FF;
}
#suggest div.over{
background-color: #99CCFF;
}
-->
</style>
<script type="text/javascript" src="suggest.js"></script>
<script type="text/javascript" src="search.js"></script>
<script type="text/javascript" language="javascript">
<!--
// wondowのonloadイベントでSuggestを生成
function start(){
sg = new Suggest.LocalMulti("text", "suggest", [], {dispAllKey: true});
initSuggest(sg);
};
window.addEventListener ?
window.addEventListener('load', start, false) :
window.attachEvent('onload', start);
//-->
</script>
</head>
<body>
<h1>名称候補 サンプル</h1>
<p>IMEモードをOFFにして入力してください。</p>
<input id="text" type="text" name="pattern" value="" autocomplete="off" size="40" style="display: block"/>
<!-- 補完候補を表示するエリア -->
<div id="suggest"></div>
</body>
</html>
検索を実行するphpはこんな感じ
■search.php
<?php
//これで、画面上で入力されている文字が取れる
$keyword = urldecode($_SERVER['QUERY_STRING']);
header("Content-type: text/plain charset=\"UTF-8\"");
if ($keyword == 'a') {
echo urldecode("['名前の','リストを','作成','します']");
} else {
echo urldecode("['本当は','データベースを','検索して','結果を','作成します']");
}
?>
これで、テキストボックスに"a"と入力したときと、それ以外の文字を
入力したときでリストの内容が変更されます。
動作はこんな感じ



※JavaScript初心者なので、致命的な障害があるかもです。
【参考URL】
suggest.js - 入力補完ライブラリ
http://www.enjoyxstudy.com/javascript/suggest/
suggest_ajax.js - suggest.jsをAjaxなどに対応する等の拡張スクリプト公開
http://blog.yappo.jp/yappo/archives/000376.html
作って理解するAjax
http://itpro.nikkeibp.co.jp/article/COLUMN/20060110/227005/?ST=nettech
もどる