This package implements a PageController design pattern, which essentially means that there is a single page processing requests and actions this page performs depend on parameters passed in GET or POST data. The pattern is described in more detail on Martin Fowler's website and WACT project website.
What does this mean in application to QuickForm: we have a single script which shows and validates different forms depending on data in request. This allows to fairly easy build very complex forms consisting of several pages (think wizards and such).
The most basic implementation of the PageController pattern would look like
switch ($_REQUEST['action']) { 'foo': doFoo(); break; 'bar': doBar(); break; default: echo 'Hello, world!'; } |
HTML_QuickForm_Controller: this class extracts the action name from request and calls the appropriate handler. It includes several Pages.
HTML_QuickForm_Page: this class (extending HTML_QuickForm) represents a single page of a form.
HTML_QuickForm_Action: this class implements the Command design pattern, i.e. is essentially an OO callback.
Session initialization: This simple example does not use sessions since there is no need to pass data between pages. You'll need to use sessions when dealing with a real multipage form, though. HTML_QuickForm_Controller does not start a session automatically, you should explicitly call session_start() before instantiating the controller class.
To ease understanding of this package's features, lets take an example form from HTML_QuickForm tutorial and redo it using HTML_QuickForm_Controller:
Example 41-1. Basic Controller usage
|
You may note that the code is more verbose than the original. That is true, but to make a three page wizard-type form you'll only need to create three subclasses of HTML_QuickForm_Page and 'process' event handler based on HTML_QuickForm_Action and add them to Controller, while without the Controller infrastructure it will require a non-trivial amount of programming.
You need to subclass HTML_QuickForm_Page and override its buildForm() method. Its contents are pretty self-explanatory (if you are familiar with QuickForm), except for a few things:
$this->_formBuilt = true; |
The second notable line is
$this->addElement('submit', $this->getButtonName('submit'), 'Send'); |
The third thing is
$this->setDefaultAction('submit'); |
You'll usually need to create handlers for two actions: 'process' and 'display'. While it is difficult to say anything about the former, as only you know how to process your form, for the latter you'll need to subclass HTML_QuickForm_Action_Display and override its _renderForm() method to call the appropriate Renderer and do form output customization.
Next we instantiate the page class defined above
$page =& new FirstPage('firstForm'); |
$page->addAction('process', new ActionProcess()); |
Then we instantiate the controller
$controller =& new HTML_QuickForm_Controller('tutorial'); |
Then we set the defaults for the form and add the page to it
$controller->setDefaults(array( 'name' => 'Joe User' )); $controller->addPage($page); |
Finally we call the Controller's run() method
$controller->run(); |
...are available in the package archive. Along with the example similar to the provided above, there are two multipage forms:
Wizard: form pages contain 'Next' and 'Back' buttons and you can't go to the next page unless the current page is valid.
Tabbed form: form has several pages and buttons allow to go directly to the corresponding page. Form is validated only when the global 'Submit' button is pressed.