Quicknavi |
|
Forms
The adventure php framework supports the dynamic generation and abstraction of forms out-of-the-box.
Owing to the generic tag parser forms can be mapped by XML tags in template files and thus are embedded
in the DOM tree of the presentation layer. Thereby it is possible to give "internal intelligence" to
form elements. This implies automatic filling with the help of an URL parameter and the validation
of user inputs. The behaviour of these features can be influenced by configuring the form elements
via tag attributes. It is not necessary to implement functionality of these elements for the current
application.
1. Construction of forms
APF forms are simily to the HTML templates discussed under templates.
Each form can be seen as a child object of the current DOM node. To get a reference on this object
each document controller feature the __getForm() method. The form class has the
following API:
-
addFormElement()
Adds a form element at the end of the current form. This method can be used for dynamic form
creation.
-
addFormContent()
Adds content (HTML or text) to the end of the currend form. This method can be used for dynamic
form creation.
-
addFormContentBeforeMarker()
Adds content (HTML or text) before a marker tag to the current form. This method can be used for
dynamic form creation.
-
addFormContentAfterMarker()
Adds content (HTML or text) after a marker tag to the current form. This method can be used for
dynamic form creation.
-
addFormElementBeforeMarker()
Adds a form element before a marker tag to the current form. This method can be used for dynamic
form creation.
-
addFormElementAfterMarker()
Adds a form element after a marker tag to the current form. This method can be used for dynamic
form creation.
-
setPlaceHolder()
Fills a place holder defined within the form. Please refer to
standard taglibs for more details.
-
setAction()
Sets the "action" attribute do define the target to POST or GET against.
-
getFormElementByName()
Returns a reference an any form object defined by a name.
-
getFormElementByID()
Returns a reference an any form object defined by an id.
-
getFormElementByObjectID()
Returns a reference an any form object defined by an internal object id.
-
transformForm()
Creates the HTML output of a form and returns it.
-
transformOnPlace()
Indicates, that the form will be displayed where it was defined within the template file. Though
it is not necessary to transform the form object with transformForm() and assign the
content to a place holder.
To use the tag it must be announced using the
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
directive before using it. After that a login form may be defined like this:
<html:form name="AdminLogin" method="post" action="">
<form:placeholder name="LogInError" />
Username: <form:text name="Username" class="input_feld" style="width: 200px; margin-left: 20px;"
validate="true" button="AdminLogin" />
<br />
Password: <form:password name="Password" class="input_feld" style="width: 200px; margin-left: 16px;"
validate="true" button="AdminLogin" />
<br />
<br />
<form:button name="AdminLogin" value="Login" class="input_feld" style="margin-left: 227px;"/>
</html:form>
In detail: the <html:form /> XML tag possesses the attribute name
to be able to get reference on the form and the attribute method to define the
send mode. action defines the target to send the form to. This attribute most not be
defined due to the fact, that the taglib behind the form tag adds the action automatically
if the attribute is not present in the template file.
Within forms many form elements can bedefined: place holders to display hints or legends, text or
password fields or buttons. Please refer to standard taglibs
to find a detailed description of the available tag libs. To use the previously defined form the
following code can be used:
$Form__AdminLogin = &$this->__getForm('AdminLogin');
The variable $Form__AdminLogin now contains a reference on the form object. Further
the place holder's content of the previously defined form can be filled by
$Form__Placeholder_LogInError = &$Form__AdminLogin->getFormElementByName('LogInError'); $Form__Placeholder_LogInError->setPlaceHolder('Login failed!');
The form object internally stores the current status of the form. To gather the information whether
a form was sent or filled correctly concerning the defined validation methods the subsequent lines of
code help to achieve this:
if($Form__AdminLogin->get('isValid') && $Form__AdminLogin->get('isSent')){
// Do something that should be done if the form is sent and valid ...
// end if }
In order to display a form you have two possibilities: assigning the content to any place holder
defined within the template file of make use of the transformOnPlace() function:
function transformContent(){
...
// Transform and output form by assigning the content to any placeholder ... $this->setPlaceHolder('...',$Form__AdminLogin->tranformForm());
// ... display the form in place $Form__AdminLogin->tranformOnPlace();
...
// end function }
2. Validation
As mentioned above validation of form elements can be configured out-of-the-box. For this purpose the
attributes
- validate
- validator
- button
must be added to a form element. For details please refer to the XML tag definition under
standard taglibs, Kapitel 2.3. In order to
validate the fields of the above defined form the text field must be adjusted as performed afterwards:
<form:text name="Username" validate="true" button="AdminLogin" />
Please note that for correct validation the name of the button must be present. If the attribute
button is not set the taglib implementation raises an error. In order to format a
form element with CSS attributes, the attributes "style" or "class" can be used as desired.
<form:text name="Username" class="eingabe_feld" style="width: 200px; margin-left: 20px;"
validate="true" button="AdminLogin" />
If the attribute "validator" is not set the standard validator (validateText) is used instead.
3. Manipulation of form elements
Die Implementierung der Formular-TagLibs des Frameworks bringt einige Möglichkeiten zur
Manipulation von Formularelementen oder deren Werte mit. Die folgenden Kapitel zeigen häufig
auftretende Anwendungsbeispiele.
3.1. Prefilling of forms
In order to prefill forms (e.g. in edit dialoges) the methods getFormElementByID(),
getFormElementByID() or getFormElementByObjectID() can be used to
get a reference on the desired form element. Subsequently, the standard methods get()
and getAttribute() and set() and setAttribute()
respectivly are avaliable for data manipulation of an form element.
The following box defines an example form, that will be filled by the PHP code printed below:
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<html:form name="UserEdit" method="post">
<strong>FirstName</strong>:
<form:text name="FirstName" validate="true" button="Edit" />
<br />
<strong>LastName</strong>:
<form:text name="LastName" validate="true" button="Edit" />
<br />
<br />
<form:button name="Edit" value="Save" />
<form:hidden name="userid" />
</html:form>
// get the form object $Form__Edit = &$this->__getForm('UserEdit');
// get the hidden field object and fill the value $UserID = &$Form__Edit->getFormElementByName('userid'); $UserID->setAttribute('value','...');
// get the FirstName field and fill the value $FirstName = &$Form__Edit->getFormElementByName('FirstName'); $FirstName->setAttribute('value','...');
// get the LastName field and fill the value $LastName = &$Form__Edit->getFormElementByName('LastName'); $LastName->setAttribute('value','...');
3.2. Prefilling of select fields
Dealing with select or multiselect fields is a little bit different to "normal" form elements. But the
framework provides common methods to fill these types of fields as well. The following form contains
two select fields in addition to the four "normal" form elements:
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<html:form name="UserCreate" method="post">
<strong>Salutation</strong>:
<form:select name="Salutation" />
<br />
<strong>FirstName</strong>:
<form:text name="FirstName" validate="true" button="Edit" />
<br />
<strong>LastName</strong>:
<form:text name="LastName" validate="true" button="Edit" />
<br />
<br />
<strong>Salutation</strong>:
<br />
<form:multiselect name="Group[]" validate="true" button="Edit" />
<br />
<br />
<form:button name="Edit" value="Save" />
<form:hidden name="userid" />
</html:form>
As the tag definition of the Groups[] fiels shows, the name of a multiselect field
must contain brackets. If the template developer forgets to put them in, a error message will be
displayed.
In order to fill the select fields, the following PHP code can be used:
Der folgende PHP-Code befüllt das Formular:
// get the form object $Form__Create = &$this->__getForm('UserCreate');
...
// get the Salutation field and add some options $Salutation = &$Form__Create->getFormElementByName('Salutation');
for($i = 0; $i < count($Salutations); $i++){ $Salutation->addOption($Salutations[$i]['Value'],$Salutations[$i]['DisplayName']); // end for }
// get the Groups[] field and add some options $Group = &$Form__Create->getFormElementByName('Groups[]');
for($i = 0; $i < count($Groups); $i++){ $Group->addOption($Groups[$i]['Value'],$Groups[$i]['DisplayName']); // end for }
...
3.3. Readout form element values
Readout of form elements is similar to the filling of form elements. In both situations, the
getFormElementByName() method can be used to obtain a reference on any form element.
Please note, that select and multiselect fields are here also treated a little bit different. The
next few lines describe, how to gather values of form elements:
// get the form object $Form__Edit = &$this->__getForm('UserEdit');
// get the value of the hidden field $UserID = &$Form__Edit->getFormElementByName('userid'); echo $UserID->getAttribute('value');
// read the content of the FirstName field $FirstName = &$Form__Edit->getFormElementByName('FirstName'); echo $FirstName->getAttribute('value');
// read the content of the LastName field $LastName = &$Form__Edit->getFormElementByName('LastName'); echo $LastName->getAttribute('value');
To read the content of select or multiselect fields the getSelectedOption() and
getSelectedOptions() function can be used:
// get the form object $Form__Create = &$this->__getForm('UserCreate');
// prefill the Salutation field $Salutation = &$Form__Create->getFormElementByName('Salutation'); for($i = 0; $i < count($Salutations); $i++){ $Salutation->addOption($Salutations[$i]['Value'],$Salutations[$i]['DisplayName']); // end for }
// get the selected option of the Salutation field and print it to screen $Option = &$Salutation->getSelectedOption(); echo $Option->getAttribute('value').', '.$Option->get('Content');
// prefill the Group field $Group = &$Form__Create->getFormElementByName('Groups[]');
for($i = 0; $i < count($Groups); $i++){ $Group->addOption($Groups[$i]['Value'],$Groups[$i]['DisplayName']); // end for }
// get the selected options of the Groups[] field and print them to screen $SelectedGroups = &$Group->getSelectedOptions(); for($i = 0; $i < count($SelectedGroups); $i++){ echo $SelectedGroups[$i]->getAttribute('value').', '.$SelectedGroups[$i]->get('Content'); // end for }
4. Dynamic Forms
In some cases it is necessary to generate forms dynamically. For this reason, the form taglib
(html_taglib_form) features the methods
- addFormElement()
- addFormContent()
and as of release 1.7
- addFormContentBeforeMarker()
- addFormContentAfterMarker()
- addFormElementBeforeMarker()
- addFormElementAfterMarker()
The first two functions can be used to add content (i.e. plain text or html) or form elements at the
end of the form. The latter ones are intended to add content or form at certain positions. For this
reason, the <form:marker /> tag was introduced. The tag itself does not generate
any output, but can be used for positioning purposes along with the "addForm*[Before|After]Marker()"
methods.
The following chapters describe, how a dynamic form can be generated displaying form coordinate fields
(triangle, square, ...). Depending on the type, the corresponding fields are displayed. If the type
is set to "square", four fields are displayed ...
... in case of "triangle" three fields are presented:
4.1. Form definition
As already mentioned, the dynamic definition can be done in two flavours. While using
addFormElement() and/or addFormContent(), no marker is needed. Instead, the
following example uses marker, because the form already contains structural elements (e.g. table).
The following code box shows the form definition needed to display the form denoted above. To keep
things simple, no CSS was added. Taking a closer look at the definition, you can see, that the form
consists of a static select field, that defines the types available and a marker tag for positioning.
Further, a document controller is specified, to add the desired form elements in front of the marker:
<@controller namespace="..." file="..." class="select_controller" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<html:form name="type" method="post">
<table>
<tr>
<td>
Please choose the desired form type:
<form:select name="type">
<select:option value="triangle">triangle</select:option>
<select:option value="square">square</select:option>
</form:select>
</td>
<td>
<form:button name="submit" value="send" />
</td>
</tr>
<tr>
<td>
<form:marker name="fields" />
</td>
</tr>
</table>
</html:form>
4.2. Controller
The document controller is responsible for generating the form field, that depends on the type of
the geometrical shape. For this reason, the constructor contains a definition of the form fields
that should be displayed for a concrete type. Afterwards, the typ is read from the select field and
the form is enhanced with additional content and fields. The following code box presents the
implementation of the document controller needed for this functionality:
class select_controller extends baseController {
// specify form element container var $__FormElements = array();
function select_controller(){
// define form elements for the triangle $this->__FormElements['triangle'][] = array('label' => 'coord 1','name' => 'coordone'); $this->__FormElements['triangle'][] = array('label' => 'coord 2','name' => 'coordtwo'); $this->__FormElements['triangle'][] = array('label' => 'coord 3','name' => 'coordthree');
// define form elements for the square $this->__FormElements['square'][] = array('label' => 'coord 1','name' => 'coordone'); $this->__FormElements['square'][] = array('label' => 'coord 2','name' => 'coordtwo'); $this->__FormElements['square'][] = array('label' => 'coord 3','name' => 'coordthree'); $this->__FormElements['square'][] = array('label' => 'coord 4','name' => 'coordfour');
// end function }
function transformContent(){
// get form reference $Form = &$this->__getForm('type');
// get current decision $Select = &$Form->getFormElementByName('type'); $Option = &$Select->getSelectedOption(); if($Option === null){ $CurrentType = 'triangle'; // end if } else{ $CurrentType = $Option->getAttribute('value'); // end else }
// add form elements for($i = 0; $i < count($this->__FormElements[$CurrentType]); $i++){
// add label $Form->addFormContentBeforeMarker('fields',$this->__FormElements[$CurrentType][$i]['label'].': ');
// add text field (name attribute is present to enable validation and presetting!) $CurrentElementID = $Form->addFormElementBeforeMarker( 'fields', 'form:text', array('name' => $this->__FormElements[$CurrentType][$i]['name']) );
// configure further form element attributes $CurrentElement = &$Form->getFormElementByObjectID($CurrentElementID); $CurrentElement->setAttribute('style','width: 200px;');
// add a line break $Form->addFormContentBeforeMarker('fields','<br />');
// end for }
// display form $Form->transformOnPlace();
// end function }
// end class }
4.3. Notes
A APF form element does need information about the name of itself already at creation time. If the
element doesn't know it's own name, presetting and validation cannot be enabled. In order to use
presetting and validation in combination with dynamic form elements, the addFormElement(),
addFormElementBeforeMarker() and addFormElementBeforeMarker() functions possess a
third parameter. This parameter expects an associative list of tag attributes, that are applied to
the form object on creation time. Creating dynamic form elements, it is thus recommended to at least
apply the name of the tag to the third argument:
array(
'name' => 'currentname'
)
Please note, that the tag attributes are also interesting for addressing the form objects after
appending them to the form via the getFormElementByName() or getFormElementByID()
methods.
Comments
Do you want to add a comment to the article above, or do you want to post additional hints? So please click here. Comments already posted can be found below.
There are no comments belonging to this article.
|