After checking out the latest WACT build from CVS, integration of Ajax functionality became a whole lot easier. This is a simple example of using the Prototype and Script.aculo.us javascript libraries to implement a rich UI with WACT. First of all, the controller itself:

<?php
 require_once '../loader.inc.php'; //loads common.inc.php
 require_once WACT_ROOT . 'controller/controller.new.php';
 require_once WACT_ROOT . 'view/view.new.php';
 
 class Application extends DecoratingController{
 	function Application(){
 		parent::DecoratingController();
 		
 		$responder =& new PathInfoDispatchController();
 
                //the search command will handle the search logic
 		$searchCommand =& new CommandController(new CallBack($this, 'search'));
 		$searchCommand->addParameter(new PostParameter('name'));
 		$responder->addPublicChild('search', $searchCommand);
 		
 		$this->addPublicChild('responder', $responder);
 		$this->setDefaultChildName('responder');
 		
 		$responder->addChild('searchResponse', new ViewController(new View('/results.html')));
 		
 		$this->setView(new AppView('/application.html'));
 	}
 	
 	function search(& $sender, & $request, & $responseModel){
 		$results = array(array('name' => 'Winnipeg'),
				 array('name' => 'Toronto'),
				 array('name' => 'Auckland'),
				 array('name' => 'Singapore'),
				 array('name' => 'Penang'));
		$results[] = array('name' => $request->getParameterValue('name'));
                //we're not doing any real filtering here, just sending content back to the client browser
 		$responseModel->set('results', $results);
                //returning searchResponse will redirect control to the ViewController in the new controller
                //architecture.
		return 'searchResponse';
	}
	
 }
 
 class AppView extends View{
 	function AppView($templateFile){
 		parent::View($templateFile);
 	}
 	
 	function prepareModel(& $source, & $request, & $responseModel){
		$responseModel->set('title', 'Application Controller');
		$responseModel->set('page_header', 'Demonstration of new WACT Controller Architecture');
	}
 }
 
 $app =& new Application;
 $app->start();
 
?>

Here’s our HTML template (application.html)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="http://localhost/ajax_php/assets/prototype.js"></script>
<script src="http://localhost/ajax_php/assets/effects.js" type="text/javascript"></script>
<script src="http://localhost/ajax_php/assets/dragdrop.js" type="text/javascript"></script>
<script src="http://localhost/ajax_php/assets/controls.js" type="text/javascript"></script>
<style type="text/css">
	#ac1update li:hover{
		background-color:#000099;
		color:#FFFFFF;
	}
</style>
<title>{$title}</title>
</head>
 
<body>
<h1>{$page_header}</h1>
 
<label>Auto-Suggest: </label><input name="name" type="text" id="ac1" autocomplete="off"/>
<div id="ac1update" style="display:none;border:1px solid black;background-color:white;position:relative;"></div>
 
 
<script type="text/javascript" language="javascript">
// <![CDATA[
    new Ajax.Autocompleter('ac1','ac1update','/samples/controllers/application.php/search');
// ]]>
</script>
 
</body>
</html>

The script block below automagically performs the linking of the textbox(ac1), the Ajax request and the response container(ac1update). When the value of the textbox changes, the onchange event will be triggered and the Prototype framework will compose a complete POST request to ‘/samples/controllers/application.php/search’. ‘application.php/search’ will direct the request to the CommandController named ‘search’ that’s been registered as the child of the root PathInfoDispatchController.

<script type="text/javascript" language="javascript">
// <![CDATA[
    new Ajax.Autocompleter('ac1','ac1update','/samples/controllers/application.php/search');
// ]]>
</script>

The results array will be populated in results.html

<list:list from="results">
<ul>
<list:item>
<li>{$name}</li>
</list:item>
</ul>
</list:list>

The populated template will be sent back as the response to the POST request made by the autocompleter. Once the autocompleter receives the response from the server, it will insert the unordered list into the container specified (ac1update) as innerHTML.

And there you have it, Ajax goodness with WACT!