diff options
-rw-r--r-- | ajax.php | 47 | ||||
-rw-r--r-- | inc/search.php | 32 | ||||
-rw-r--r-- | inc/template.php | 20 | ||||
-rw-r--r-- | tpl/default/design.css | 11 | ||||
-rw-r--r-- | tw-sack.js | 91 |
5 files changed, 200 insertions, 1 deletions
diff --git a/ajax.php b/ajax.php new file mode 100644 index 000000000..7af88d835 --- /dev/null +++ b/ajax.php @@ -0,0 +1,47 @@ +<?php +/** + * DokuWiki AJAX call handler + * + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Andreas Gohr <andi@splitbrain.org> + */ + +if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/'); +require_once(DOKU_INC.'inc/init.php'); +require_once(DOKU_INC.'inc/common.php'); +require_once(DOKU_INC.'inc/pageutils.php'); +require_once(DOKU_INC.'lang/en/lang.php'); +require_once(DOKU_INC.'lang/'.$conf['lang'].'/lang.php'); +require_once(DOKU_INC.'inc/auth.php'); + + +//call the requested function +$call = 'ajax_'.$_REQUEST['call']; +if(function_exists($call)){ + $call(); +}else{ + print "The called function does not exist!"; +} + +/** + * Searches for matching pagenames + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function ajax_qsearch(){ + global $conf; + + $query = cleanID($_REQUEST['q']); + if(empty($query)) return; + + $nsdir = str_replace(':','/',getNS($query)); + require_once(DOKU_INC.'inc/search.php'); + require_once(DOKU_INC.'inc/html.php'); + + $data = array(); + search($data,$conf['datadir'],'search_qsearch',array(query => $query),$nsdir); + + print html_buildlist($data,'qsearch','html_list_index'); +} + +?> diff --git a/inc/search.php b/inc/search.php index 0b2e26c67..b368f6756 100644 --- a/inc/search.php +++ b/inc/search.php @@ -71,6 +71,38 @@ function search(&$data,$base,$func,$opts,$dir='',$lvl=1){ */ /** + * Searches for pages beginning with the given query + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function search_qsearch(&$data,$base,$file,$type,$lvl,$opts){ + $item = array(); + + if($type == 'd'){ + return false; //no handling yet + } + + //get id + $id = pathID($file); + + //check if it matches the query + if(!preg_match('/^'.preg_quote($opts['query'],'/').'/u',$id)){ + return false; + } + + //check ACL + if(auth_quickaclcheck($id) < AUTH_READ){ + return false; + } + + $data[]=array( 'id' => $id, + 'type' => $type, + 'level' => 1, + 'open' => true); + return true; +} + +/** * Build the browsable index of pages * * $opts['ns'] is the current namespace diff --git a/inc/template.php b/inc/template.php index 4c782ace9..0720a12f6 100644 --- a/inc/template.php +++ b/inc/template.php @@ -332,9 +332,27 @@ function tpl_actionlink($type,$pre='',$suf=''){ function tpl_searchform(){ global $lang; print '<form action="'.wl().'" accept-charset="utf-8" class="search" onsubmit="return svchk()">'; + +//FIXME this should be moved somewhere else +?> +<script type="text/javascript" src="<?=DOKU_BASE?>tw-sack.js"></script> +<script type="text/javascript"> + ajax = new sack('<?=DOKU_BASE?>ajax.php'); + ajax.AjaxFailedAlert = ''; + + function ajax_qsearch(value){ + ajax.element = 'ajax_qsearch'; + ajax.encodeURIString = false; + var call = 'call=qsearch&q='; + call += encodeURI(value); + ajax.runAJAX(call); + } +</script> +<?php print '<input type="hidden" name="do" value="search" />'; - print '<input type="text" accesskey="f" name="id" class="edit" />'; + print '<input type="text" accesskey="f" name="id" class="edit" onkeyup="ajax_qsearch(this.value)" />'; print '<input type="submit" value="'.$lang['btn_search'].'" class="button" />'; + print '<div id="ajax_qsearch" class="ajax_qsearch"></div>'; print '</form>'; } diff --git a/tpl/default/design.css b/tpl/default/design.css index 685b7eeb4..73914d3f9 100644 --- a/tpl/default/design.css +++ b/tpl/default/design.css @@ -591,3 +591,14 @@ div.acladmin table{ margin-left: 10%; width: 80%; } + +/* ---------- AJAX quicksearch ----------- */ + +div.ajax_qsearch { + position:absolute; + text-align:left; + width: 200px; + background-color: #ff9; + opacity: 0.9; + -moz-border-radius: 15px; +} diff --git a/tw-sack.js b/tw-sack.js new file mode 100644 index 000000000..42e9322ed --- /dev/null +++ b/tw-sack.js @@ -0,0 +1,91 @@ +// ====== Simple Ajax Code Kit ======= +// code by Gregory Wild-Smith (c)2005 +// http://twilightuniverse.com +// If you use this code please keep this credit intact. +// A link or email would be nice, but is not required. +// v1.01 + +function sack(file){ + this.AjaxFailedAlert = "Your browser doesn't support the extended functionality of this website, and therefore you have have an experience that differs from the intended one.\n"; + this.requestFile = file; + this.method = "POST"; + this.URLString = ""; + this.encodeURIString = true; + this.execute = false; + + this.onLoading = function() { }; + this.onLoaded = function() { }; + this.onInteractive = function() { }; + this.onCompletion = function() { }; + + this.createAJAX = function() { + try { + this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (oc) { + this.xmlhttp = null; + } + } + if(!this.xmlhttp && typeof XMLHttpRequest != "undefined") + this.xmlhttp = new XMLHttpRequest(); + if (!this.xmlhttp){ + // no XMLHttpRequest support, so no AJAX. + this.failed = true; + } + }; + + this.encodeURLString = function(string){ + varArray = string.split('&'); + for (i = 0; i < varArray.length; i++){ + urlVars = varArray[i].split('='); + if (urlVars[0].indexOf('amp;') != -1){ + urlVars[0] = urlVars[0].substring(4); + } + urlVars[0] = encodeURIComponent(urlVars[0]); + urlVars[1] = encodeURIComponent(urlVars[1]); + varArray[i] = urlVars.join("="); + } + return varArray.join('&'); + } + + this.runResponse = function(){ + eval(this.response); + } + + this.runAJAX = function(urlstring){ + if (urlstring){ this.URLString = urlstring; } + if (this.element) { this.elementObj = document.getElementById(this.element); } + if (this.xmlhttp) { + var self = this; // wierd fix for odd behavior where "this" wouldn't work in the readystate function. + this.xmlhttp.open(this.method, this.requestFile ,true); + if (this.method == "POST") { this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') } + if (this.encodeURIString){ this.URLString = this.encodeURLString(this.URLString); } + this.xmlhttp.send(this.URLString); + this.xmlhttp.onreadystatechange = function() { + switch (self.xmlhttp.readyState){ + case 1: // Loading. + self.onLoading(); + break; + case 2: // Loaded. + self.onLoaded(); + break; + case 3: // Interactive - is called every 4096 bytes.. pretty much just tells you it's downloading data. + self.onInteractive(); + break; + case 4: // Completed. + self.response = self.xmlhttp.responseText + self.onCompletion(); + if(self.execute){ self.runResponse(); } + if (self.elementObj) { + self.elementObj.innerHTML = self.response; + } + break; + } + }; + } + }; +this.createAJAX(); +if(this.failed && this.AjaxFailedAlert){ alert(this.AjaxFailedAlert); } +} |