E-PARLOR Wiki Live Search
AJAX (or
Asynchronous JavaScript and XML)
JavaScript and
XMLHTTP∞.
入力された文字により、Wiki DBに対して全文検索を実行してリアルタイムに表示します。
※Wikkaの
DarTarさんのページを参考にして組み込んでみました。
※
スクリプトはこちら ∞
E-PARLOR Wiki への実装試験
1. actions/header.php の<head>内に追加
<script type="text/javascript" src="http://e-parlor.org/blog/livesearch.js"></script>
<script type="text/javascript">liveSearchRoot = "http://e-parlor.org/";liveSearchRootSubDir = "/";</script>
2. actions/livesearch.php textsearch.phpを改造して作成
<?php
// echo $this->FormOpen("", "", "get")
?>
<!--
Search
for:
<input name=
"phrase" size=
"35" value=
"<?php echo $this->htmlspecialchars_ent(stripslashes($_REQUEST["phrase
"])) ?>" class=
"searchbox" /> <input type=
"submit" value=
"Search" />
-->
<?php
// echo $this->FormClose();
?>
<h2> LiveSearch this wiki: </h2>
<br /> <form action=
"http://e-parlor.org/LiveSearch" id=
"form_searchform">
<!-- <fieldset
class=
"hidden"><input type=
"hidden" name=
"wakka" value=
"LiveSearch" /></fieldset> -->
Search for: <input id=
"livesearch" onkeypress=
"liveSearchStart()" name=
"q" size=
"35" value=
"" class=
"searchbox" />
<input type=
"submit" value=
"Search" />
<div id=
"LSResult" style=
"display: none;"><div id=
"LSShadow"></div></div>
</form>
<br />
Start typing in the search field to trigger the automatic DB lookup
(javascript must be enabled on your browser
).
<?php
if ($phrase =
$_REQUEST["q"])
{
$phrase =
stripslashes($phrase);
$results =
$this->
FullTextSearch($phrase);
print("<br />");
$total_results =
count($results);
$match_str =
$total_results <>
1 ?
" matches" :
" match";
print("Search results: <strong>".
$total_results.
$match_str.
"</strong> for <strong>".
$this->
htmlspecialchars_ent($phrase).
"</strong><br /><br />\n");
if ($results)
{
foreach ($results as $i =>
$page)
{
print(($i+
1).
". ".
$this->
Link($page["tag"]).
"<br />\n");
}
$phrase =
urlencode($phrase);
print("<br />Not sure which page to choose?<br />Try the <a href=\"".
$this->
href("",
"TextSearchExpanded",
"phrase=$phrase").
"\">Expanded Text Search</a> which shows surrounding text.");
}
}
if ($this->
CheckMySQLVersion(4,
00,
01))
{
$search_tips =
"<br /><br /><hr /><br /><strong>Search Tips:</strong><br /><br />"
.
"<div class=\"indent\">apple banana</div>"
.
"Find pages that contain at least one of the two words. <br />"
.
"<br />"
.
"<div class=\"indent\">+apple +juice</div>"
.
"Find pages that contain both words. <br />"
.
"<br />"
.
"<div class=\"indent\">+apple -macintosh</div>"
.
"Find pages that contain the word 'apple' but not 'macintosh'. <br />"
.
"<br />"
.
"<div class=\"indent\">apple*</div>"
.
"Find pages that contain words such as apple, apples, applesauce, or applet. <br />"
.
"<br />"
.
"<div class=\"indent\">\"some words\"</div>"
.
"Find pages that contain the exact phrase 'some words' (for example, pages that contain 'some words of wisdom' <br />"
.
"but not 'some noise words'). <br />";
print($search_tips);
}
?>
3. blog/livesearch.js
/*
// +----------------------------------------------------------------------+
// | Copyright (c) 2004 Bitflux GmbH |
// +----------------------------------------------------------------------+
// | Licensed under the Apache License, Version 2.0 (the "License"); |
// | you may not use this file except in compliance with the License. |
// | You may obtain a copy of the License at |
// | http://www.apache.org/licenses/LICENSE-2.0 |
// | Unless required by applicable law or agreed to in writing, software |
// | distributed under the License is distributed on an "AS IS" BASIS, |
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
// | implied. See the License for the specific language governing |
// | permissions and limitations under the License. |
// +----------------------------------------------------------------------+
// | Author: Bitflux GmbH <devel@bitflux.ch> |
// +----------------------------------------------------------------------+
*/
var liveSearchReq = false;
var t = null;
var liveSearchLast = "";
var isIE = false;
// on !IE we only have to initialize it once
if (window.XMLHttpRequest) {
liveSearchReq = new XMLHttpRequest();
}
function liveSearchInit() {
if (navigator.userAgent.indexOf("Safari") > 0) {
document.getElementById('livesearch').addEventListener("keydown",liveSearchKeyPress,false);
// document.getElementById('livesearch').addEventListener("blur",liveSearchHide,false);
} else if (navigator.product == "Gecko") {
document.getElementById('livesearch').addEventListener("keypress",liveSearchKeyPress,false);
document.getElementById('livesearch').addEventListener("blur",liveSearchHideDelayed,false);
} else {
document.getElementById('livesearch').attachEvent('onkeydown',liveSearchKeyPress);
// document.getElementById('livesearch').attachEvent("onblur",liveSearchHide,false);
isIE = true;
}
document.getElementById('livesearch').setAttribute("autocomplete","off");
}
function liveSearchHideDelayed() {
window.setTimeout("liveSearchHide()",400);
}
function liveSearchHide() {
document.getElementById("LSResult").style.display = "none";
var highlight = document.getElementById("LSHighlight");
if (highlight) {
highlight.removeAttribute("id");
}
}
function liveSearchKeyPress(event) {
if (event.keyCode == 40 )
//KEY DOWN
{
highlight = document.getElementById("LSHighlight");
if (!highlight) {
highlight = document.getElementById("LSShadow").firstChild.firstChild;
} else {
highlight.removeAttribute("id");
highlight = highlight.nextSibling;
}
if (highlight) {
highlight.setAttribute("id","LSHighlight");
}
if (!isIE) { event.preventDefault(); }
}
//KEY UP
else if (event.keyCode == 38 ) {
highlight = document.getElementById("LSHighlight");
if (!highlight) {
highlight = document.getElementById("LSResult").firstChild.firstChild.lastChild;
}
else {
highlight.removeAttribute("id");
highlight = highlight.previousSibling;
}
if (highlight) {
highlight.setAttribute("id","LSHighlight");
}
if (!isIE) { event.preventDefault(); }
}
//ESC
else if (event.keyCode == 27) {
highlight = document.getElementById("LSHighlight");
if (highlight) {
highlight.removeAttribute("id");
}
document.getElementById("LSResult").style.display = "none";
}
}
function liveSearchStart() {
if (t) {
window.clearTimeout(t);
}
t = window.setTimeout("liveSearchDoSearch()",200);
}
function liveSearchDoSearch() {
if (typeof liveSearchRoot == "undefined") {
liveSearchRoot = "";
}
if (typeof liveSearchRootSubDir == "undefined") {
liveSearchRootSubDir = "";
}
if (typeof liveSearchParams == "undefined") {
liveSearchParams = "";
}
if (liveSearchLast != document.forms.form_searchform.q.value) {
if (liveSearchReq && liveSearchReq.readyState < 4) {
liveSearchReq.abort();
}
if ( document.forms.form_searchform.q.value == "") {
liveSearchHide();
return false;
}
if (window.XMLHttpRequest) {
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
liveSearchReq = new ActiveXObject("Microsoft.XMLHTTP");
}
liveSearchReq.onreadystatechange= liveSearchProcessReqChange;
//liveSearchReq.open("GET", liveSearchRoot + "/feedlivesearch.php?q=" + document.forms.searchform.q.value + liveSearchParams);
liveSearchReq.open("GET", liveSearchRoot + "LiveSearch/livesearch.xml&q=" + document.forms.form_searchform.q.value + liveSearchParams);
//liveSearchReq.open("GET", liveSearchRoot + "blog/livesearch.xml");
liveSearchLast = document.forms.form_searchform.q.value;
liveSearchReq.send(null);
}
}
function liveSearchProcessReqChange() {
if (liveSearchReq.readyState == 4) {
var res = document.getElementById("LSResult");
res.style.display = "block";
var sh = document.getElementById("LSShadow");
sh.innerHTML = liveSearchReq.responseText;
}
}
function liveSearchSubmit() {
var highlight = document.getElementById("LSHighlight");
if (highlight && highlight.firstChild) {
window.location = liveSearchRoot + liveSearchRootSubDir + highlight.firstChild.nextSibling.getAttribute("href");
return false;
}
else {
return true;
}
}
4. handlers/page/livesearch.xml.php
<?php
header("Content-type: text/xml");
if ($phrase =
$_REQUEST["q"])
{
$phrase =
stripslashes($phrase);
$results =
$this->
FullTextSearch($phrase);
$xml =
"<div class=\"LSRes\">\n";
// 1
if ($results)
{
foreach ($results as $i =>
$page)
{
// print(($i+1).". ".$this->Link($page["tag"])."<br />\n");
$xml .=
" <div class=\"LSRow\">\n";
$xml .=
" ".
$this->
Link($page["tag"]).
"\n";
$xml .=
" </div>\n";
}
$xml .=
"</div>\n";
}
}
print($xml);
?>
Live Search
External links
CategoryDevelopment
There are no comments on this page. [Add comment]