E-PARLOR : DevLiveSearch

HomePage :: Blog :: Gallery :: Library :: Forum :: Categories :: Index :: Changes :: Comments :: Login

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:&nbsp;
        <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:&nbsp;<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]

1999-2006 The E-PARLOR Project. All right reserved. :: Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.1
Page was generated in 0.2534 seconds