<?php /////////////////////////////////////////////////////////////////////////////// // xajax version 0.1 beta4 // copyright (c) 2005 by J. Max Wilson // http://xajax.sourceforge.net // // // xajax is an open source PHP class library for easily creating powerful // PHP-driven, web-based AJAX Applications. Using xajax, you can asynchronously // call PHP functions and update the content of your your webpage without // reloading the page. // // xajax is released under the terms of the LGPL license // http://www.gnu.org/copyleft/lesser.html#SEC3 // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /////////////////////////////////////////////////////////////////////////////// // The xajaxResponse class is used to created responses to be sent back to your // webpage. A response contains one or more command messages for updating your page. // Currently xajax supports five kinds of command messages: // * Assign - sets the specified attribute of an element in your page // * Append - appends data to the end of the specified attribute of an element in your page // * Prepend - prepends data to teh beginning of the specified attribute of an element in your page // * Replace - searches for and replaces data in the specified attribute of an element in your page // * Script - runs JavaScript // * Alert - shows an alert box with the suplied message text // elements are identified by their HTML id class xajaxResponse { var $xml; // Constructor function xajaxResponse() { $this->charset = is_object($GLOBALS['egw']->translation) ? $GLOBALS['egw']->translation->charset() : 'UTF-8'; //error_log("xajaxResponse: charset=$this->charset"); $this->xml = "<?xml version=\"1.0\" encoding=\"$this->charset\"?>"; $this->xml .= "<xajax>"; } // addAssign() adds an assign command message to your xml response // $sTarget is a string containing the id of an HTML element // $sAttribute is the part of the element you wish to modify ("innerHTML", "value", etc.) // $sData is the data you want to set the attribute to // usage: $objResponse->addAssign("contentDiv","innerHTML","Some Text"); function addAssign($sTarget,$sAttribute,$sData) { $this->xml .= "<update action=\"assign\">"; $this->xml .= "<target attribute=\"$sAttribute\">$sTarget</target>"; $this->xml .= "<data><![CDATA[$sData]]></data>"; $this->xml .= "</update>"; } // addAppend() adds an append command message to your xml response // $sTarget is a string containing the id of an HTML element // $sAttribute is the part of the element you wish to modify ("innerHTML", "value", etc.) // $sData is the data you want to append to the end of the attribute // usage: $objResponse->addAppend("contentDiv","innerHTML","Some Text"); function addAppend($sTarget,$sAttribute,$sData) { $this->xml .= "<update action=\"append\">"; $this->xml .= "<target attribute=\"$sAttribute\">$sTarget</target>"; $this->xml .= "<data><![CDATA[$sData]]></data>"; $this->xml .= "</update>"; } // addPrepend() adds an prepend command message to your xml response // $sTarget is a string containing the id of an HTML element // $sAttribute is the part of the element you wish to modify ("innerHTML", "value", etc.) // $sData is the data you want to prepend to the beginning of the attribute // usage: $objResponse->addPrepend("contentDiv","innerHTML","Some Text"); function addPrepend($sTarget,$sAttribute,$sData) { $this->xml .= "<update action=\"prepend\">"; $this->xml .= "<target attribute=\"$sAttribute\">$sTarget</target>"; $this->xml .= "<data><![CDATA[$sData]]></data>"; $this->xml .= "</update>"; } // addReplace() adds an replace command message to your xml response // $sTarget is a string containing the id of an HTML element // $sAttribute is the part of the element you wish to modify ("innerHTML", "value", etc.) // $sSearch is a string to search for // $sData is a string to replace the search string when found in the attribute // usage: $objResponse->addReplace("contentDiv","innerHTML","text","<b>text</b>"); function addReplace($sTarget,$sAttribute,$sSearch,$sData) { $this->xml .= "<update action=\"replace\">"; $this->xml .= "<target attribute=\"$sAttribute\">$sTarget</target>"; $this->xml .= "<search><![CDATA[$sSearch]]></search>"; $this->xml .= "<data><![CDATA[$sData]]></data>"; $this->xml .= "</update>"; } // addClear() adds an clear command message to your xml response // $sTarget is a string containing the id of an HTML element // $sAttribute is the part of the element you wish to clear ("innerHTML", "value", etc.) // usage: $objResponse->addClear("contentDiv","innerHTML"); function addClear($sTarget,$sAttribute) { $this->xml .= "<update action=\"clear\">"; $this->xml .= "<target attribute=\"$sAttribute\">$sTarget</target>"; $this->xml .= "</update>"; } // addAlert() adds an alert command message to your xml response // $sMsg is a text to be displayed in the alert box // usage: $objResponse->addAlert("This is some text"); function addAlert($sMsg) { $this->xml .= "<alert><![CDATA[$sMsg]]></alert>"; } // addScript() adds a jscript command message to your xml response // $sJS is a string containing javascript code to be executed // usage: $objResponse->addAlert("var x = prompt('get some text');"); function addScript($sJS) { $this->xml .= "<jscript><![CDATA[$sJS]]></jscript>"; } // addRemove() adds a Remove Element command message to your xml response // $sTarget is a string containing the id of an HTML element to be removed // from your page // usage: $objResponse->addRemove("Div2"); function addRemove($sTarget) { $this->xml .= "<update action=\"remove\">"; $this->xml .= "<target>$sTarget</target>"; $this->xml .= "</update>"; } function addCreate($sParent, $sTag, $sId, $sType="") { $this->xml .= "<update action=\"create\">"; $this->xml .= "<target attribute=\"$sTag\">$sParent</target>"; $this->xml .= "<data><![CDATA[$sId]]></data>"; if ($sType != "") $this->xml .= "<type><![CDATA[$sType]]></type>"; $this->xml .= "</update>"; } // getXML() returns the xml to be returned from your function to the xajax // processor on your page // usage: $objResponse->getXML(); function getXML() { if (strstr($this->xml,"</xajax>") == false) $this->xml .= "</xajax>"; return $this->xml; } }// end class xajaxResponse // Communication Method Defines if (!defined ('GET')) { define ('GET', 0); } if (!defined ('POST')) { define ('POST', 1); } // the xajax class generates the xajax javascript for your page including the // javascript wrappers for the PHP functions that you want to call from your page. // It also handles processing and executing the command messages in the xml responses // sent back to your page from your PHP functions. class xajax { var $aFunctions; // Array of PHP functions that will be callable through javascript wrappers var $aFunctionRequestTypes; // Array of RequestTypes to be used with each function (key=function name) var $sRequestURI; // The URI for making requests to the xajax object var $bDebug; // Show debug messages true/false var $sWrapperPrefix; // The prefix to prepend to the javascript wraper function name var $bStatusMessages; // Show debug messages true/false var $aObjArray; // Array for parsing complex objects var $iPos; // Position in $aObjArray // Contructor // $sRequestURI - defaults to the current page // $bDebug Mode - defaults to false // $sWrapperPrefix - defaults to "xajax_"; // usage: $xajax = new xajax(); function xajax($sRequestURI="",$sWrapperPrefix="xajax_",$bDebug=false) { $this->aFunctions = array(); $this->sRequestURI = $sRequestURI; if ($this->sRequestURI == "") $this->sRequestURI = $this->detectURI(); $this->sWrapperPrefix = $sWrapperPrefix; $this->bDebug = $bDebug; } // detectURL() returns the current URL based upon the SERVER vars // used internally function detectURI() { $aUri = array(); if (!empty($_SERVER['REQUEST_URI'])) { $aUri = parse_url($_SERVER['REQUEST_URI']); } if (empty($aUri['scheme'])) { if (!empty($_SERVER['HTTP_SCHEME'])) { $aUri['scheme'] = $_SERVER['HTTP_SCHEME']; } else { $aUri['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http'; } if (!empty($_SERVER['HTTP_HOST'])) { if (strpos($_SERVER['HTTP_HOST'], ':') > 0) { list($aUri['host'], $aUri['port']) = explode(':', $_SERVER['HTTP_HOST']); } else { $aUri['host'] = $_SERVER['HTTP_HOST']; } } else if (!empty($_SERVER['SERVER_NAME'])) { $aUri['host'] = $_SERVER['SERVER_NAME']; } else { print "xajax Error: xajax failed to automatically identify your Request URI."; print "Please set the Request URI explicitly when you instantiate the xajax object."; exit(); } if (empty($aUri['port']) && !empty($_SERVER['SERVER_PORT'])) { $aUri['port'] = $_SERVER['SERVER_PORT']; } if (empty($aUri['path'])) { if (!empty($_SERVER['PATH_INFO'])) { $path = parse_url($_SERVER['PATH_INFO']); } else { $path = parse_url($_SERVER['PHP_SELF']); } $aUri['path'] = $path['path']; unset($path); } } $sUri = $aUri['scheme'] . '://'; if (!empty($aUri['user'])) { $sUri .= $aUri['user']; if (!empty($aUri['pass'])) { $sUri .= ':' . $aUri['pass']; } $sUri .= '@'; } $sUri .= $aUri['host']; if (!empty($aUri['port']) && (($aUri['scheme'] == 'http' && $aUri['port'] != 80) || ($aUri['scheme'] == 'https' && $aUri['port'] != 443))) { $sUri .= ':'.$aUri['port']; } // And finally path, without script name $sUri .= substr($aUri['path'], 0, strrpos($aUri['path'], '/') + 1); unset($aUri); return $sUri.basename($_SERVER['SCRIPT_NAME']); } // setRequestURI() sets the URI to which requests will be made // usage: $xajax->setRequestURI("http://xajax.sourceforge.net"); function setRequestURI($sRequestURI) { $this->sRequestURI = $sRequestURI; } // debugOn() enables debug messages for xajax // usage: $xajax->debugOn(); function debugOn() { $this->bDebug = true; } // debugOff() disables debug messages for xajax // usage: $xajax->debugOff(); function debugOff() { $this->bDebug = false; } // statusMessagesOn() enables messages in the statusbar for xajax // usage: $xajax->statusMessagesOn(); function statusMessagesOn() { $this->bStatusMessages = true; } // statusMessagesOff() disables messages in the statusbar for xajax // usage: $xajax->statusMessagesOff(); function statusMessagesOff() { $this->bStatusMessages = false; } // setWrapperPrefix() sets the prefix that will be appended to the javascript // wraper functions. function setWrapperPrefix($sPrefix) { $this->sWrapperPrefix = $sPrefix; } //Dpericated. Use registerFunction(); function addFunction($sFunction,$sRequestType=POST) { trigger_error("xajax: the <b>addFunction()</b> method has been renamed <b>registerFunction()</b>. <br />Please use ->registerFunction('$sFunction'".($sRequestType==GET?",GET":"")."); instead.",E_USER_WARNING); $this->registerFunction($sFunction,$sRequestType); } // registerFunction() registers a PHP function to be callable through xajax // $sFunction is a string containing the function name // $sRequestType is the RequestType (GET/POST) that should be used // for this function. Defaults to POST. // usage: $xajax->registerFunction("myfunction",POST); function registerFunction($sFunction,$sRequestType=POST) { $this->aFunctions[] = $sFunction; $this->aFunctionRequestTypes[$sFunction] = $sRequestType; } // generates the javascript wrapper for the specified PHP function // used internally function wrap($sFunction,$sRequestType=POST) { $js = "function ".$this->sWrapperPrefix."$sFunction(){xajax.call(\"$sFunction\", arguments, ".$sRequestType.");}\n"; return $js; } // processRequests() is the main communications engine of xajax // The engine handles all incoming xajax requests, calls the apporiate PHP functions // and passes the xml responses back to the javascript response handler // if your RequestURI is the same as your web page then this function should // be called before any headers or html has been sent. // usage: $xajax->processRequests() function processRequests() { if (!empty($_GET['xajaxjs'])) { header("Content-type: text/javascript"); print $this->generateJavascript(); exit(); return; } $requestMode = -1; $sFunctionName = ""; $aArgs = array(); $sResponse = ""; if (!empty($_GET["xajax"])) $requestMode = GET; if (!empty($_POST["xajax"])) $requestMode = POST; if ($requestMode == -1) return; if ($requestMode == POST) { $sFunctionName = $_POST["xajax"]; if (!empty($_POST["xajaxargs"])) $aArgs = $_POST["xajaxargs"]; } else { header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header ("Cache-Control: no-cache, must-revalidate"); header ("Pragma: no-cache"); header("Content-type: text/xml"); $sFunctionName = $_GET["xajax"]; if (!empty($_GET["xajaxargs"])) $aArgs = $_GET["xajaxargs"]; } if (!in_array($sFunctionName, $this->aFunctions)) { $objResponse = new xajaxResponse(); $objResponse->addAlert("Unknown Function $sFunctionName."); $sResponse = $objResponse->getXML(); } else if ($this->aFunctionRequestTypes[$sFunctionName] != $requestMode) { $objResponse = new xajaxResponse(); $objResponse->addAlert("Incorrect Request Type."); $sResponse = $objResponse->getXML(); } else { for ($i = 0; $i < sizeof($aArgs); $i++) { if (stristr($aArgs[$i],"<xjxobj>") != false) { $aArgs[$i] = $this->xmlToArray("xjxobj",$aArgs[$i]); } else if (stristr($aArgs[$i],"<xjxquery>") != false) { $aArgs[$i] = $this->xmlToArray("xjxquery",$aArgs[$i]); } } $sResponse = call_user_func_array($sFunctionName, $aArgs); } header("Content-type: text/xml; charset=$this->charset"); print $sResponse; exit(); } // xmlToArray() takes a string containing xajax xjxobj xml or xjxquery xml // and builds an array representation of it to pass as an argument to // the php function being called. Returns an array. // used internally function xmlToArray($rootTag, $sXml) { $aArray = array(); $sXml = str_replace("<$rootTag>","<$rootTag>|~|",$sXml); $sXml = str_replace("</$rootTag>","</$rootTag>|~|",$sXml); $sXml = str_replace("<e>","<e>|~|",$sXml); $sXml = str_replace("</e>","</e>|~|",$sXml); $sXml = str_replace("<k>","<k>|~|",$sXml); $sXml = str_replace("</k>","|~|</k>|~|",$sXml); $sXml = str_replace("<v>","<v>|~|",$sXml); $sXml = str_replace("</v>","|~|</v>|~|",$sXml); $sXml = str_replace("<q>","<q>|~|",$sXml); $sXml = str_replace("</q>","|~|</q>|~|",$sXml); $this->aObjArray = explode("|~|",$sXml); $this->iPos = 0; $aArray = $this->parseObjXml($rootTag); return $aArray; } // parseObjXml() is a recursive function that generates an array from the // contents of $this->aObjArray. Returns an array. // used internally function parseObjXml($rootTag) { $aArray = array(); if ($rootTag == "xjxobj") { while(!stristr($this->aObjArray[$this->iPos],"</xjxobj>")) { $this->iPos++; if(stristr($this->aObjArray[$this->iPos],"<e>")) { $key = ""; $value = null; $this->iPos++; while(!stristr($this->aObjArray[$this->iPos],"</e>")) { if(stristr($this->aObjArray[$this->iPos],"<k>")) { $this->iPos++; while(!stristr($this->aObjArray[$this->iPos],"</k>")) { $key .= $this->aObjArray[$this->iPos]; $this->iPos++; } } if(stristr($this->aObjArray[$this->iPos],"<v>")) { $this->iPos++; while(!stristr($this->aObjArray[$this->iPos],"</v>")) { if(stristr($this->aObjArray[$this->iPos],"<xjxobj>")) { $value = $this->parseObjXml("xjxobj"); $this->iPos++; } else { $value .= $this->aObjArray[$this->iPos]; } $this->iPos++; } } $this->iPos++; } $aArray[$key]=$value; } } } if ($rootTag == "xjxquery") { $sQuery = ""; $this->iPos++; while(!stristr($this->aObjArray[$this->iPos],"</xjxquery>")) { if (stristr($this->aObjArray[$this->iPos],"<q>") || stristr($this->aObjArray[$this->iPos],"</q>")) { $this->iPos++; continue; } $sQuery .= $this->aObjArray[$this->iPos]; $this->iPos++; } parse_str($sQuery, $aArray); } return $aArray; } // Depricated. Use printJavascript(); function javascript($sJsURI="") { trigger_error("xajax: the <b>javascript()</b> method has been renamed <b>printJavascript()</b>. <br />Please use ->printJavascript(".($sJsURI==""?"":"'$sJsURI'")."); instead.",E_USER_WARNING); $this->printJavascript($sJsURI); } // printJavascript() prints the xajax javascript code into your page // it should only be called between the <head> </head> tags // usage: // <head> // ... // <?php $xajax->printJavascript(); function printJavascript($sJsURI="") { print $this->getJavascript($sJsURI); } // getJavascript() returns the xajax javascript code that should be added to // your page between the <head> </head> tags // usage: // <head> // ... // <?php $xajax->getJavascript(); function getJavascript($sJsURI="") { if ($sJsURI == "") $sJsURI = $this->sRequestURI; $separator=strpos($sJsURI,'?')==false?'?':'&'; $html = "<script type=\"text/javascript\">var xajaxRequestUri=\"".$this->sRequestURI."\";</script>\n"; $html .= "\t<script type=\"text/javascript\" src=\"".$sJsURI.$separator."xajaxjs=xajaxjs\"></script>\n"; return $html; } // compressJavascript() compresses the javascript code for more efficient delivery // used internally // $sJS is a string containing the javascript code to compress function compressJavascript($sJS) { //remove windows cariage returns $sJS = str_replace("\r","",$sJS); //array to store replaced literal strings $literal_strings = array(); //explode the string into lines $lines = explode("\n",$sJS); //loop through all the lines, building a new string at the same time as removing literal strings $clean = ""; $inComment = false; $literal = ""; $inQuote = false; $escaped = false; $quoteChar = ""; for($i=0;$i<count($lines);$i++) { $line = $lines[$i]; $inNormalComment = false; //loop through line's characters and take out any literal strings, replace them with ___i___ where i is the index of this string for($j=0;$j<strlen($line);$j++) { $c = substr($line,$j,1); $d = substr($line,$j,2); //look for start of quote if(!$inQuote && !$inComment) { //is this character a quote or a comment if(($c=="\"" || $c=="'") && !$inComment && !$inNormalComment) { $inQuote = true; $inComment = false; $escaped = false; $quoteChar = $c; $literal = $c; } else if($d=="/*" && !$inNormalComment) { $inQuote = false; $inComment = true; $escaped = false; $quoteChar = $d; $literal = $d; $j++; } else if($d=="//") //ignore string markers that are found inside comments { $inNormalComment = true; $clean .= $c; } else { $clean .= $c; } } else //allready in a string so find end quote { if($c == $quoteChar && !$escaped && !$inComment) { $inQuote = false; $literal .= $c; //subsitute in a marker for the string $clean .= "___" . count($literal_strings) . "___"; //push the string onto our array array_push($literal_strings,$literal); } else if($inComment && $d=="*/") { $inComment = false; $literal .= $d; //subsitute in a marker for the string $clean .= "___" . count($literal_strings) . "___"; //push the string onto our array array_push($literal_strings,$literal); $j++; } else if($c == "\\" && !$escaped) $escaped = true; else $escaped = false; $literal .= $c; } } if($inComment) $literal .= "\n"; $clean .= "\n"; } //explode the clean string into lines again $lines = explode("\n",$clean); //now process each line at a time for($i=0;$i<count($lines);$i++) { $line = $lines[$i]; //remove comments $line = preg_replace("/\/\/(.*)/","",$line); //strip leading and trailing whitespace $line = trim($line); //remove all whitespace with a single space $line = preg_replace("/\s+/"," ",$line); //remove any whitespace that occurs after/before an operator $line = preg_replace("/\s*([!\}\{;,&=\|\-\+\*\/\)\(:])\s*/","\\1",$line); $lines[$i] = $line; } //implode the lines $sJS = implode("\n",$lines); //make sure there is a max of 1 \n after each line $sJS = preg_replace("/[\n]+/","\n",$sJS); //strip out line breaks that immediately follow a semi-colon $sJS = preg_replace("/;\n/",";",$sJS); //curly brackets aren't on their own $sJS = preg_replace("/[\n]*\{[\n]*/","{",$sJS); //finally loop through and replace all the literal strings: for($i=0;$i<count($literal_strings);$i++) $sJS = str_replace("___".$i."___",$literal_strings[$i],$sJS); return $sJS; } // generateJavascript() generates all of the xajax javascript code including the javascript // wrappers for the PHP functions specified by the registerFunction() method and the response // xml parser // used internally function generateJavascript() { $js = ""; if ($this->bDebug){ $js .= "var xajaxDebug=".($this->bDebug?"true":"false").";\n"; } ob_start(); ?> function Xajax() { <?php if ($this->bDebug){ ?>this.DebugMessage = function(text){if (xajaxDebug) alert("Xajax Debug:\n " + text)}<?php } ?> this.workId = 'xajaxWork'+ new Date().getTime(); this.depth = 0; //Get the XMLHttpRequest Object this.getRequestObject = function() { <?php if ($this->bDebug){ ?>this.DebugMessage("Initializing Request Object..");<?php } ?> var req; try { req=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { req=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { req=null; } } if(!req && typeof XMLHttpRequest != "undefined") req = new XMLHttpRequest(); <?php if ($this->bDebug){ ?>if (!req) this.DebugMessage("Request Object Instantiation failed.");<?php } ?> return req; } // xajax.$() is shorthand for document.getElementById() this.$ = function(sId) { return document.getElementById(sId); } // xajax.getFormValues() builds a query string XML message from the elements of a form object this.getFormValues = function(frm) { var objForm; if (typeof(frm) == "string") objForm = this.$(frm); else objForm = frm; var sXml = "<xjxquery><q>"; if (objForm && objForm.tagName == 'FORM') { var formElements = objForm.elements; for( var i=0; i < formElements.length; i++) { if ((formElements[i].type == 'radio' || formElements[i].type == 'checkbox') && formElements[i].checked == false) continue; var name = formElements[i].name; if (name) { if (sXml != '<xjxquery><q>') sXml += '&'; sXml += name+"="+encodeURIComponent(formElements[i].value); } } } sXml +="</q></xjxquery>"; return sXml; } // Generates an XML message that xajax can understand from a javascript object this.objectToXML = function(obj) { var sXml = "<xjxobj>"; for (i in obj) { try { if (i == 'constructor') continue; if (obj[i] && typeof(obj[i]) == 'function') continue; var key = i; var value = obj[i]; if (value && typeof(value)=="object" && (value.constructor == Array ) && this.depth <= 50) { this.depth++; value = this.objectToXML(value); this.depth--; } sXml += "<e><k>"+key+"</k><v>"+value+"</v></e>"; } catch(e) { <?php if ($this->bDebug){ ?>this.DebugMessage(e);<?php } ?> } } sXml += "</xjxobj>"; return sXml; } // Sends a XMLHttpRequest to call the specified PHP function on the server this.call = function(sFunction, aArgs, sRequestType) { var i,r,postData; if (document.body) document.body.style.cursor = 'wait'; <?php if ($this->bStatusMessages == true){?>window.status = 'Sending Request...';<?php } ?> <?php if ($this->bDebug){ ?>this.DebugMessage("Starting xajax...");<?php } ?> var xajaxRequestType = sRequestType; var uri = xajaxRequestUri; var value; switch(xajaxRequestType) { case <?php print GET; ?>:{ var uriGet = uri.indexOf("?")==-1?"?xajax="+encodeURIComponent(sFunction):"&xajax="+encodeURIComponent(sFunction); for (i = 0; i<aArgs.length; i++) { value = aArgs[i]; if (typeof(value)=="object") value = this.objectToXML(value); uriGet += "&xajaxargs[]="+encodeURIComponent(value); } uriGet += "&xajaxr=" + new Date().getTime(); uri += uriGet; postData = null; } break; case <?php print POST; ?>:{ postData = "xajax="+encodeURIComponent(sFunction); postData += "&xajaxr="+new Date().getTime(); for (i = 0; i <aArgs.length; i++) { value = aArgs[i]; if (typeof(value)=="object") value = this.objectToXML(value); postData = postData+"&xajaxargs[]="+encodeURIComponent(value); } } break; default: alert("Illegal request type: " + xajaxRequestType); return false; break; } r = this.getRequestObject(); r.open(xajaxRequestType==<?php print GET; ?>?"GET":"POST", uri, true); if (xajaxRequestType == <?php print POST; ?>) { try { r.setRequestHeader("Method", "POST " + uri + " HTTP/1.1"); r.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); } catch(e) { alert("Your browser does not appear to support asynchronous requests using POST."); return false; } } r.onreadystatechange = function() { if (r.readyState != 4) return; if (r.status==200) { <?php if ($this->bDebug){ ?>xajax.DebugMessage("Received:\n" + r.responseText);<?php } ?> var data = r.responseXML; if (data) xajax.processResponse(data); } } <?php if ($this->bDebug){ ?>this.DebugMessage("Calling "+sFunction +" uri="+uri+" (post:"+ postData +")");<?php } ?> r.send(postData); <?php if ($this->bStatusMessages == true){?>window.status = 'Waiting for data...';<?php } ?> <?php if ($this->bDebug){ ?>this.DebugMessage(sFunction + " waiting..");<?php } ?> delete r; return true; } // Tests if the new Data is the same as the extant data this.willChange = function(element, attribute, newData) { var oldData; if (attribute == "innerHTML") { tmpXajax = this.$(this.workId); if (tmpXajax == null) { tmpXajax = document.createElement("div"); tmpXajax.setAttribute('id',this.workId); tmpXajax.style.display = "none"; tmpXajax.style.visibility = "hidden"; document.body.appendChild(tmpXajax); } tmpXajax.innerHTML = newData; newData = tmpXajax.innerHTML; } eval("oldData=document.getElementById('"+element+"')."+attribute); if (newData != oldData) return true; return false; } //Process XML xajaxResponses returned from the request this.processResponse = function(xml) { <?php if ($this->bStatusMessages == true){?> window.status = 'Recieving data...'; <?php } ?> var tmpXajax = null; xml = xml.documentElement; for (i=0; i<xml.childNodes.length; i++) { if (xml.childNodes[i].nodeName == "alert") { if (xml.childNodes[i].firstChild) alert(xml.childNodes[i].firstChild.nodeValue); } if (xml.childNodes[i].nodeName == "jscript") { if (xml.childNodes[i].firstChild) eval(xml.childNodes[i].firstChild.nodeValue); } if (xml.childNodes[i].nodeName == "update") { var action; var element; var attribute; var search; var data; var type; var objElement; for (j=0; j<xml.childNodes[i].attributes.length; j++) { if (xml.childNodes[i].attributes[j].name == "action") { action = xml.childNodes[i].attributes[j].value; } } var node = xml.childNodes[i]; for (j=0;j<node.childNodes.length;j++) { if (node.childNodes[j].nodeName == "target") { for (k=0; k<node.childNodes[j].attributes.length; k++) { if (node.childNodes[j].attributes[k].name == "attribute") { attribute = node.childNodes[j].attributes[k].value; } } element = node.childNodes[j].firstChild.nodeValue; } if (node.childNodes[j].nodeName == "search") { if (node.childNodes[j].firstChild) search = node.childNodes[j].firstChild.nodeValue; else search = ""; } if (node.childNodes[j].nodeName == "data") { if (node.childNodes[j].firstChild) data = node.childNodes[j].firstChild.nodeValue; else data = ""; } if (node.childNodes[j].nodeName == "type") { if (node.childNodes[j].firstChild) type = node.childNodes[j].firstChild.nodeValue; else type = ""; } } if (action=="assign") { if (this.willChange(element,attribute,data)) { eval("document.getElementById('"+element+"')."+attribute+"=data;"); } } if (action=="append") eval("document.getElementById('"+element+"')."+attribute+"+=data;"); if (action=="prepend") eval("document.getElementById('"+element+"')."+attribute+"=data+document.getElementById('"+element+"')."+attribute); if (action=="replace") { eval("var v=document.getElementById('"+element+"')."+attribute); var v2 = v.indexOf(search)==-1?v:""; while (v.indexOf(search) > -1) { x = v.indexOf(search)+search.length+1; v2 += v.substr(0,x).replace(search,data); v = v.substr(x,v.length-x); } if (this.willChange(element,attribute,v2)) eval('document.getElementById("'+element+'").'+attribute+'=v2;'); } if (action=="clear") eval("document.getElementById('"+element+"')."+attribute+"='';"); if (action=="remove") { objElement = this.$(element); if (objElement.parentNode && objElement.parentNode.removeChild) { objElement.parentNode.removeChild(objElement); } } if (action=="create") { var objParent = this.$(element); objElement = document.createElement(attribute); objElement.setAttribute('id',data); if (type && type != '') objElement.setAttribute('type',type); objParent.appendChild(objElement); if (objParent.tagName == "FORM") { } } } } document.body.style.cursor = 'default'; <?php if ($this->bStatusMessages == true){?> window.status = 'Done'; <?php } ?> } } var xajax = new Xajax(); <?php $js .= ob_get_contents()."\n"; ob_end_clean(); foreach($this->aFunctions as $sFunction) $js .= $this->wrap($sFunction,$this->aFunctionRequestTypes[$sFunction]); if ($this->bDebug == false) $js = $this->compressJavascript($js); print $js; } }// end class xajax ?>