|
You are here: Home / Documentation / AJAX in Sitellite |
AJAX in SitelliteNote: An introduction to this topic is available in the article "Client-Side RPC in Sitellite". This article builds on the topic by introducing a new, more powerful method introduced in Sitellite 4.2 Sitellite 4.2 introduces a new XMLHttpRequest-based method of performing RPC requests in JavaScript (the technique has now been dubbed "AJAX" amongst the JavaScript crowd, so I'll use that to keep in line with the majority). An AJAX request in this case is a behind-the-scenes request sent from JavaScript to PHP/Sitellite and back, happening instantaneously and requiring no page reload. Sitellite's previous method of performing AJAX requests was iframe-based, and while it was simple, it didn't help developers to effectively organize complex AJAX-based applications. It was good for isolated AJAX requests, but not for full-fledged AJAX-based applications. The new technique begins by creating a calculator app in your inc/app folder in Sitellite, with a box named 'index'. We'll re-implement the calculator example form the previous article, so you may compare and contrast the two techniques. inc/app/calculator/boxes/index/index.php
<?php
// import the RPC package
loader_import ('saf.Misc.RPC');
// set the page title
page_title ('RPC Calculator');
page_add_script (site_prefix () . '/js/rpc.js');
// display the calculator
echo template_simple ('calc.spt', $parameters);
?>
As you can see, the PHP code is pretty short, and is identical to the previous technique except that we've substituted the rpc_init() function call for a call to page_add_script(). Next, we'll create the template to output the calculator interface. inc/app/calculator/html/calc.spt
<script language="javascript">
var rpc = new rpc ();
var calculator = {
// the RPC request is an ordinary Sitellite box call
url: '{site/prefix}/index/calculator-rpc-action',
action: rpc.action,
calc: function (f) {
// these are the values we'll pass ot the RPC request
func = f.elements.func.options[f.elements.func.selectedIndex].value;
v1 = f.elements.v1.value;
v2 = f.elements.v2.value;
// the actual call to the server
rpc.call (
// the first parameter is the URL in the form of a GET request
this.action (func, [v1, v2]),
// the second parameter is an abstract function, which will
// handle the respnse from the server
function (request) {
// parsing the server's response
ans = eval (request.responseText);
// now that we have the server's response, let's do
// something with it
if (ans === false) {
ans = 'invalid entry';
}
document.getElementById ('answer').innerHTML = ans;
}
);
// always return false, in case the function is included in an
// onsubmit attribute
return false;
}
}
</script>
<form onsubmit="return calculator.calc (this)">
<p>
<input type="text" name="v1" size="5" />
<select name="func">
<option value="add">+</option>
<option value="sub">-</option>
<option value="mult">*</option>
<option value="div">/</option>
<option value="mod">%</option>
</select>
<input type="text" name="v2" size="5" />
<input type="submit" value="Go" />
</p>
</form>
<p>
= <span id="answer" style="font-weight: bold"> </span>
</p>
You'll notice the JavaScript has changed a fair bit from the previous method. This JavaScript looks a bit more complicated than before, but once we walk through it things should all make sense. First, we create a global rpc object. This object will take care of the communication with the server so we don't have to worry about that. Next, we create another global object, but this time it's a custom one. The calculator object will be our doorway to the server. Usually the methods we define within this object correspond to the functions available on the server. In this case however, we're going to wrap multiple server-side functions into one method on the client-side. The first thing we define in the calculator object is the url property. This tells us where to call the server-side handler. Notice that I used a {site/prefix} tag in this value. This is possible because we're in a .spt file, a SimpleTemplate template file. Now we'll define the method we'll use in our object to communicate with the server. We'll call it calc to stay in line with the previous article. The calc method takes the form object that is passed to it, retrieves the values from the fields func, v1, and v2 (value one and value two). It then calls rpc.call with two parameters. The first is the URL of the server-side handler (a Sitellite box call) made as an ordinary HTTP GET request. This is created for us by the this.action method. It's equivalent literal Javascript, which we saw something similar to in the first RPC tutorial, would be: this.url + '?method=' + func + '&v1=' + v1 + '&v2=' + v2, The this.action method takes the server-side function to call as as its first parameter, and an optional array of parameters to pass to the server-side function as its second parameter. The second parameter passed to rpc.call is a function which will be called by rpc.call to handle the server's response. calc then returns false so the form onsubmit event trigger does not submit the form. The function passed to the rpc.call has to do two things to complete the client-side code. The first is to parse the response from the server, which is stored as a serialized string in the request.responseText variable and can be turnned into an ordinary Javascript data structure (ie. a variable, an array, an object, etc.) via the eval() function. So the first thing our anonymous function calls is: ans = eval (request.responseText); Next, before updating the answer for the user, we'll check that the server was able to process it correctly. If it wasn't, the server will return false, so we then say: if (ans === false) {
ans = 'invalid entry';
}
It's as simple as that. Now all that's left to do is to show the user the answer by placing it into the span with the id="answer". This can be done with the following one-liner as well: document.getElementById ('answer').innerHTML = ans;
Now that we've gone over the Javascript line-by-line, it's not so mysterious at all. If we add two more files to our new "calculator" app, as we did in the first RPC tutorial, we'll be ready to see it in action: inc/app/calculator/conf/config.ini.php ; <?php /* DO NOT ALTER THIS LINE, IT IS HERE FOR SECURITY REASONS default_handler = index default_handler_type = box app_name = Calculator Example ;admin_handler = "" ;admin_handler_type = app ; DO NOT ALTER THIS LINE, IT IS HERE FOR SECURITY REASONS */ ?> inc/app/calculator/boxes/access.php sitellite_access = public sitellite_status = approved sitellite_action = on You should now be able to view the initial user interface of the example application by going to the following URL (be sure to replace "www.example.com" with your actual web site location): http://www.example.com/index/calculator-app Page 1: Note: An introduction to this to... |
|
Copyright © 2009, SIMIAN systems Inc. All rights reserved. Privacy policy Some of the icons on this site were created by the Gnome Project. |