hi!
I designed this myself, too, but I admit it needs rework (oo architecture should be redesigned).
basically it has proven for me to require the following.
- generally, html-displayable elements are to be nested into each other. top element of the nested structure can receive a getHtml() call and gets complete structure's html per delegation to contained elements.
top element can be a Page or, as I normally use it, the Form.
$f = new Form();
$f->addElement(new TextInput(...));
echo $f->getHtml();
all classes have a getHtml method, container classes have addElement etc. methods. all elements should have a styleClass attribute.
complex classes have a private buildHtml method which is accessed only once (caching of generated html code for performance reasons!): on getHtml call in case $this->html is still empty.
(optional) Page element (container for form)
Form element (container)
my forms have two display modes: (a) "flow" (one element's html after the other's with a Form::separator (default: <br />) in between. (b) "table" - one element in a table row. if the element has a [element]::label set, left cell is the label, right cell is the input itself. if not, colspan=2. left/right ([element]::labelside) changed for checkboxes and the like!
Form::addItems / Form::addItem should prevent multiple adding of elements with the same name.
InputContainer element: for nesting, e.g. for having multiple inputs in one form table row. align attribute (left, center, right).
Table container element: add a 2-dim array structure and have it displayed as an html table
Columns container element: simplified html table for text/html output in 2 (or more) columns (layout issue)
HtmlSnippet element: not an input but just a space for inserting arbitrary html code
normal HTML Input elements: TextField, PasswordField, FileUploadButton, ...
more sophisticated elements: TextArea (needs a maxlength for practical use - achieved by client-side javascript), DateInput, TimeInput, DateTimeInput
radio buttons need to come in form of an array of radio buttons, this is useful for checkboxes, too; therefore: RadioButtonArray, CheckBoxArray elements
SelectBox (::type may be multiple, ::size may be 1 or more - this covers Comboboxes and Listboxes) is extended by SqlSelectBox which automatically populates itself from the database. consider handy default values. I usually have "category tables" like category(id,text) (example: 1 - software, 2 - hardware, 3 - other). imagine this use: $form->addElement(new SqlSelectbox('type', 'category')); (type being the element's name and category the database table)
in analogy, there are SqlRadioButtonArray and SqlCheckBoxArray as well.
ErrorMessage and WarningMessage elements (contain array of elements to be presented in a predefined css style class, if more than one, as an <ul>).
this is where I have come to so far. I still have no automated, built-in processing and validation. there simply was no great need for ist. I validate always server-side and I use other structures for validation, like:
FurnitureOrderForm extends Form
where "FurnitureOrderForm" would have
a method to define itself - build($population=null) [population may be $_POST variable or whatever]
a processing method (validation, db writing)
* sometimes the constructor has an optional parameter: id of record in database, for internal load() method
I normally have small sequential wrapper scripts (e.g. place-order.php or edit-customer.php) that make use of the objects: trigger submit button click for data processing, if successful, header relocation to another page. else, display error message above form.
I hope this contains some useful ideas for you.
yours, matto