1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.form.elements">
4 <title>Creating Form Elements Using Zend_Form_Element</title>
7 A form is made of elements that typically correspond to HTML form
8 input. <classname>Zend_Form_Element</classname> encapsulates single form elements, with the
9 following areas of responsibility:
15 validation (is submitted data valid?)
19 <listitem><para>capturing of validation error codes and messages</para></listitem>
25 filtering (how is the element escaped or normalized prior to
26 validation and/or for output?)
31 <para>rendering (how is the element displayed?)</para>
35 <para>metadata and attributes (what information further qualifies the element?)</para>
40 The base class, <classname>Zend_Form_Element</classname>, has reasonable defaults
41 for many cases, but it is best to extend the class for commonly used
42 special purpose elements. Additionally, Zend Framework ships with a
43 number of standard <acronym>XHTML</acronym> elements; you can read about them <link
44 linkend="zend.form.standardElements">in the Standard Elements
48 <sect2 id="zend.form.elements.loaders">
49 <title>Plugin Loaders</title>
52 <classname>Zend_Form_Element</classname> makes use of <link
53 linkend="zend.loader.pluginloader">Zend_Loader_PluginLoader</link>
54 to allow developers to specify locations of alternate validators,
55 filters, and decorators. Each has its own plugin loader associated
56 with it, and general accessors are used to retrieve and modify
61 The following loader types are used with the various plugin loader
62 methods: 'validate', 'filter', and 'decorator'. The type names are
67 The methods used to interact with plugin loaders are as follows:
73 <methodname>setPluginLoader($loader, $type)</methodname>:
74 <varname>$loader</varname> is the plugin loader object itself, while
75 <varname>$type</varname> is one of the types specified above. This
76 sets the plugin loader for the given type to the newly
77 specified loader object.
83 <methodname>getPluginLoader($type)</methodname>: retrieves the plugin
84 loader associated with <varname>$type</varname>.
90 <methodname>addPrefixPath($prefix, $path, $type = null)</methodname>: adds
91 a prefix/path association to the loader specified by
92 <varname>$type</varname>. If <varname>$type</varname> is
93 <constant>NULL</constant>, it will attempt to add the path to all loaders, by
94 appending the prefix with each of "_Validate", "_Filter", and "_Decorator"; and
95 appending the path with "Validate/", "Filter/", and
96 "Decorator/". If you have all your extra form element classes
97 under a common hierarchy, this is a convenience method for
98 setting the base prefix for them.
104 <methodname>addPrefixPaths(array $spec)</methodname>: allows you to add
105 many paths at once to one or more plugin loaders. It expects
106 each array item to be an array with the keys 'path', 'prefix',
113 Custom validators, filters, and decorators are an easy way to share
114 functionality between forms and to encapsulate custom functionality.
117 <example id="zend.form.elements.loaders.customLabel">
118 <title>Custom Label</title>
121 One common use case for plugins is to provide replacements for
122 standard classes. For instance, if you want to provide a
123 different implementation of the 'Label' decorator -- for
124 instance, to always append a colon -- you could create your own
125 'Label' decorator with your own class prefix, and then add it to
130 Let's start with a custom Label decorator. We'll give it the
131 class prefix "My_Decorator", and the class itself will be in the
132 file "My/Decorator/Label.php".
135 <programlisting language="php"><![CDATA[
136 class My_Decorator_Label extends Zend_Form_Decorator_Abstract
138 protected $_placement = 'PREPEND';
140 public function render($content)
142 if (null === ($element = $this->getElement())) {
145 if (!method_exists($element, 'getLabel')) {
149 $label = $element->getLabel() . ':';
151 if (null === ($view = $element->getView())) {
152 return $this->renderLabel($content, $label);
155 $label = $view->formLabel($element->getName(), $label);
157 return $this->renderLabel($content, $label);
160 public function renderLabel($content, $label)
162 $placement = $this->getPlacement();
163 $separator = $this->getSeparator();
165 switch ($placement) {
167 return $content . $separator . $label;
170 return $label . $separator . $content;
177 Now we can tell the element to use this plugin path when looking
181 <programlisting language="php"><![CDATA[
182 $element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
186 Alternately, we can do that at the form level to ensure all
187 decorators use this path:
190 <programlisting language="php"><![CDATA[
191 $form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
195 After it added as in the example above, the 'My/Decorator/' path will be searched
196 first to see if the decorator exists there when you add a decorator. As a result,
197 'My_Decorator_Label' will now be used when the 'Label' decorator is requested.
202 <sect2 id="zend.form.elements.filters">
203 <title>Filters</title>
206 It's often useful and/or necessary to perform some normalization on
207 input prior to validation. For example, you may want to strip out
208 all HTML, but run your validations on what remains to ensure the
209 submission is valid. Or you may want to trim empty space surrounding input so that a
210 StringLength validator will use the correct length of the input without counting leading
211 or trailing whitespace characters. These operations may be performed using
212 <classname>Zend_Filter</classname>. <classname>Zend_Form_Element</classname> has support
213 for filter chains, allowing you to specify multiple, sequential filters. Filtering
214 happens both during validation and when you retrieve the element value via
215 <methodname>getValue()</methodname>:
218 <programlisting language="php"><![CDATA[
219 $filtered = $element->getValue();
223 Filters may be added to the chain in two ways:
229 passing in a concrete filter instance
235 providing a filter name – either a short name or fully
242 Let's see some examples:
245 <programlisting language="php"><![CDATA[
246 // Concrete filter instance:
247 $element->addFilter(new Zend_Filter_Alnum());
249 // Fully qualified class name:
250 $element->addFilter('Zend_Filter_Alnum');
252 // Short filter name:
253 $element->addFilter('Alnum');
254 $element->addFilter('alnum');
258 Short names are typically the filter name minus the prefix. In the
259 default case, this will mean minus the 'Zend_Filter_' prefix.
260 The first letter can be upper-cased or lower-cased.
264 <title>Using Custom Filter Classes</title>
267 If you have your own set of filter classes, you can tell
268 <classname>Zend_Form_Element</classname> about these using
269 <methodname>addPrefixPath()</methodname>. For instance, if you have
270 filters under the 'My_Filter' prefix, you can tell
271 <classname>Zend_Form_Element</classname> about this as follows:
274 <programlisting language="php"><![CDATA[
275 $element->addPrefixPath('My_Filter', 'My/Filter/', 'filter');
279 (Recall that the third argument indicates which plugin loader
280 on which to perform the action.)
285 If at any time you need the unfiltered value, use the
286 <methodname>getUnfilteredValue()</methodname> method:
289 <programlisting language="php"><![CDATA[
290 $unfiltered = $element->getUnfilteredValue();
294 For more information on filters, see the <link
295 linkend="zend.filter.introduction">Zend_Filter
296 documentation</link>.
300 Methods associated with filters include:
306 <methodname>addFilter($nameOfFilter, array $options = null)</methodname>
312 <methodname>addFilters(array $filters)</methodname>
318 <methodname>setFilters(array $filters)</methodname> (overwrites all filters)
324 <methodname>getFilter($name)</methodname> (retrieve a filter object by name)
330 <methodname>getFilters()</methodname> (retrieve all filters)
336 <methodname>removeFilter($name)</methodname> (remove filter by name)
342 <methodname>clearFilters()</methodname> (remove all filters)
348 <sect2 id="zend.form.elements.validators">
349 <title>Validators</title>
352 If you subscribe to the security mantra of "filter input, escape
353 output," you'll should use validator to filter input submitted with your form.
354 In <classname>Zend_Form</classname>, each element includes its own validator
355 chain, consisting of <classname>Zend_Validate_*</classname> validators.
359 Validators may be added to the chain in two ways:
365 passing in a concrete validator instance
371 providing a validator name – either a short name or fully
378 Let's see some examples:
381 <programlisting language="php"><![CDATA[
382 // Concrete validator instance:
383 $element->addValidator(new Zend_Validate_Alnum());
385 // Fully qualified class name:
386 $element->addValidator('Zend_Validate_Alnum');
388 // Short validator name:
389 $element->addValidator('Alnum');
390 $element->addValidator('alnum');
394 Short names are typically the validator name minus the prefix. In
395 the default case, this will mean minus the 'Zend_Validate_' prefix.
396 As is the case with filters, the first letter can be upper-cased or lower-cased.
400 <title>Using Custom Validator Classes</title>
403 If you have your own set of validator classes, you can tell
404 <classname>Zend_Form_Element</classname> about these using
405 <methodname>addPrefixPath()</methodname>. For instance, if you have
406 validators under the 'My_Validator' prefix, you can tell
407 <classname>Zend_Form_Element</classname> about this as follows:
410 <programlisting language="php"><![CDATA[
411 $element->addPrefixPath('My_Validator', 'My/Validator/', 'validate');
415 (Recall that the third argument indicates which plugin loader
416 on which to perform the action.)
421 If failing a particular validation should prevent later validators
422 from firing, pass boolean <constant>TRUE</constant> as the second parameter:
425 <programlisting language="php"><![CDATA[
426 $element->addValidator('alnum', true);
430 If you are using a string name to add a validator, and the
431 validator class accepts arguments to the constructor, you may pass
432 these to the third parameter of <methodname>addValidator()</methodname> as an
436 <programlisting language="php"><![CDATA[
437 $element->addValidator('StringLength', false, array(6, 20));
441 Arguments passed in this way should be in the order in which they
442 are defined in the constructor. The above example will instantiate
443 the <classname>Zend_Validate_StringLenth</classname> class with its
444 <varname>$min</varname> and <varname>$max</varname> parameters:
447 <programlisting language="php"><![CDATA[
448 $validator = new Zend_Validate_StringLength(6, 20);
452 <title>Providing Custom Validator Error Messages</title>
455 Some developers may wish to provide custom error messages for a
456 validator. The <varname>$options</varname> argument of the
457 <methodname>Zend_Form_Element::addValidator()</methodname> method allows you to do
458 so by providing the key 'messages' and mapping it to an array of key/value pairs
459 for setting the message templates. You will need to know the
460 error codes of the various validation error types for the
461 particular validator.
465 A better option is to use a <classname>Zend_Translate_Adapter</classname>
466 with your form. Error codes are automatically passed to the
467 adapter by the default Errors decorator; you can then specify
468 your own error message strings by setting up translations for
469 the various error codes of your validators.
474 You can also set many validators at once, using
475 <methodname>addValidators()</methodname>. The basic usage is to pass an array
476 of arrays, with each array containing 1 to 3 values, matching the
477 constructor of <methodname>addValidator()</methodname>:
480 <programlisting language="php"><![CDATA[
481 $element->addValidators(array(
482 array('NotEmpty', true),
484 array('stringLength', false, array(6, 20)),
489 If you want to be more verbose or explicit, you can use the array
490 keys 'validator', 'breakChainOnFailure', and 'options':
493 <programlisting language="php"><![CDATA[
494 $element->addValidators(array(
496 'validator' => 'NotEmpty',
497 'breakChainOnFailure' => true),
498 array('validator' => 'alnum'),
500 'validator' => 'stringLength',
501 'options' => array(6, 20)),
506 This usage is good for illustrating how you could then configure
507 validators in a config file:
510 <programlisting language="ini"><![CDATA[
511 element.validators.notempty.validator = "NotEmpty"
512 element.validators.notempty.breakChainOnFailure = true
513 element.validators.alnum.validator = "Alnum"
514 element.validators.strlen.validator = "StringLength"
515 element.validators.strlen.options.min = 6
516 element.validators.strlen.options.max = 20
520 Notice that every item has a key, whether or not it needs one; this
521 is a limitation of using configuration files -- but it also helps
522 make explicit what the arguments are for. Just remember that any
523 validator options must be specified in order.
527 To validate an element, pass the value to
528 <methodname>isValid()</methodname>:
531 <programlisting language="php"><![CDATA[
532 if ($element->isValid($value)) {
540 <title>Validation Operates On Filtered Values</title>
543 <methodname>Zend_Form_Element::isValid()</methodname> filters values through
544 the provided filter chain prior to validation. See <link
545 linkend="zend.form.elements.filters">the Filters
546 section</link> for more information.
551 <title>Validation Context</title>
554 <methodname>Zend_Form_Element::isValid()</methodname> supports an
555 additional argument, <varname>$context</varname>.
556 <methodname>Zend_Form::isValid()</methodname> passes the entire array of
557 data being processed to <varname>$context</varname> when validating a
558 form, and <methodname>Zend_Form_Element::isValid()</methodname>, in turn,
559 passes it to each validator. This means you can write
560 validators that are aware of data passed to other form
561 elements. As an example, consider a standard registration form
562 that has fields for both password and a password confirmation;
563 one validation would be that the two fields match. Such a
564 validator might look like the following:
567 <programlisting language="php"><![CDATA[
568 class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
570 const NOT_MATCH = 'notMatch';
572 protected $_messageTemplates = array(
573 self::NOT_MATCH => 'Password confirmation does not match'
576 public function isValid($value, $context = null)
578 $value = (string) $value;
579 $this->_setValue($value);
581 if (is_array($context)) {
582 if (isset($context['password_confirm'])
583 && ($value == $context['password_confirm']))
587 } elseif (is_string($context) && ($value == $context)) {
591 $this->_error(self::NOT_MATCH);
599 Validators are processed in order. Each validator is processed,
600 unless a validator created with a <constant>TRUE</constant>
601 <varname>$breakChainOnFailure</varname> value fails its validation. Be
602 sure to specify your validators in a reasonable order.
606 After a failed validation, you can retrieve the error codes and
607 messages from the validator chain:
610 <programlisting language="php"><![CDATA[
611 $errors = $element->getErrors();
612 $messages = $element->getMessages();
616 (Note: error messages returned are an associative array of error
617 code / error message pairs.)
621 In addition to validators, you can specify that an element is
622 required, using <methodname>setRequired(true)</methodname>. By default, this
623 flag is <constant>FALSE</constant>, meaning that your validator chain will be skipped if
624 no value is passed to <methodname>isValid()</methodname>. You can modify this
625 behavior in a number of ways:
631 By default, when an element is required, a flag,
632 'allowEmpty', is also <constant>TRUE</constant>. This means that if a value
633 evaluating to empty is passed to <methodname>isValid()</methodname>, the
634 validators will be skipped. You can toggle this flag using
635 the accessor <methodname>setAllowEmpty($flag)</methodname>; when the
636 flag is <constant>FALSE</constant> and a value is passed, the validators
643 By default, if an element is required but does not contain
644 a 'NotEmpty' validator, <methodname>isValid()</methodname> will add one
645 to the top of the stack, with the
646 <varname>$breakChainOnFailure</varname> flag set. This behavior lends
647 required flag semantic meaning: if no value is passed,
648 we immediately invalidate the submission and notify the
649 user, and prevent other validators from running on what we
650 already know is invalid data.
654 If you do not want this behavior, you can turn it off by
655 passing a <constant>FALSE</constant> value to
656 <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>; this
657 will prevent <methodname>isValid()</methodname> from placing the
658 'NotEmpty' validator in the validator chain.
664 For more information on validators, see the <link
665 linkend="zend.validate.introduction">Zend_Validate
666 documentation</link>.
670 <title>Using Zend_Form_Elements as general-purpose validators</title>
673 <classname>Zend_Form_Element</classname> implements
674 <classname>Zend_Validate_Interface</classname>, meaning an element may
675 also be used as a validator in other, non-form related
681 <title>When is an element detected as empty?</title>
684 As mentioned the 'NotEmpty' validator is used to detect if an element is empty
685 or not. But <classname>Zend_Validate_NotEmpty</classname> does, per default, not
686 work like <acronym>PHP</acronym>'s method <methodname>empty()</methodname>.
690 This means when an element contains an integer <emphasis>0</emphasis> or an string
691 <emphasis>'0'</emphasis> then the element will be seen as not empty. If you want to
692 have a different behaviour you must create your own instance of
693 <classname>Zend_Validate_NotEmpty</classname>. There you can define the behaviour of
694 this validator. See <ulink
695 url="zend.validate.set.notempty">Zend_Validate_NotEmpty</ulink> for details.
700 Methods associated with validation include:
706 <methodname>setRequired($flag)</methodname> and
707 <methodname>isRequired()</methodname> allow you to set and retrieve the
708 status of the 'required' flag. When set to boolean <constant>TRUE</constant>,
709 this flag requires that the element be in the data processed by
710 <classname>Zend_Form</classname>.
716 <methodname>setAllowEmpty($flag)</methodname> and
717 <methodname>getAllowEmpty()</methodname> allow you to modify the
718 behaviour of optional elements (i.e., elements where the
719 required flag is <constant>FALSE</constant>). When the 'allow empty' flag is
720 <constant>TRUE</constant>, empty values will not be passed to the validator
727 <methodname>setAutoInsertNotEmptyValidator($flag)</methodname> allows
728 you to specify whether or not a 'NotEmpty' validator will be
729 prepended to the validator chain when the element is
730 required. By default, this flag is <constant>TRUE</constant>.
736 <methodname>addValidator($nameOrValidator, $breakChainOnFailure = false, array
737 $options = null)</methodname>
743 <methodname>addValidators(array $validators)</methodname>
749 <methodname>setValidators(array $validators)</methodname> (overwrites all
756 <methodname>getValidator($name)</methodname> (retrieve a validator object by
763 <methodname>getValidators()</methodname> (retrieve all validators)
769 <methodname>removeValidator($name)</methodname> (remove validator by name)
775 <methodname>clearValidators()</methodname> (remove all validators)
780 <sect3 id="zend.form.elements.validators.errors">
781 <title>Custom Error Messages</title>
784 At times, you may want to specify one or more specific error
785 messages to use instead of the error messages generated by the
786 validators attached to your element. Additionally, at times you
787 may want to mark the element invalid yourself. As of 1.6.0, this
788 functionality is possible via the following methods.
794 <methodname>addErrorMessage($message)</methodname>: add an error message
795 to display on form validation errors. You may call this more
796 than once, and new messages are appended to the stack.
802 <methodname>addErrorMessages(array $messages)</methodname>: add multiple
803 error messages to display on form validation errors.
809 <methodname>setErrorMessages(array $messages)</methodname>: add multiple
810 error messages to display on form validation errors,
811 overwriting all previously set error messages.
817 <methodname>getErrorMessages()</methodname>: retrieve the list of
818 custom error messages that have been defined.
824 <methodname>clearErrorMessages()</methodname>: remove all custom error
825 messages that have been defined.
831 <methodname>markAsError()</methodname>: mark the element as having
838 <methodname>hasErrors()</methodname>: determine whether the element has
839 either failed validation or been marked as invalid.
845 <methodname>addError($message)</methodname>: add a message to the custom
846 error messages stack and flag the element as invalid.
852 <methodname>addErrors(array $messages)</methodname>: add several
853 messages to the custom error messages stack and flag the
860 <methodname>setErrors(array $messages)</methodname>: overwrite the
861 custom error messages stack with the provided messages and
862 flag the element as invalid.
868 All errors set in this fashion may be translated. Additionally,
869 you may insert the placeholder "%value%" to represent the
870 element value; this current element value will be substituted
871 when the error messages are retrieved.
876 <sect2 id="zend.form.elements.decorators">
877 <title>Decorators</title>
880 One particular pain point for many web developers is the creation
881 of the <acronym>XHTML</acronym> forms themselves. For each element, the developer
882 needs to create markup for the element itself (typically a label)
883 and special markup for displaying
884 validation error messages. The more elements on the page, the less
885 trivial this task becomes.
889 <classname>Zend_Form_Element</classname> tries to solve this issue through
890 the use of "decorators". Decorators are simply classes that have
891 access to the element and a method for rendering content. For more
892 information on how decorators work, please see the section on <link
893 linkend="zend.form.decorators">Zend_Form_Decorator</link>.
897 The default decorators used by <classname>Zend_Form_Element</classname> are:
903 <emphasis>ViewHelper</emphasis>: specifies a view helper to use
904 to render the element. The 'helper' element attribute can be
905 used to specify which view helper to use. By default,
906 <classname>Zend_Form_Element</classname> specifies the 'formText' view
907 helper, but individual subclasses specify different helpers.
913 <emphasis>Errors</emphasis>: appends error messages to the
914 element using <classname>Zend_View_Helper_FormErrors</classname>. If none are
915 present, nothing is appended.
921 <emphasis>Description</emphasis>: appends the element
922 description. If none is present, nothing is appended. By
923 default, the description is rendered in a <p> tag with a
924 class of 'description'.
930 <emphasis>HtmlTag</emphasis>: wraps the element and errors in
931 an HTML <dd> tag.
937 <emphasis>Label</emphasis>: prepends a label to the element
938 using <classname>Zend_View_Helper_FormLabel</classname>, and wraps it in a
939 <dt> tag. If no label is provided, just the definition term tag is
946 <title>Default Decorators Do Not Need to Be Loaded</title>
949 By default, the default decorators are loaded during object
950 initialization. You can disable this by passing the
951 'disableLoadDefaultDecorators' option to the constructor:
954 <programlisting language="php"><![CDATA[
955 $element = new Zend_Form_Element('foo',
956 array('disableLoadDefaultDecorators' =>
962 This option may be mixed with any other options you pass,
963 both as array options or in a <classname>Zend_Config</classname> object.
968 Since the order in which decorators are registered matters- the first
969 decorator registered is executed first- you will need to make
970 sure you register your decorators in an appropriate order, or
971 ensure that you set the placement options in a sane fashion. To
972 give an example, here is the code that registers the default
976 <programlisting language="php"><![CDATA[
977 $this->addDecorators(array(
980 array('Description', array('tag' => 'p', 'class' => 'description')),
981 array('HtmlTag', array('tag' => 'dd')),
982 array('Label', array('tag' => 'dt')),
987 The initial content is created by the 'ViewHelper' decorator, which
988 creates the form element itself. Next, the 'Errors' decorator
989 fetches error messages from the element, and, if any are present,
990 passes them to the 'FormErrors' view helper to render. If a
991 description is present, the 'Description' decorator will append a
992 paragraph of class 'description' containing the descriptive text to
993 the aggregated content. The next decorator, 'HtmlTag', wraps the
994 element, errors, and description in an HTML <dd> tag.
995 Finally, the last decorator, 'label', retrieves the element's label
996 and passes it to the 'FormLabel' view helper, wrapping it in an HTML
997 <dt> tag; the value is prepended to the content by default.
998 The resulting output looks basically like this:
1001 <programlisting language="html"><![CDATA[
1002 <dt><label for="foo" class="optional">Foo</label></dt>
1004 <input type="text" name="foo" id="foo" value="123" />
1006 <li>"123" is not an alphanumeric value</li>
1008 <p class="description">
1009 This is some descriptive text regarding the element.
1012 ]]></programlisting>
1015 For more information on decorators, read the <link
1016 linkend="zend.form.decorators">Zend_Form_Decorator section</link>.
1020 <title>Using Multiple Decorators of the Same Type</title>
1023 Internally, <classname>Zend_Form_Element</classname> uses a decorator's
1024 class as the lookup mechanism when retrieving decorators. As a
1025 result, you cannot register multiple decorators of the same
1026 type; subsequent decorators will simply overwrite those that
1031 To get around this, you can use <emphasis>aliases</emphasis>.
1032 Instead of passing a decorator or decorator name as the first
1033 argument to <methodname>addDecorator()</methodname>, pass an array with a
1034 single element, with the alias pointing to the decorator object
1038 <programlisting language="php"><![CDATA[
1039 // Alias to 'FooBar':
1040 $element->addDecorator(array('FooBar' => 'HtmlTag'),
1041 array('tag' => 'div'));
1043 // And retrieve later:
1044 $decorator = $element->getDecorator('FooBar');
1045 ]]></programlisting>
1048 In the <methodname>addDecorators()</methodname> and
1049 <methodname>setDecorators()</methodname> methods, you will need to pass
1050 the 'decorator' option in the array representing the decorator:
1053 <programlisting language="php"><![CDATA[
1054 // Add two 'HtmlTag' decorators, aliasing one to 'FooBar':
1055 $element->addDecorators(
1056 array('HtmlTag', array('tag' => 'div')),
1058 'decorator' => array('FooBar' => 'HtmlTag'),
1059 'options' => array('tag' => 'dd')
1063 // And retrieve later:
1064 $htmlTag = $element->getDecorator('HtmlTag');
1065 $fooBar = $element->getDecorator('FooBar');
1066 ]]></programlisting>
1070 Methods associated with decorators include:
1076 <methodname>addDecorator($nameOrDecorator, array $options = null)</methodname>
1082 <methodname>addDecorators(array $decorators)</methodname>
1088 <methodname>setDecorators(array $decorators)</methodname> (overwrites all
1095 <methodname>getDecorator($name)</methodname> (retrieve a decorator object by
1102 <methodname>getDecorators()</methodname> (retrieve all decorators)
1108 <methodname>removeDecorator($name)</methodname> (remove decorator by name)
1114 <methodname>clearDecorators()</methodname> (remove all decorators)
1120 <classname>Zend_Form_Element</classname> also uses overloading to allow rendering
1121 specific decorators. <methodname>__call()</methodname> will intercept methods
1122 that lead with the text 'render' and use the remainder of the method
1123 name to lookup a decorator; if found, it will then render that
1124 <emphasis>single</emphasis> decorator. Any arguments passed to the
1125 method call will be used as content to pass to the decorator's
1126 <methodname>render()</methodname> method. As an example:
1129 <programlisting language="php"><![CDATA[
1130 // Render only the ViewHelper decorator:
1131 echo $element->renderViewHelper();
1133 // Render only the HtmlTag decorator, passing in content:
1134 echo $element->renderHtmlTag("This is the html tag content");
1135 ]]></programlisting>
1138 If the decorator does not exist, an exception is raised.
1142 <sect2 id="zend.form.elements.metadata">
1143 <title>Metadata and Attributes</title>
1146 <classname>Zend_Form_Element</classname> handles a variety of attributes and
1147 element metadata. Basic attributes include:
1153 <emphasis>name</emphasis>: the element name. Uses the
1154 <methodname>setName()</methodname> and <methodname>getName()</methodname>
1161 <emphasis>label</emphasis>: the element label. Uses the
1162 <methodname>setLabel()</methodname> and <methodname>getLabel()</methodname>
1169 <emphasis>order</emphasis>: the index at which an element
1170 should appear in the form. Uses the <methodname>setOrder()</methodname> and
1171 <methodname>getOrder()</methodname> accessors.
1177 <emphasis>value</emphasis>: the current element value. Uses the
1178 <methodname>setValue()</methodname> and <methodname>getValue()</methodname>
1185 <emphasis>description</emphasis>: a description of the element;
1186 often used to provide tooltip or javascript contextual hinting
1187 describing the purpose of the element. Uses the
1188 <methodname>setDescription()</methodname> and
1189 <methodname>getDescription()</methodname> accessors.
1195 <emphasis>required</emphasis>: flag indicating whether or not
1196 the element is required when performing form validation. Uses
1197 the <methodname>setRequired()</methodname> and
1198 <methodname>getRequired()</methodname> accessors. This flag is
1199 <constant>FALSE</constant> by default.
1205 <emphasis>allowEmpty</emphasis>: flag indicating whether or not
1206 a non-required (optional) element should attempt to validate
1207 empty values. If it is set to <constant>TRUE</constant> and the required flag is
1208 <constant>FALSE</constant>, empty values are not passed to the validator chain
1209 and are presumed <constant>TRUE</constant>. Uses the
1210 <methodname>setAllowEmpty()</methodname> and
1211 <methodname>getAllowEmpty()</methodname> accessors. This flag is
1212 <constant>TRUE</constant> by default.
1218 <emphasis>autoInsertNotEmptyValidator</emphasis>: flag
1219 indicating whether or not to insert a 'NotEmpty' validator when
1220 the element is required. By default, this flag is <constant>TRUE</constant>. Set
1221 the flag with <methodname>setAutoInsertNotEmptyValidator($flag)</methodname> and
1222 determine the value with
1223 <methodname>autoInsertNotEmptyValidator()</methodname>.
1229 Form elements may require additional metadata. For <acronym>XHTML</acronym> form
1230 elements, for instance, you may want to specify attributes such as
1231 the class or id. To facilitate this are a set of accessors:
1237 <emphasis>setAttrib($name, $value)</emphasis>: add an attribute
1243 <emphasis>setAttribs(array $attribs)</emphasis>: like
1244 addAttribs(), but overwrites
1250 <emphasis>getAttrib($name)</emphasis>: retrieve a single
1257 <emphasis>getAttribs()</emphasis>: retrieve all attributes as
1264 Most of the time, however, you can simply access them as object
1265 properties, as <classname>Zend_Form_Element</classname> utilizes overloading
1266 to facilitate access to them:
1269 <programlisting language="php"><![CDATA[
1270 // Equivalent to $element->setAttrib('class', 'text'):
1271 $element->class = 'text;
1272 ]]></programlisting>
1275 By default, all attributes are passed to the view helper used by
1276 the element during rendering, and rendered as HTML attributes of
1281 <sect2 id="zend.form.elements.standard">
1282 <title>Standard Elements</title>
1285 <classname>Zend_Form</classname> ships with a number of standard elements; please read
1286 the <link linkend="zend.form.standardElements">Standard Elements</link>
1287 chapter for full details.
1291 <sect2 id="zend.form.elements.methods">
1292 <title>Zend_Form_Element Methods</title>
1295 <classname>Zend_Form_Element</classname> has many, many methods. What follows
1296 is a quick summary of their signatures, grouped by type:
1301 <para>Configuration:</para>
1305 <para><methodname>setOptions(array $options)</methodname></para>
1309 <para><methodname>setConfig(Zend_Config $config)</methodname></para>
1320 <methodname>setTranslator(Zend_Translate_Adapter $translator
1321 = null)</methodname>
1325 <listitem><para><methodname>getTranslator()</methodname></para></listitem>
1328 <para><methodname>setDisableTranslator($flag)</methodname></para>
1332 <para><methodname>translatorIsDisabled()</methodname></para>
1338 <para>Properties:</para>
1341 <listitem><para><methodname>setName($name)</methodname></para></listitem>
1342 <listitem><para><methodname>getName()</methodname></para></listitem>
1343 <listitem><para><methodname>setValue($value)</methodname></para></listitem>
1344 <listitem><para><methodname>getValue()</methodname></para></listitem>
1345 <listitem><para><methodname>getUnfilteredValue()</methodname></para></listitem>
1346 <listitem><para><methodname>setLabel($label)</methodname></para></listitem>
1347 <listitem><para><methodname>getLabel()</methodname></para></listitem>
1350 <para><methodname>setDescription($description)</methodname></para>
1353 <listitem><para><methodname>getDescription()</methodname></para></listitem>
1354 <listitem><para><methodname>setOrder($order)</methodname></para></listitem>
1355 <listitem><para><methodname>getOrder()</methodname></para></listitem>
1356 <listitem><para><methodname>setRequired($flag)</methodname></para></listitem>
1357 <listitem><para><methodname>getRequired()</methodname></para></listitem>
1358 <listitem><para><methodname>setAllowEmpty($flag)</methodname></para></listitem>
1359 <listitem><para><methodname>getAllowEmpty()</methodname></para></listitem>
1362 <para><methodname>setAutoInsertNotEmptyValidator($flag)</methodname></para>
1366 <para><methodname>autoInsertNotEmptyValidator()</methodname></para>
1369 <listitem><para><methodname>setIgnore($flag)</methodname></para></listitem>
1370 <listitem><para><methodname>getIgnore()</methodname></para></listitem>
1371 <listitem><para><methodname>getType()</methodname></para></listitem>
1374 <para><methodname>setAttrib($name, $value)</methodname></para>
1378 <para><methodname>setAttribs(array $attribs)</methodname></para>
1381 <listitem><para><methodname>getAttrib($name)</methodname></para></listitem>
1382 <listitem><para><methodname>getAttribs()</methodname></para></listitem>
1387 <para>Plugin loaders and paths:</para>
1392 <methodname>setPluginLoader(Zend_Loader_PluginLoader_Interface $loader,
1398 <para><methodname>getPluginLoader($type)</methodname></para>
1403 <methodname>addPrefixPath($prefix, $path, $type = null)</methodname>
1408 <para><methodname>addPrefixPaths(array $spec)</methodname></para>
1414 <para>Validation:</para>
1419 <methodname>addValidator($validator, $breakChainOnFailure = false,
1420 $options = array())</methodname>
1425 <para><methodname>addValidators(array $validators)</methodname></para>
1429 <para><methodname>setValidators(array $validators)</methodname></para>
1432 <listitem><para><methodname>getValidator($name)</methodname></para></listitem>
1433 <listitem><para><methodname>getValidators()</methodname></para></listitem>
1436 <para><methodname>removeValidator($name)</methodname></para>
1439 <listitem><para><methodname>clearValidators()</methodname></para></listitem>
1442 <para><methodname>isValid($value, $context = null)</methodname></para>
1445 <listitem><para><methodname>getErrors()</methodname></para></listitem>
1446 <listitem><para><methodname>getMessages()</methodname></para></listitem>
1451 <para>Filters:</para>
1455 <para><methodname>addFilter($filter, $options = array())</methodname></para>
1459 <para><methodname>addFilters(array $filters)</methodname></para>
1463 <para><methodname>setFilters(array $filters)</methodname></para>
1466 <listitem><para><methodname>getFilter($name)</methodname></para></listitem>
1467 <listitem><para><methodname>getFilters()</methodname></para></listitem>
1468 <listitem><para><methodname>removeFilter($name)</methodname></para></listitem>
1469 <listitem><para><methodname>clearFilters()</methodname></para></listitem>
1474 <para>Rendering:</para>
1479 <methodname>setView(Zend_View_Interface $view = null)</methodname>
1483 <listitem><para><methodname>getView()</methodname></para></listitem>
1487 <methodname>addDecorator($decorator, $options = null)</methodname>
1492 <para><methodname>addDecorators(array $decorators)</methodname></para>
1496 <para><methodname>setDecorators(array $decorators)</methodname></para>
1499 <listitem><para><methodname>getDecorator($name)</methodname></para></listitem>
1500 <listitem><para><methodname>getDecorators()</methodname></para></listitem>
1503 <para><methodname>removeDecorator($name)</methodname></para>
1506 <listitem><para><methodname>clearDecorators()</methodname></para></listitem>
1510 <methodname>render(Zend_View_Interface $view = null)</methodname>
1518 <sect2 id="zend.form.elements.config">
1519 <title>Configuration</title>
1522 <classname>Zend_Form_Element</classname>'s constructor accepts either an
1523 array of options or a <classname>Zend_Config</classname> object containing
1524 options, and it can also be configured using either
1525 <methodname>setOptions()</methodname> or <methodname>setConfig()</methodname>. Generally
1526 speaking, keys are named as follows:
1532 If 'set' + key refers to a <classname>Zend_Form_Element</classname>
1533 method, then the value provided will be passed to that method.
1539 Otherwise, the value will be used to set an attribute.
1545 Exceptions to the rule include the following:
1551 <property>prefixPath</property> will be passed to
1552 <methodname>addPrefixPaths()</methodname>
1558 The following setters cannot be set in this way:
1564 <property>setAttrib</property> (though
1565 <property>setAttribs</property> <emphasis>will</emphasis> work)
1569 <listitem><para><property>setConfig</property></para></listitem>
1570 <listitem><para><property>setOptions</property></para></listitem>
1571 <listitem><para><property>setPluginLoader</property></para></listitem>
1572 <listitem><para><property>setTranslator</property></para></listitem>
1573 <listitem><para><property>setView</property></para></listitem>
1579 As an example, here is a config file that passes configuration for
1580 every type of configurable data:
1583 <programlisting language="ini"><![CDATA[
1591 autoInsertNotEmptyValidator = true
1592 description = "Foo elements are for examples"
1595 attribs.class = "element"
1596 ; sets 'onclick' attribute
1597 onclick = "autoComplete(this, '/form/autocomplete/element')"
1598 prefixPaths.decorator.prefix = "My_Decorator"
1599 prefixPaths.decorator.path = "My/Decorator/"
1600 disableTranslator = 0
1601 validators.required.validator = "NotEmpty"
1602 validators.required.breakChainOnFailure = true
1603 validators.alpha.validator = "alpha"
1604 validators.regex.validator = "regex"
1605 validators.regex.options.pattern = "/^[A-F].*/$"
1606 filters.ucase.filter = "StringToUpper"
1607 decorators.element.decorator = "ViewHelper"
1608 decorators.element.options.helper = "FormText"
1609 decorators.label.decorator = "Label"
1610 ]]></programlisting>
1613 <sect2 id="zend.form.elements.custom">
1614 <title>Custom Elements</title>
1617 You can create your own custom elements by simply extending the
1618 <classname>Zend_Form_Element</classname> class. Common reasons to do so
1625 Elements that share common validators and/or filters
1631 Elements that have custom decorator functionality
1637 There are two methods typically used to extend an element:
1638 <methodname>init()</methodname>, which can be used to add custom initialization
1639 logic to your element, and <methodname>loadDefaultDecorators()</methodname>,
1640 which can be used to set a list of default decorators used by your
1645 As an example, let's say that all text elements in a form you are
1646 creating need to be filtered with <classname>StringTrim</classname>,
1647 validated with a common regular expression, and that you want to
1648 use a custom decorator you've created for displaying them,
1649 'My_Decorator_TextItem'. In addition, you have a number of standard
1650 attributes, including 'size', 'maxLength', and 'class' you wish to
1651 specify. You could define an element to accomplish this as follows:
1654 <programlisting language="php"><![CDATA[
1655 class My_Element_Text extends Zend_Form_Element
1657 public function init()
1659 $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator')
1660 ->addFilters('StringTrim')
1661 ->addValidator('Regex', false, array('/^[a-z0-9]{6,}$/i'))
1662 ->addDecorator('TextItem')
1663 ->setAttrib('size', 30)
1664 ->setAttrib('maxLength', 45)
1665 ->setAttrib('class', 'text');
1668 ]]></programlisting>
1671 You could then inform your form object about the prefix path for
1672 such elements, and start creating elements:
1675 <programlisting language="php"><![CDATA[
1676 $form->addPrefixPath('My_Element', 'My/Element/', 'element')
1677 ->addElement('text', 'foo');
1678 ]]></programlisting>
1681 The 'foo' element will now be of type <classname>My_Element_Text</classname>,
1682 and exhibit the behaviour you've outlined.
1686 Another method you may want to override when extending
1687 <classname>Zend_Form_Element</classname> is the
1688 <methodname>loadDefaultDecorators()</methodname> method. This method
1689 conditionally loads a set of default decorators for your element;
1690 you may wish to substitute your own decorators in your extending
1694 <programlisting language="php"><![CDATA[
1695 class My_Element_Text extends Zend_Form_Element
1697 public function loadDefaultDecorators()
1699 $this->addDecorator('ViewHelper')
1700 ->addDecorator('DisplayError')
1701 ->addDecorator('Label')
1702 ->addDecorator('HtmlTag',
1703 array('tag' => 'div', 'class' => 'element'));
1706 ]]></programlisting>
1709 There are many ways to customize elements. Read the <acronym>API</acronym>
1710 documentation of <classname>Zend_Form_Element</classname> to learn about all of the
1716 vim:se ts=4 sw=4 tw=80 et: