Forms (as of release 1.11)
Due to the fact, that the
page controller of the APF
provides a generic frame to handle taglibs, we were able to implement a form abstraction built on
taglibs (e.g. text fields).
The release of the adventure php framework contains a set of taglibs, that fully describe HTML
forms and that contain features such as filtering, validation and presetting at the same time out of
the box. With the taglibs reworked with release 1.11, form fields can be applied various filters and
validators and custom form elements can be integrated with the delivered ones.
The subsequent chapters describe the general design and the handling of APF forms as well as the
tags shipped with the release with their meaning and functionality. Reading this documentation
and implementing applications, it is recommended to have the
API documentation opened.
There, you can see, which functionality is included in the various taglibs - e.g. the
html_taglib_form.
As noted in the introduction, APF forms are represented by taglibs. The
<html:form /> tag forms the base taglib, that encapsulates all other form
tags and presents an APF form
as a single object to the document controller. It contains
further tag instances as it's child oblects that represent dedicated elements like text fields or
buttons or functional tags such as place holders, listeners or tags, that add custom form controls.
Forms - as you know from other APF GUI elements - are defines within template files. A simple form
with a search field and a button looks like this:
APF-Template
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<html:form name="Search">
<form:text name="searchterm" /> <form:button name="search" value="GO" />
</html:form>
In order to display the form a document controller must be defined for the corresponding template.
This is necessary, because a form - in contrast to other tags - is always coupled with functionality
to handle the data passed to the form. This may be reading the search term or executing the search
or saving user data.
Displaying a form is not rocket science with the APF and can be done with the following controller
code:
PHP-Code
class search_controller extends base_controller {
public function transformContent(){
$form = &$this->__getForm('Search');
$form->transformOnPlace();
}
}
The subsequent sections present the form controls contained within the APF release and give you
a brief introduction to the usage of these elements.
The APF contains an extended set of form control abstraction tags, that can be configured for
different purposes. In case this is not enough, custom form taglibs can be introduced as desired.
This is described in detail under
usage of forms.
Since the APF's page controller is built up on a generic tag parser, form tags can be added
generic attributes such as:
- id="..."
- class="..."
- style="..."
These are presented in the generated source code and can thus be used for formatting purposes. For
this reason, the following chapters do not mention these attributes, but only describe the
attributes, that are necessary for the configuration of the tag.
Attributes, that are surrounded with "[" and "]" (brackets) are optional.
All other attributes must be present, otherwise the corresponding taglib may throw an error.
The form tag itself takes three functional atributes, that are used for definition and configuration:
APF-Template
<html:form name="" [method=""] [action=""]>
...
</html:form>
Description of the attributes:
-
name: Name of the form. This attribute is used to address the form within
a document controller.
(Allowed characters:
[A-Za-z0-9-_])
-
method: Method that is used to send the form data. By default,
post is used.
(Allowed characters:
[get|post])
-
action: The url, that is called on button click by the browser.
This taglib represents a submit button. APF form elements are validated and filtered on button click
event. Hence, it is necessary to specify a button or image button within the form, due buttons
create the
click event.
APF-Template
<form:button name="" value="" />
Description of the attributes:
-
name: Name of the button. The name is used to access the button. This is
necessary for validators and filters.
(Allowed characters:
[A-Za-z0-9-_])
-
value: Value of the button. The browser uses this value to label the button.
The image button tag creates an image button, that uses an image as the label. The functionality
is equal to the "normal" button.
APF-Template
<form:imagebutton name="" src="" />
Description of the attributes:
-
name: Name of the button. The name is used to access the button. This is
necessary for validators and filters.
(Allowed characters:
[A-Za-z0-9-_])
-
src: Image source.
As of the release 1.10, the form taglibs contain a reset button wrapper. It represents a HTML reset
button and can be addressed and configured as "normal" buttons within a document
controller.
A reset button does not fire the click event, thus validation and filtering is not possible!
APF-Template
<form:reset value="" />
Description of the attributes:
-
value: The value (label) of the reset button.
APF-Template
<form:hidden name="" value="" />
Description of the attributes:
-
name: The name of the hidden field. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
-
value: The value of the hidden field.
APF-Template
<form:text name="" [value=""] />
Description of the attributes:
-
name: Name of the text fields. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
-
value: Value of te text field.
You can use the APF text area wrapper taglib in two flavours: without explicit content as a
self-closing tag and with content as explicitly closing tag.
APF-Template
<form:area name="" />
<form:area name="">...</form:area>
Description of the attributes:
-
name: Name of the text area. This attribute can be used to access the
control. (Allowed characters:
[A-Za-z0-9-_])
APF-Template
<form:password name="" [value=""]/>
Description of the attributes:
-
name: Name of the password field. This attribute can be used to access the
control. (Allowed characters:
[A-Za-z0-9-_])
-
value: Value of the password field.
The file upload field can be defined as follows:
APF-Template
<form:file name="" />
Description of the attributes:
-
name: Name of the file upload field. This attribute can be used to access the
control. (Allowed characters:
[A-Za-z0-9-_])
As of release 1.12, the file upload field was enhanced to support the developer to build file
upload forms easily. For this reason, the taglib was enhanced by the following methods that can
be used in document controllers to handle uploaded files:
-
hasUploadedFile():boolean: returns true in case a file has been uploaded and
false otherwise.
-
getFile():FileModel: returns an instance of the FileModel that represents an
uploaded file. In case no file has been uploadad null is returned.
The wiki article
File-Upload mit Form-Taglibs
(German) describes, how file upload can now be realized easily. Please note the
MimeTypeValidator and
FileSizeValidator added in 1.12. They can be
used to validate the files uploaded by the user.
The checkbox implementation is not only a simple wrapper for the HTML checkbox, but includes the
functionality to automatically check or uncheck the box. With this taglib, the problem with
re-checking boxes on re-submit is solved.
APF-Template
<form:checkbox name="" value="" [checked="checked"] />
Description of the attributes:
-
name: Name of the checkbox. This attribute can be used to access the
control. (Allowed characters:
[A-Za-z0-9-_])
-
value: Value of the checkbox.
-
checked: Defines, whether the checkbox should be preselected.
The radio button implementation is not only a simple wrapper for the HTML radio buttons, but
includes the functionality to automatically check or uncheck the button. With this taglib, the
problem with re-checking buttons on re-submit is solved.
APF-Template
<form:radio name="" value="" [checked="checked"]/>
Description of the attributes:
-
name: Name of the radio button. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
-
value: Value of the radio button - or precisely - the name of the current option.
-
checked: Defines, whether the button should be preselected.
A select field can be defined in two different ways. Possibility one is a field, that is filled
dynamically within a document controller and does not contain static options. Possibility two is a
select field, that defines static options that may be preselected.
APF-Template
<form:select name="" />
<form:select name="">
<select:option value="" [selected="selected"]>...</select:option>
</form:select>
Description of the attributes:
-
name: Name of the select field. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
-
value: Value of the option.
(Allowed characters:
[A-Za-z0-9-_])
-
selected: In case an option should be preselected, the selected
attribute must contain the name of the attribute as it's value.
As the simple select field, the multi select field allows you to specify two different types: with
and without static options.
APF-Template
<form:multiselect name="" />
<form:multiselect name="">
<select:option value="" [selected="selected"]></select:option>
</form:multiselect>
Description of the attributes:
-
name: Name of the multi select field. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
-
value: Value of the option.
(Allowed characters:
[A-Za-z0-9-_])
-
selected: In case an option should be preselected, the selected
attribute must contain the name of the attribute as it's value.
The name of the form field must not contain "[]" at the end. Otherwise errors occure
when addressing the element!
A place holder can be used to insert dynamic content into the form.
APF-Template
<form:placeholder name="" />
Description of the attributes:
-
name: Name of the place holder. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
Filling a place holder, the
html_taglib_form's method
setPlaceHolder() can be uses:
PHP-Code
$form = &$this->__getForm('MyForm');
$form->setPlaceHolder('NameOfThePlaceHolder','...Value...');
To ease date select field generation, the APF contains a date form control that can be configured
to fit your needs.
APF-Template
<form:date name="" [yearrange=""] [offsetnames=""]/>
Description of the attributes:
-
name: Name of the date control. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9-_])
-
yearrange: The range of years, that should be presented to the user.
Example:
1990-2007.
(Allowed characters: [0-9-])
-
offsetnames: Explicitly specifies the name of the date control's components
(=name of the single fields). Example:
day;month;year.
(Allowed characters: [A-Za-z;])
As described in chapter
dynamic forms,
the
<form:marker /> tag can be used to position dynamic form elements. The
tag itself creates no output.
APF-Template
<form:marker name="" />
Description of the attributes:
-
name: Name of the markers. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9_-])
The
<form:addtaglib /> tag is the pendant to the
<core:addtaglib /> tag. It offers the possibbility to add custom form tags.
APF-Template
<form:addtaglib namespace="" prefix="" class="" />
Description of the attributes:
-
namespace: Namespace path seperated with "::".
(Allowed characters:
[A-Za-z0-9_-:])
-
prefix: XML prefix
(Allowed characters:
[a-z])
-
class: XML class
(Allowed characters:
[a-z])
Please note, that the taglibs added with this tag implement the form_control
class to ensure, that the correct status is reported to the form by isSent() and isValid().
The
<form:getstring /> tag offers the possibility to display language
dependent values from a language dependent config file within forms. Details on the configuration
can be read about in the chapter, that describes the
<html:getstring />
tag.
APF-Template
<form:getstring namespace="" config="" entry="" />
Description of the attributes:
-
namespace: Namespace of the configuration file.
(Allowed characters:
[A-Za-z0-9_-:])
-
config: Name of the configuration file.
(Allowed characters:
[A-Za-z0-9-_])
-
entry: Name of the configuration key to display the value of.
(Allowed characters:
[A-Za-z0-9-_.])
The listener tag is part of the new validation concept. The tag "listens" on the event, the
validator fires and shows it's content, in case the addressed form element could not be validated
successfully. Within the body of the tag, several subtags and textual content can be defined, that
can be used to format the output. Details on the validation concept can be read about in chapter 4.
APF-Template
<form:listener [name=""] control="..." [validator="..." ]>
...
[<listener:getstring namespace="" config="" key="" />]
[<listener:placeholder name="" />]
...
</form:listener>
Description of the attributes:
-
control: Name of the form element, that the validator tag listens to.
(Allowed characters:
[A-Za-z0-9_-])
-
name: Name of the listener. This attribute can be used to access the
control.
(Allowed characters:
[A-Za-z0-9_-])
-
validator: Name of the validator, that is allowed to notify the listener on
validation errors.
The place holder tag
<listener:placeholder /> acts like the
<html:placeholder />,
the
<listener:getstring /> tag like the
<html:getstring />
tag. In order to fill the the place holder, the following document controller code can be used:
Template:
APF-Template
<html:form name="name_form" method="post">
<form:listener name="name-listener" control="name">
Please fill in the <listener:placeholder name="field-name" /> field!
</form:listener>
<form:text name="name" />
<form:addvalidator
class="TextLengthValidator"
control="name"
button="send"
/>
<form:button name="send" value="Send" />
</html:form>
Controller:
PHP-Code
class form_controller extends base_controller {
public function transformContent(){
$form = &$this->__getForm('name-form');
$listener = &$form->getFormElementByName('name-listener');
$listener->setPlaceHolder('field-name','name');
}
}
The attribute validator can be used in case the form control to validate has a
special validator defined. One sample application case is an email field, that
should be marked up with two different error messages: one for missing input and one for
incorrect email addresses. To achieve this, you can use the following template code:
APF-Template
<html:form name="email_form" method="post">
<form:listener control="email" validator="TextLengthValidator">
Please fill in the email field!
</form:listener>
<form:listener control="email" validator="EMailValidator">
Please fill in the email field with a correct email address!
</form:listener>
<form:text name="email" />
<form:addvalidator
class="TextLengthValidator"
control="name"
button="send"
type="special"
/>
<form:addvalidator
class="EMailValidator"
control="email"
button="send"
type="special"
/>
<form:button name="send" value="Send" />
</html:form>
Please note, that validators having the attribut
type set to
special do only
notify special validators. In case the validator messages of the target control should be marked,
you can add another
EMailValidator, that notifies listeners, that contain the necessary
markup.:
APF-Template
<html:form name="email_form" method="post">
<form:listener control="email">
<div class="error-container">
</form:listener>
<form:listener control="email" validator="TextLengthValidator">
Please fill in the email field!
</form:listener>
<form:listener control="email" validator="EMailValidator">
Please fill in the email field with a correct email address!
</form:listener>
<form:listener control="email">
</div>
</form:listener>
<form:text name="email" />
<form:addvalidator
class="TextLengthValidator"
control="name"
button="send"
type="special"
/>
<form:addvalidator
class="EMailValidator"
control="email"
button="send"
type="special"
/>
<form:addvalidator
class="EMailValidator"
control="email"
button="send"
/>
<form:button name="send" value="Send" />
</html:form>
The tag described within chapter 3.18 can be used to automatically display field relevant errors.
The
<form:error /> tag is used to display errors for the matter
of the whole form. If one of the fields could not be validated successfully, the content of the tag
is displayed - if present in the form definition.
APF-Template
<form:error [name=""]>
...
[<error:getstring namespace="" config="" key="" />]
[<error:placeholder name="" />]
...
</form:error>
The place holder tag
<error:placeholder /> acts like the
<html:placeholder />,
the
<error:getstring /> tag like the
<html:getstring />
tag. Filling the place holder can be done as described in the last chapter.
The tag described within chapter 3.19 can be used to automatically display error messages for the
matter of the whole form. Often, it is necessary to display messages in case the form was correctly
filled. The
<form:success /> displays it's content, in case all
fields are maked valid. The definition of the tag is as follows:
APF-Template
<form:success [name=""]>
...
[<success:getstring namespace="" config="" key="" />]
[<success:placeholder name="" />]
...
</form:success>
The place holder tag
<success:placeholder /> acts like the
<html:placeholder />,
the
<success:getstring /> tag like the
<html:getstring />
tag. Filling the place holder can be done as described in the last chapter.
The TimeCaptcha can be used in combination with the
TimeCaptchaValidator to defeat (spam-)bots
in forms. For this reason, the taglib saves the point in time, the form is generated and makes
this timestamp available for the validator within the session.
Setting the optional attribute seconds the minimal time can be influenced that the
validator uses to decide, whether the form was filled by a bot or a regular user. The value of the
attribute must contain an integer value of the desired period of time.
APF-Template
<html:form name="...">
<form:timecaptcha name="timecaptcha" [seconds="3"]/>
...
</html:form>
In the previous versions of the APF the validation was linked directly with a form element and
the validation was executed within the
lifecycle of the taglibs.
This has the disadvantage, that one element can be defined with only one validator. This leads to
redundant code, because each field must have it's own validator defined. Furthermore, it was not
possible to implement own validators.
From version 1.11 these circumstances were considered and the form taglibs were moved to a new
variation of the validation. From this version validators are applied by an own tag, that follows
the observer pattern.
The tag itself then binds a validator to the desired form control. Thus it is possible to attach
several validators onto one field, to write own validators and to validate several fields with one
observer definition at the same time.
The definition of a validator now is as follows:
APF-Template
<form:addvalidator
namespace=""
class=""
button=""
control=""
[type="special"]
/>
Description of the attributes:
-
namespace: Namespace of the validator implementation.
(Allowed characters:
[A-Za-z0-9:])
-
class: Name of the validator implementation (name = class name!)
(Allowed characters:
[A-Za-z0-9_])
-
button: Name of the button, that triggers the validation event. The validation
is executed, when the isSent event is fired by a button or an image button.
(Allowed characters:
[A-Za-z0-9-_])
-
control: Name of the form control to validate. In case, multiple controls should
be allocated the same validator by only one tag definition, the attribute can contain a
pipe-separated list of form controls (e.g. sender|recipient|subject).
(Allowed characters:
[A-Za-z0-9-_|])
-
type: In case the optional attribute is set to special only listeners
are notified, that contain the name (=class name) of the validator in the validator
attribute.
(Allowed characters:
special)
In case you are using shipped validators, the namespace attribute can be omitted.
The taglib therefore uses tools::form::validator as the default value. Within
this namespace, all validators described in chapter 4.1 are located there.
As in previous releases, the APF shipps a couple of built-in validators. These usually cover the
large part of the demands. Should these not be enough, own validators can be implemented. This is
described in the next chapter.
Currently the following validators are available:
The TextLengthValidator checks a text form field (text field, password field,
text area) whether the contained text has a least length. By default, the text entered by the user
must have a least length of 3 characters, before the field is considered valid. Provided that
another text length is desired, the attributes minlength and
maxlength must be given in the attribute list of the referenced text field:
APF-Template
<html:form name="...">
<form:text name="firstname" />
<form:text name="lastname" minlength="5" />
<form:password name="pass" />
<form:area name="comment" minlength="20" maxlength="200"/>
<form:button name="send" value="Send"/>
<form:addvalidator
class="TextLengthValidator"
button="send"
control="firstname|lastname|pass|comment"
/>
</html:form>
Within the code block the form control firstname is tested to contain at least >=3
characters, the lastname field must contain at least 5 characters and at maximum
200 characters to be considered valid.
Since release 1.12 it is possible to enable strict validation of the text length. To do so, you
can add the mode attribute to the target control. In case it is filled with
strict the input is filtered through trim() to accept content that does not
only contain blanks.
The
NumberValidator checks whether a text field contains a valid number. For this reason,
the PHP function
is_numeric() is used.
APF-Template
<html:form name="...">
<form:text name="number" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="NumberValidator"
button="send"
control="number"
/>
</html:form>
The
EMailValidator checks whether the referenced form control contains a valid
email address. For this reason, the content of the text field is checked against a regular expression.
APF-Template
<html:form name="...">
<form:text name="email" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="EMailValidator"
button="send"
control="email"
/>
</html:form>
The
PhoneAndFaxValidator checks whether a form field contains a valid phone or
fax number. For this reason, the content of the text field is checked against a regular expression.
APF-Template
<html:form name="...">
<form:text name="phone" />
<form:text name="fax" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="PhoneAndFaxValidator"
button="send"
control="phone|fax"
/>
</html:form>
With the
FieldCompareValidator you are enabled to compare the content of two text
fields. If the content of both controls is equal, the fields ara makred valid.
Due to the fact, that an APF form validator must be added to one dedicated control (due to observer
implementation), the main control must define the reference on the control, that can be used to
double check the content. For this reason, the
ref attribute within the main
control definition must refer to the field, that is defined for the comparison check.
APF-Template
<html:form name="...">
<form:password name="pass" ref="pass2" />
<form:password name="pass2" />
<form:addvalidator
class="FieldCompareValidator"
control="pass"
button="login"
/>
<form:button name="login" value="login" />
</html:form>
The
SimpleBirthdayValidator is also belonging to the group of text field validators
and checks the content of a text field to contain a date definition that matches the pattern
dd.MM.YYYY.
This validator can only be used with "normal" text fields. In case you intend to
validate a date control, the
SimpleDateControlValidator
must be used or you must implement a custom validator as desired.
APF-Template
<html:form name="...">
<form:text name="birthday" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleBirthdayValidator"
button="send"
control="birthday"
/>
</html:form>
The
DefaultSelectFieldValidator can be added to select fields. It checks, if the
selected content is not empty (=no option selected). Please note, that this validator may only be
used with select fields, that are defined statically (with an explicit set of options). To validate
dynamic select fields, please use the
SimpleSelectControlValidator.
APF-Template
<html:form name="...">
<form:select name="color">
<select:option value=""></select:option>
<select:option value="red">Red color</select:option>
<select:option value="green">Green color</select:option>
</form:select>
<form:button name="send" value="Send"/>
<form:addvalidator
class="DefaultSelectFieldValidator"
button="send"
control="color"
/>
</html:form>
The
SimpleSelectControlValidator validates static and dynamic text fields (=options
are filled within a document controller). The validator checks, if the selected content is not
empty.
APF-Template
<html:form name="...">
<form:select name="color">
<select:option value=""></select:option>
<select:option value="red">Red color</select:option>
<select:option value="green">Green color</select:option>
</form:select>
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleSelectControlValidator"
button="send"
control="color"
/>
</html:form>
The
MultiSelectFieldValidator is the pendant to the
SimpleSelectControlValidator but validates multi select fields. It checks the
target element to have at least one option selected.
APF-Template
<html:form name="...">
<form:multiselect name="colors">
<select:option value="red">Red color</select:option>
<select:option value="green">Green color</select:option>
</form:multiselect>
<form:button name="send" value="Send"/>
<form:addvalidator
class="MultiSelectFieldValidator"
button="send"
control="colors"
/>
</html:form>
Using the
SimpleRadioControlValidator, a radio button as well as a radio button
group can be checked. The validator thus expects, that at one button out of a group is selected. The
validator can be used for static and dynamic form definitions.
APF-Template
<html:form name="...">
<form:radio id="red" name="color" /> Red color
<form:radio id="green" name="color" /> Green color
<form:radio id="blue" name="color" /> Blue color
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleRadioControlValidator"
button="send"
control="color"
/>
</html:form>
The
SimpleDateControlValidator validates the date control described in chapter
3.14. It requires the date to be greater or equal to today's date..
APF-Template
<html:form name="...">
<form:date name="birthday" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleDateControlValidator"
button="send"
control="birthday"
/>
</html:form>
The MimeTypeValidator checks, whether the MIME type of the uploaded file can be
found in the list of accepted file types. This list must be defines within a pipe-separated list
in the accepts attribute of the form control to validate.
The evaluation of the file type is done using the finfo starting at PHP 5.3.
For older versions, the type offset of the $_FILES is used (please refer to
$_FILES
in the PHP manual).
The differences in evaluating the file type of the uploaded file are relevant for the definition
of the list of allowed media types. As of PHP 5.3, the accepted file types can be defined using
the MIME type notation (e.g. application/pdf) in previous versions only the file
extension can be added (e.g. pdf).
The subsequently defined form accepts only PDF files in the upload field. The form is makred as
invalid as long as the uploaded file matches the accepted file format:
APF-Template
<html:form name="upload" method="post">
<fieldset>
<label for="pdf">PDF file:</label>
<form:file name="pdf" id="pdf" accepts="pdf|application/pdf" />
<form:addvalidator
class="MimeTypeValidator"
control="pdf"
button="send"
/>
<form:button name="send" value="GO" />
</fieldset>
</html:form>
For compatibility reasons, the accepts attribute contains both the MIME type notation
and the file extension. This makes an upgrade to PHP 5.3 more easy, because the functionality is
still given after an upgrade.
The FileSizeValidator checks the file size of the uploaded file. For this reason,
the optional attributes minsize And maxsize can be used to define the allowed
file size in in bytes.
In case the attribute minsize is not defined in the target control's attribute list,
0 is taken as defaukt value. This let's the form accept 0 byte files as valid files. In
case the maxsize attribute is not defined in the target control's attribute list, a
maximum size of 1024000 (=1 MB) is assumed.
The following upload field only allows files with at least 20kB and a maximum size of
500kB:
APF-Template
<html:form name="upload" method="post">
<fieldset>
<label for="image">Image:</label>
<form:file name="image" id="image" minsize="20480" maxsize="512000" />
<form:addvalidator
class="FileSizeValidator"
control="image"
button="send"
/>
<form:button name="send" value="GO" />
</fieldset>
</html:form>
The CheckboxValidator validates if a checkbox is activated of not. In case it is
not activated, the control is marked as invalid.
APF-Template
<html:form name="upload" method="post">
<fieldset>
...
<form:checkbox name="agb" value="agb" /> Accepting terms of conditions.
<form:addvalidator
class="CheckboxValidator"
button="send"
control="agb"
/>
<form:button name="send" value="GO" />
</fieldset>
</html:form>
The TimeCaptchaValidator can be used in combination with the
<form:timecaptcha /> taglib to defeat (spam-)bots
in forms. The validator checks the time, which the "user" took to complete the form. Bots
normally only need a fraction of a second, so it should be enough to refuse all data which was
filled within the default 2 seconds. This period can be influenced by adding an optional
seconds attribute in the taglib definition.
APF-Template
<html:form name="...">
<form:timecaptcha name="timecaptcha"/>
<form:addvalidator
class="TimeCaptchaValidator"
button="send"
control="timecaptcha"
/>
<form:button name="send" value="Send"/>
</html:form>
Validators are classes, that are derived from
AbstractFormValidator. This abstract
base class defines the structure of all form validators. This is necessary to be able to apply all
validators to form controls as an observer.
The interface is as follows:
PHP-Code
abstract class AbstractFormValidator extends APFObject {
protected $__Control;
protected $__Button;
public function AbstractFormValidator(form_control &$control,form_control &$button){
$this->__Control = &$control;
$this->__Button = &$button;
}
public abstract function validate($input);
public abstract function notify();
public function isActive(){
return $this->__Button->isSent();
}
}
The constructor takes the control to validate and the button that triggers the element as arguments.
The
validate() method is applied the content to check against the logic the
validator includes. The return param is expected to be of type boolean indicating successful
validation (
true) of failure (
false).
The method
notify() is called, when a form control could not be validated
successfully. It is intended to add css formatting to the desired form control, to fill place holders
or to apply changes to the DOM tree. In common, within this function the form fields are maked as
invalid using css style definitions and the listeners are notified.
The class members
$__Control and
$__Button contain the instance
of the form control to validate and the button, that is used as a trigger for the validation event.
Thus, these can easily be used within the validation code.
To be able to add a validator as an observer to a form control, the form control, must support this
operation. For this reason, each form element must implement the
addValidator()
function. The signature of this method is defined within
form_control:
PHP-Code
public function addValidator(AbstractFormValidator &$validator){
if($validator->isActive()){
if(!$validator->validate($this->getAttribute('value'))){
$validator->notify();
}
}
}
As the code snippet describes, the method takes an instance of the validator as an argument. In case,
the validator is active (=button is clicked) the validator is executed and on failure, the
notify() methode is called.
Further, the validator
by default is passed the
value of the tag, what is
only legal for text fields. Thus, non-text fields re-implement the method to pass the right content
to the validator.
As mentioned in the last chapters, a validator must inherit from the
AbstractFormValidator class. Besides, the APF includes two more base classes, that
can be used to implement text field or select box validators:
- TextFieldValidator: Base class for all text field validators
- SelectFieldValidator: Base class for all select box validators
These include the functionality to mark the desired form elements as invalid and notify the
validation event listeners.
In order to implement custom validators, please remember the following topics:
- Each validator must inherit from the AbstractFormValidator class.
-
The method markAsInvalid() can be used to mark a form element as invalid.
-
Using the notifyValidationListeners() method, listeners of the applied
form control can be notified.
-
Using the button's isSent() method, you can decide, whether the form was
sent or not.
In the previous versions of the APF the filters were linked directly with a form element and
executed within the
lifecycle of the taglibs.
This has the disadvantage, that one element can be defined with only one filter. This leads to
redundant code, because each field must have it's own filter defined.
From version 1.11 these circumstances were considered and the form taglibs were moved to a new
variation of the filter facility. Thus, filters can be added as observers just like form validators
can be defined.
Filtering of form elements is executed before validation to avoid positive
validation due to removed characters during filtering. This is especially relevant for the
TextLengthValidator.
The definition of a filter now is as follows:
APF-Template
<form:addfilter
namespace=""
class=""
button=""
control=""
/>
Description of the attributes:
-
namespace: Namespace of the tilter implementation.
(Allowed characters:
[A-Za-z0-9:])
-
class: Name of the tilter implementation (name = class name!)
(Allowed characters:
[A-Za-z0-9_])
-
button: Name of the button, that triggers the filter event. Filtering is
executed, when the isSent event is fired by a button or an image button.
(Allowed characters:
[A-Za-z0-9-_])
-
control: Name of the form control to filter. In case, multiple controls
should be allocated the same filter by only one tag definition, the attribute can contain a
pipe-separated list of form controls (e.g. sender|recipient|subject).
(Allowed characters:
[A-Za-z0-9-_|])
In case you are using shipped validators, the namespace attribute can be omitted.
The taglib therefore uses tools::form::filter as the default value. Within this
namespace, all validators described in chapter 5.1 are located there.
As in previous releases, the APF shipps a couple of built-in filters. These usually cover the large
part of the demands. Should these not be enough, own filters can be implemented. This is described
in the next chapter.
Currently the following filters are available:
The
EMailFilter removes all characters, that must not be contained in a valid email
address.
APF-Template
<html:form name="...">
<form:text name="email" />
<form:button name="send" value="Send"/>
<form:addfilter
class="EMailFilter"
button="send"
control="email"
/>
</html:form>
The
NoSpecialCharactersFilter filters all characters, that to not comply with the
regexp
[^0-9A-Za-z-_\.& ].
APF-Template
<html:form name="...">
<form:text name="simplechars" />
<form:button name="send" value="Send"/>
<form:addfilter
class="NoSpecialCharactersFilter"
button="send"
control="simplechars"
/>
</html:form>
Using the
OnlyHTMLEntitiesFilter you can encode all special characters into their
HTML entity. Please note, that this filter may generate multiple encoding.
APF-Template
<html:form name="...">
<form:text name="htmlentitiestext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyHTMLEntitiesFilter"
button="send"
control="htmlentitiestext"
/>
</html:form>
The
OnlyIntegersFilter only returns the numbers contained in the given text.
APF-Template
<html:form name="...">
<form:text name="zipcode" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyIntegersFilter"
button="send"
control="zipcode"
/>
</html:form>
The
OnlyLettersFilter removes all signs except normal characters.
APF-Template
<html:form name="...">
<form:text name="productcode" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyLettersFilter"
button="send"
control="productcode"
/>
</html:form>
The
OnlyNumbersFilter only allows numbers and formatting signs such as dots or
commas.
APF-Template
<html:form name="...">
<form:text name="productprice" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyNumbersFilter"
button="send"
control="productprice"
/>
</html:form>
The
SpecialCharacterFilter filters all signs except normal characters and signs that
are needed for normal sentences.
APF-Template
<html:form name="...">
<form:area name="simpletext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="SpecialCharacterFilter"
button="send"
control="simpletext"
/>
</html:form>
The
String2LowerFilter converts all characters to lowercase letters.
APF-Template
<html:form name="...">
<form:area name="lowertext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="String2LowerFilter"
button="send"
control="lowertext"
/>
</html:form>
The
String2UpperFilter converts all characters to uppercase letters.
APF-Template
<html:form name="...">
<form:area name="uppertext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="String2LowerFilter"
button="send"
control="uppertext"
/>
</html:form>
Using the
StripTagsFilter all HTML and PHP code fragments are filtered out. This
is especially good for text areas.
APF-Template
<html:form name="...">
<form:area name="notagstext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="StripTagsFilter"
button="send"
control="notagstext"
/>
</html:form>
Form filters are special filters, that are built on the APF filter API described in detail in chapter
design and function of filters.
Each form filter must implement the
AbstractFormFilter class that acts as an
interface for dedicated form filter implementations.
Just like the form validators, form filters must implement some form-specific methods. The
AbstractFormFilter interface class is as follows:
PHP-Code
abstract class AbstractFormFilter extends AbstractFilter {
protected $__Control;
protected $__Button;
public function AbstractFormFilter(form_control &$control,form_control &$button){
$this->__Control = &$control;
$this->__Button = &$button;
}
public function isActive(){
return $this->__Button->isSent();
}
}
The constructor takes the control to filter and the button that triggers the element as arguments.
The
filter() method is applied the content to filter included in the method. The
return param is expected to be the filtered content.
isActive() returns
true in case the filter should be executed and
false otherwise.
The class members
$__Control and
$__Button contain the instance of
the form control to filter and the button, that is used as a trigger for the validation event. Thus,
these can easily be used within the filter code.
To be able to add a filter as an observer to a form control, the form control, must support this
operation. For this reason, each form element must implement the
addFilter()
function. The signature of the method defined within the
form_control class is as
follows:
PHP-Code
public function addFilter(AbstractFormFilter &$filter){
if($filter->isActive()){
$value = $this->getAttribute('value');
$filteredValue = $filter->filter($value);
$this->setAttribute('value',$filteredValue);
}
}
As the code snippet describes, the method takes an instance of the filter as an argument. In case,
the filter is active (=button is clicked) the filter is executed.
Further, the filter is passed the content of the
value attribute of the form control
by default. Thus, non-text fields re-implement the method to pass the right content to the
filter.
Filters are usually applied on text fields. It is not recommended to apply filters to complex
data structures and in case of select fields it may not be necessary at all. There, the content
of the fields are filled by the application itself. Hence, the APF does not ship select field
filters.
As mentioned in the last chapters, a filter must inherit from the
AbstractFormFilter
class.
In order to implement custom filters, please remember the following topics:
-
Each filter must inherit from the AbstractFormFilter class to be compatible
with the APF filter API.
-
The isSent() method can be used to query the click status of a given button
within the desired form.
-
The isActive() can be used to check, whether a filter is active or not. In
most cases, the implementation defined within the AbstractFormFilter can be
used without adaption.
Due to the fact, that with PHP >=5.2.10 and >=5.3.0 respectively, the signatures of abstract
methods must be exactly equal to their implementations. Thus, please ensure, that the filter
classes have a method public function filter($input) defined as printed here literally!
Chapter
usage of forms deals with
the usage of APF forms and the form handling using document controller. The present page is only
intended as a reference for the shipped tags and the implementation of validators and filters.
Further, the linked chapter discusses dynamic form implementation.
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.