Table of Contents
Reusable form components for OWCMS
We often end up implementing similar user interface functionality in many places in OwCms. This usually would involve a cut+paste of the code from one place to another, perhaps with some slight customisation.
This approach has a number of drawbacks:
- it takes time to re-implement functionality over again
- the chance of introducing a bug after cut+paste is high
- if you want to make a global change to the behaviour of a particular user interface component (such as enhancing its usability or changing the design) then this is very difficult
- the incentive to implement high quality user interface is weakened, because it's difficult to reuse
To help overcome this problem, a framework for building re-usable form components has been developed. This was loosely based on the form components system in ACS-Java (arsdigita community system, Java).
This framework provides:
- a base-class called
formsection -- This is the basic building block for a reusable form component. I'll say more about it later
-
form which is a specialisation of formsection (ie. it is derived from it). A form is the root container into which you should add other form sections.
The FormSection class includes a number of important methods, many of which need to be overridden in a derived class in order to implement your own customized FormSection. These are:
-
validate()
-
process()
-
render()
In order to understand these methods, you should understand the basic flow of execution of a form. Normally this would be:
-
formSubmitted() is called.
- if the form has been submitted (e.g. the "OK" button was pressed), then
validateAndProcess() will be called
-
validateAndProcess() will in turn call validate(). This will check whether form data entered by the user is valid, returning boolean to indicate success or fail
- if
validate() suceeded, then process() will be called. This should read the user submitted data and carry out the requested actions, such as updating data in the database.
- if
validateAndProcess() was successful then formExit() is called
- depending on how the form has been customized, and what action was requested,
formExit() may issue an http redirect to another page (e.g. if OK was pressed and everything was processed correctly, the form will be closed)
-
render() is called, this will generate the html for displaying the form to the user.
Here is a sample code snippet illustrating how a form would be used:
$form =& new MyTest();
$form->formSubmitted();
echo $form->render();
This does the following:
- instantiates a Form called MyTest
- calls
formSubmitted() to allow it to handle any posted events
- finally calls
render() to render the form.
* This section to be written
*
In order to build your own form section, you must
call $this->addValidationError() for each error message you want to display. These will appear in the error form section.
Return false if there was an error, or true if not.
*TBD*
Rendering can be either 'basic' or 'template driven'.
To use 'template driven' style, call initialiseTemplateDrivenFormSection() in the constructor of your form section, then override
renderTemplateDriven to populate your template variables. Eg:
class MyTest extends TemplateDrivenForm {
function MyTest() {
$ini =& INIFile::globalINI();
$this->initialiseTemplateDrivenFormSection('ezarticle/admin/'.$ini->read_var( "eZArticleMain", "AdminTemplateDir" ),
'ezarticle/admin/intl/',
'mytest');
$this->_search =& new eZArticleAdvancedSearch();
$advancedSearchWidget=& new ArticleAdvancedSearchWidget($this->_search);
$this->addNamedFormComponent('searchwidget', $advancedSearchWidget);
}
function process() {
$ok = parent::process();
echo dumpArray($this->_search);
return $ok;
}
function renderTemplateDriven() {
if ($this->_search) {
$t =& $this->getTemplate();
$t->set_var('search_result_dump', $this->_search->count()));
}
}
}
Adding child components to a form or form section
-
addComponent()
-
addNamedFormComponent()
see
OwCmsReusableFormComponentsTryItOut for sample code and a step-by-step guide of how to try out a reusable form component.
for some examples, look at the block layout tool. Each block provides an editing widget for itself.
See
ezsitemanager/classes/pagelayout/:
-
blockwithheading.php
- see how the editing widget from blockwithheading is reused in
articleblock.php
most reusable widgets are added in classes/widgets
| filename | purpose |
| form.php | contains the implementation of formsection and form classes, together with other minor form sections such as okcancel, heading |
| articleadvancedsearchwidget.php | for editing an eZArticleAdvancedSearch object, edits category, topic, language, etc |
| articleimagelistwidget.php | for editing images associated with a single article |
| categorysearchwidget.php | for finding a single category by typing in a path for the category then selecting from a list of matching options (as used in frontpage tool and block edit tool) |
| countrywidget.php | select a country |
| dateselectorwidget.php | select a date using dropdown menus for day&month |
| filteredcategorynavigator.php | perform an action on a particular category. Categories are displayed in a tree-like way. Good for allowing a user to quickly find a category from up to 50 options. (used in AliasBlock) |
| formattedtexteditwidget.php | for editing 'ezpublish tagged' text |
| jobadvancedsearchwidget.php | for editing a job advanced search object |
| jobwidgets.php | ??? |
| languagewidget.php | language |
| multicategorysearchwidget.php | ??? |
| parameditsheet.php | edit a whole bunch of params at once, not sure how generic it is |
| partneradvancedsearchwidgets.php | for editing a partner advanced search |
| partnerdescriptionwidget.php | for editing partner 'description of work' classification |
| partnerpackagewidget.php | for editing a partner package |
| partnersectorwidget.php | partner sector |
| partnertopicwidget.php | partner topic |
| selectboxwidget.php | generic selectbox widget (base class for many of the above select box widgets) |
| topicwidget.php | article topic |