| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.form.elements">
- <title>Creating Form Elements Using Zend_Form_Element</title>
- <para>
- A form is made of elements that typically correspond to <acronym>HTML</acronym> form
- input. <classname>Zend_Form_Element</classname> encapsulates single form elements, with the
- following areas of responsibility:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- validation (is submitted data valid?)
- </para>
- <itemizedlist>
- <listitem><para>capturing of validation error codes and messages</para></listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>
- filtering (how is the element escaped or normalized prior to
- validation and/or for output?)
- </para>
- </listitem>
- <listitem>
- <para>rendering (how is the element displayed?)</para>
- </listitem>
- <listitem>
- <para>metadata and attributes (what information further qualifies the element?)</para>
- </listitem>
- </itemizedlist>
- <para>
- The base class, <classname>Zend_Form_Element</classname>, has reasonable defaults
- for many cases, but it is best to extend the class for commonly used
- special purpose elements. Additionally, Zend Framework ships with a
- number of standard <acronym>XHTML</acronym> elements; you can read about them <link
- linkend="zend.form.standardElements">in the Standard Elements
- chapter</link>.
- </para>
- <sect2 id="zend.form.elements.loaders">
- <title>Plugin Loaders</title>
- <para>
- <classname>Zend_Form_Element</classname> makes use of <link
- linkend="zend.loader.pluginloader">Zend_Loader_PluginLoader</link>
- to allow developers to specify locations of alternate validators,
- filters, and decorators. Each has its own plugin loader associated
- with it, and general accessors are used to retrieve and modify
- each.
- </para>
- <para>
- The following loader types are used with the various plugin loader
- methods: 'validate', 'filter', and 'decorator'. The type names are
- case insensitive.
- </para>
- <para>
- The methods used to interact with plugin loaders are as follows:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setPluginLoader($loader, $type)</methodname>:
- <varname>$loader</varname> is the plugin loader object itself, while
- <varname>$type</varname> is one of the types specified above. This
- sets the plugin loader for the given type to the newly
- specified loader object.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getPluginLoader($type)</methodname>: retrieves the plugin
- loader associated with <varname>$type</varname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addPrefixPath($prefix, $path, $type = null)</methodname>: adds
- a prefix/path association to the loader specified by
- <varname>$type</varname>. If <varname>$type</varname> is
- <constant>NULL</constant>, it will attempt to add the path to all loaders, by
- appending the prefix with each of "_Validate", "_Filter", and "_Decorator"; and
- appending the path with "Validate/", "Filter/", and
- "Decorator/". If you have all your extra form element classes
- under a common hierarchy, this is a convenience method for
- setting the base prefix for them.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addPrefixPaths(array $spec)</methodname>: allows you to add
- many paths at once to one or more plugin loaders. It expects
- each array item to be an array with the keys 'path', 'prefix',
- and 'type'.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Custom validators, filters, and decorators are an easy way to share
- functionality between forms and to encapsulate custom functionality.
- </para>
- <example id="zend.form.elements.loaders.customLabel">
- <title>Custom Label</title>
- <para>
- One common use case for plugins is to provide replacements for
- standard classes. For instance, if you want to provide a
- different implementation of the 'Label' decorator -- for
- instance, to always append a colon -- you could create your own
- 'Label' decorator with your own class prefix, and then add it to
- your prefix path.
- </para>
- <para>
- Let's start with a custom Label decorator. We'll give it the
- class prefix "My_Decorator", and the class itself will be in the
- file "My/Decorator/Label.php".
- </para>
- <programlisting language="php"><![CDATA[
- class My_Decorator_Label extends Zend_Form_Decorator_Abstract
- {
- protected $_placement = 'PREPEND';
- public function render($content)
- {
- if (null === ($element = $this->getElement())) {
- return $content;
- }
- if (!method_exists($element, 'getLabel')) {
- return $content;
- }
- $label = $element->getLabel() . ':';
- if (null === ($view = $element->getView())) {
- return $this->renderLabel($content, $label);
- }
- $label = $view->formLabel($element->getName(), $label);
- return $this->renderLabel($content, $label);
- }
- public function renderLabel($content, $label)
- {
- $placement = $this->getPlacement();
- $separator = $this->getSeparator();
- switch ($placement) {
- case 'APPEND':
- return $content . $separator . $label;
- case 'PREPEND':
- default:
- return $label . $separator . $content;
- }
- }
- }
- ]]></programlisting>
- <para>
- Now we can tell the element to use this plugin path when looking
- for decorators:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
- ]]></programlisting>
- <para>
- Alternately, we can do that at the form level to ensure all
- decorators use this path:
- </para>
- <programlisting language="php"><![CDATA[
- $form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
- ]]></programlisting>
- <para>
- After it added as in the example above, the 'My/Decorator/' path will be searched
- first to see if the decorator exists there when you add a decorator. As a result,
- 'My_Decorator_Label' will now be used when the 'Label' decorator is requested.
- </para>
- </example>
- </sect2>
- <sect2 id="zend.form.elements.filters">
- <title>Filters</title>
- <para>
- It's often useful and/or necessary to perform some normalization on
- input prior to validation. For example, you may want to strip out
- all <acronym>HTML</acronym>, but run your validations on what remains to ensure the
- submission is valid. Or you may want to trim empty space surrounding input so that a
- StringLength validator will use the correct length of the input without counting leading
- or trailing whitespace characters. These operations may be performed using
- <classname>Zend_Filter</classname>. <classname>Zend_Form_Element</classname> has support
- for filter chains, allowing you to specify multiple, sequential filters. Filtering
- happens both during validation and when you retrieve the element value via
- <methodname>getValue()</methodname>:
- </para>
- <programlisting language="php"><![CDATA[
- $filtered = $element->getValue();
- ]]></programlisting>
- <para>
- Filters may be added to the chain in two ways:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- passing in a concrete filter instance
- </para>
- </listitem>
- <listitem>
- <para>
- providing a short filter name
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Let's see some examples:
- </para>
- <programlisting language="php"><![CDATA[
- // Concrete filter instance:
- $element->addFilter(new Zend_Filter_Alnum());
- // Short filter name:
- $element->addFilter('Alnum');
- $element->addFilter('alnum');
- ]]></programlisting>
- <para>
- Short names are typically the filter name minus the prefix. In the
- default case, this will mean minus the 'Zend_Filter_' prefix.
- The first letter can be upper-cased or lower-cased.
- </para>
- <note>
- <title>Using Custom Filter Classes</title>
- <para>
- If you have your own set of filter classes, you can tell
- <classname>Zend_Form_Element</classname> about these using
- <methodname>addPrefixPath()</methodname>. For instance, if you have
- filters under the 'My_Filter' prefix, you can tell
- <classname>Zend_Form_Element</classname> about this as follows:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addPrefixPath('My_Filter', 'My/Filter/', 'filter');
- ]]></programlisting>
- <para>
- (Recall that the third argument indicates which plugin loader
- on which to perform the action.)
- </para>
- </note>
- <para>
- If at any time you need the unfiltered value, use the
- <methodname>getUnfilteredValue()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $unfiltered = $element->getUnfilteredValue();
- ]]></programlisting>
- <para>
- For more information on filters, see the <link
- linkend="zend.filter.introduction">Zend_Filter
- documentation</link>.
- </para>
- <para>
- Methods associated with filters include:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>addFilter($nameOfFilter, array $options = null)</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addFilters(array $filters)</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setFilters(array $filters)</methodname> (overwrites all filters)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getFilter($name)</methodname> (retrieve a filter object by name)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getFilters()</methodname> (retrieve all filters)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>removeFilter($name)</methodname> (remove filter by name)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearFilters()</methodname> (remove all filters)
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.form.elements.validators">
- <title>Validators</title>
- <para>
- If you subscribe to the security mantra of "filter input, escape
- output," you'll should use validator to filter input submitted with your form.
- In <classname>Zend_Form</classname>, each element includes its own validator
- chain, consisting of <classname>Zend_Validate_*</classname> validators.
- </para>
- <para>
- Validators may be added to the chain in two ways:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- passing in a concrete validator instance
- </para>
- </listitem>
- <listitem>
- <para>
- providing a short validator name
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Let's see some examples:
- </para>
- <programlisting language="php"><![CDATA[
- // Concrete validator instance:
- $element->addValidator(new Zend_Validate_Alnum());
- // Short validator name:
- $element->addValidator('Alnum');
- $element->addValidator('alnum');
- ]]></programlisting>
- <para>
- Short names are typically the validator name minus the prefix. In
- the default case, this will mean minus the 'Zend_Validate_' prefix.
- As is the case with filters, the first letter can be upper-cased or lower-cased.
- </para>
- <note>
- <title>Using Custom Validator Classes</title>
- <para>
- If you have your own set of validator classes, you can tell
- <classname>Zend_Form_Element</classname> about these using
- <methodname>addPrefixPath()</methodname>. For instance, if you have
- validators under the 'My_Validator' prefix, you can tell
- <classname>Zend_Form_Element</classname> about this as follows:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addPrefixPath('My_Validator', 'My/Validator/', 'validate');
- ]]></programlisting>
- <para>
- (Recall that the third argument indicates which plugin loader
- on which to perform the action.)
- </para>
- </note>
- <para>
- If failing a particular validation should prevent later validators
- from firing, pass boolean <constant>TRUE</constant> as the second parameter:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addValidator('alnum', true);
- ]]></programlisting>
- <para>
- If you are using a string name to add a validator, and the
- validator class accepts arguments to the constructor, you may pass
- these to the third parameter of <methodname>addValidator()</methodname> as an
- array:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addValidator('StringLength', false, array(6, 20));
- ]]></programlisting>
- <para>
- Arguments passed in this way should be in the order in which they
- are defined in the constructor. The above example will instantiate
- the <classname>Zend_Validate_StringLenth</classname> class with its
- <varname>$min</varname> and <varname>$max</varname> parameters:
- </para>
- <programlisting language="php"><![CDATA[
- $validator = new Zend_Validate_StringLength(6, 20);
- ]]></programlisting>
- <note>
- <title>Providing Custom Validator Error Messages</title>
- <para>
- Some developers may wish to provide custom error messages for a
- validator. The <varname>$options</varname> argument of the
- <methodname>Zend_Form_Element::addValidator()</methodname> method allows you to do
- so by providing the key 'messages' and mapping it to an array of key/value pairs
- for setting the message templates. You will need to know the
- error codes of the various validation error types for the
- particular validator.
- </para>
- <para>
- A better option is to use a <classname>Zend_Translate_Adapter</classname>
- with your form. Error codes are automatically passed to the
- adapter by the default Errors decorator; you can then specify
- your own error message strings by setting up translations for
- the various error codes of your validators.
- </para>
- </note>
- <para>
- You can also set many validators at once, using
- <methodname>addValidators()</methodname>. The basic usage is to pass an array
- of arrays, with each array containing 1 to 3 values, matching the
- constructor of <methodname>addValidator()</methodname>:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addValidators(array(
- array('NotEmpty', true),
- array('alnum'),
- array('stringLength', false, array(6, 20)),
- ));
- ]]></programlisting>
- <para>
- If you want to be more verbose or explicit, you can use the array
- keys 'validator', 'breakChainOnFailure', and 'options':
- </para>
- <programlisting language="php"><![CDATA[
- $element->addValidators(array(
- array(
- 'validator' => 'NotEmpty',
- 'breakChainOnFailure' => true),
- array('validator' => 'alnum'),
- array(
- 'validator' => 'stringLength',
- 'options' => array(6, 20)),
- ));
- ]]></programlisting>
- <para>
- This usage is good for illustrating how you could then configure
- validators in a config file:
- </para>
- <programlisting language="ini"><![CDATA[
- element.validators.notempty.validator = "NotEmpty"
- element.validators.notempty.breakChainOnFailure = true
- element.validators.alnum.validator = "Alnum"
- element.validators.strlen.validator = "StringLength"
- element.validators.strlen.options.min = 6
- element.validators.strlen.options.max = 20
- ]]></programlisting>
- <para>
- Notice that every item has a key, whether or not it needs one; this
- is a limitation of using configuration files -- but it also helps
- make explicit what the arguments are for. Just remember that any
- validator options must be specified in order.
- </para>
- <para>
- To validate an element, pass the value to
- <methodname>isValid()</methodname>:
- </para>
- <programlisting language="php"><![CDATA[
- if ($element->isValid($value)) {
- // valid
- } else {
- // invalid
- }
- ]]></programlisting>
- <note>
- <title>Validation Operates On Filtered Values</title>
- <para>
- <methodname>Zend_Form_Element::isValid()</methodname> filters values through
- the provided filter chain prior to validation. See <link
- linkend="zend.form.elements.filters">the Filters
- section</link> for more information.
- </para>
- </note>
- <note>
- <title>Validation Context</title>
- <para>
- <methodname>Zend_Form_Element::isValid()</methodname> supports an
- additional argument, <varname>$context</varname>.
- <methodname>Zend_Form::isValid()</methodname> passes the entire array of
- data being processed to <varname>$context</varname> when validating a
- form, and <methodname>Zend_Form_Element::isValid()</methodname>, in turn,
- passes it to each validator. This means you can write
- validators that are aware of data passed to other form
- elements. As an example, consider a standard registration form
- that has fields for both password and a password confirmation;
- one validation would be that the two fields match. Such a
- validator might look like the following:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
- {
- const NOT_MATCH = 'notMatch';
- protected $_messageTemplates = array(
- self::NOT_MATCH => 'Password confirmation does not match'
- );
- public function isValid($value, $context = null)
- {
- $value = (string) $value;
- $this->_setValue($value);
- if (is_array($context)) {
- if (isset($context['password_confirm'])
- && ($value == $context['password_confirm']))
- {
- return true;
- }
- } elseif (is_string($context) && ($value == $context)) {
- return true;
- }
- $this->_error(self::NOT_MATCH);
- return false;
- }
- }
- ]]></programlisting>
- </note>
- <para>
- Validators are processed in order. Each validator is processed,
- unless a validator created with a <constant>TRUE</constant>
- <varname>$breakChainOnFailure</varname> value fails its validation. Be
- sure to specify your validators in a reasonable order.
- </para>
- <para>
- After a failed validation, you can retrieve the error codes and
- messages from the validator chain:
- </para>
- <programlisting language="php"><![CDATA[
- $errors = $element->getErrors();
- $messages = $element->getMessages();
- ]]></programlisting>
- <para>
- (Note: error messages returned are an associative array of error
- code / error message pairs.)
- </para>
- <para>
- In addition to validators, you can specify that an element is
- required, using <methodname>setRequired($flag)</methodname>. By default, this
- flag is <constant>FALSE</constant>. In combination with
- <methodname>setAllowEmpty($flag)</methodname> (<constant>TRUE</constant>
- by default) and <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
- (<constant>TRUE</constant> by default), the behavior of your validator chain
- can be modified in a number of ways:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Using the defaults, validating an Element without passing a value, or
- passing an empty string for it, skips all validators and validates to
- <constant>TRUE</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setAllowEmpty(false)</methodname> leaving the two other
- mentioned flags untouched, will validate against the validator chain
- you defined for this Element, regardless of the value passed
- to <methodname>isValid()</methodname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setRequired(true)</methodname> leaving the two other
- mentioned flags untouched, will add a 'NotEmpty' validator
- on top of the validator chain (if none was already set)), with the
- <varname>$breakChainOnFailure</varname> flag set. This behavior lends
- required flag semantic meaning: if no value is passed,
- we immediately invalidate the submission and notify the
- user, and prevent other validators from running on what we
- already know is invalid data.
- </para>
- <para>
- If you do not want this behavior, you can turn it off by
- passing a <constant>FALSE</constant> value to
- <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>; this
- will prevent <methodname>isValid()</methodname> from placing the
- 'NotEmpty' validator in the validator chain.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- For more information on validators, see the <link
- linkend="zend.validate.introduction">Zend_Validate
- documentation</link>.
- </para>
- <note>
- <title>Using Zend_Form_Elements as general-purpose validators</title>
- <para>
- <classname>Zend_Form_Element</classname> implements
- <classname>Zend_Validate_Interface</classname>, meaning an element may
- also be used as a validator in other, non-form related
- validation chains.
- </para>
- </note>
- <note>
- <title>When is an element detected as empty?</title>
- <para>
- As mentioned the 'NotEmpty' validator is used to detect if an element is empty
- or not. But <classname>Zend_Validate_NotEmpty</classname> does, per default, not
- work like <acronym>PHP</acronym>'s method <methodname>empty()</methodname>.
- </para>
- <para>
- This means when an element contains an integer <emphasis>0</emphasis> or an string
- <emphasis>'0'</emphasis> then the element will be seen as not empty. If you want to
- have a different behaviour you must create your own instance of
- <classname>Zend_Validate_NotEmpty</classname>. There you can define the behaviour of
- this validator. See <ulink
- url="zend.validate.set.notempty">Zend_Validate_NotEmpty</ulink> for details.
- </para>
- </note>
- <para>
- Methods associated with validation include:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setRequired($flag)</methodname> and
- <methodname>isRequired()</methodname> allow you to set and retrieve the
- status of the 'required' flag. When set to boolean <constant>TRUE</constant>,
- this flag requires that the element be in the data processed by
- <classname>Zend_Form</classname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setAllowEmpty($flag)</methodname> and
- <methodname>getAllowEmpty()</methodname> allow you to modify the
- behaviour of optional elements (i.e., elements where the
- required flag is <constant>FALSE</constant>). When the 'allow empty' flag is
- <constant>TRUE</constant>, empty values will not be passed to the validator
- chain.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setAutoInsertNotEmptyValidator($flag)</methodname> allows
- you to specify whether or not a 'NotEmpty' validator will be
- prepended to the validator chain when the element is
- required. By default, this flag is <constant>TRUE</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addValidator($nameOrValidator, $breakChainOnFailure = false, array
- $options = null)</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addValidators(array $validators)</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setValidators(array $validators)</methodname> (overwrites all
- validators)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getValidator($name)</methodname> (retrieve a validator object by
- name)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getValidators()</methodname> (retrieve all validators)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>removeValidator($name)</methodname> (remove validator by name)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearValidators()</methodname> (remove all validators)
- </para>
- </listitem>
- </itemizedlist>
- <sect3 id="zend.form.elements.validators.errors">
- <title>Custom Error Messages</title>
- <para>
- At times, you may want to specify one or more specific error
- messages to use instead of the error messages generated by the
- validators attached to your element. Additionally, at times you
- may want to mark the element invalid yourself. As of 1.6.0, this
- functionality is possible via the following methods.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>addErrorMessage($message)</methodname>: add an error message
- to display on form validation errors. You may call this more
- than once, and new messages are appended to the stack.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addErrorMessages(array $messages)</methodname>: add multiple
- error messages to display on form validation errors.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setErrorMessages(array $messages)</methodname>: add multiple
- error messages to display on form validation errors,
- overwriting all previously set error messages.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getErrorMessages()</methodname>: retrieve the list of
- custom error messages that have been defined.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearErrorMessages()</methodname>: remove all custom error
- messages that have been defined.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>markAsError()</methodname>: mark the element as having
- failed validation.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>hasErrors()</methodname>: determine whether the element has
- either failed validation or been marked as invalid.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addError($message)</methodname>: add a message to the custom
- error messages stack and flag the element as invalid.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addErrors(array $messages)</methodname>: add several
- messages to the custom error messages stack and flag the
- element as invalid.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setErrors(array $messages)</methodname>: overwrite the
- custom error messages stack with the provided messages and
- flag the element as invalid.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- All errors set in this fashion may be translated. Additionally,
- you may insert the placeholder "%value%" to represent the
- element value; this current element value will be substituted
- when the error messages are retrieved.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.form.elements.decorators">
- <title>Decorators</title>
- <para>
- One particular pain point for many web developers is the creation
- of the <acronym>XHTML</acronym> forms themselves. For each element, the developer
- needs to create markup for the element itself (typically a label)
- and special markup for displaying
- validation error messages. The more elements on the page, the less
- trivial this task becomes.
- </para>
- <para>
- <classname>Zend_Form_Element</classname> tries to solve this issue through
- the use of "decorators". Decorators are simply classes that have
- access to the element and a method for rendering content. For more
- information on how decorators work, please see the section on <link
- linkend="zend.form.decorators">Zend_Form_Decorator</link>.
- </para>
- <para>
- The default decorators used by <classname>Zend_Form_Element</classname> are:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>ViewHelper</emphasis>: specifies a view helper to use
- to render the element. The 'helper' element attribute can be
- used to specify which view helper to use. By default,
- <classname>Zend_Form_Element</classname> specifies the 'formText' view
- helper, but individual subclasses specify different helpers.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Errors</emphasis>: appends error messages to the
- element using <classname>Zend_View_Helper_FormErrors</classname>. If none are
- present, nothing is appended.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Description</emphasis>: appends the element
- description. If none is present, nothing is appended. By
- default, the description is rendered in a <p> tag with a
- class of 'description'.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>HtmlTag</emphasis>: wraps the element and errors in
- an <acronym>HTML</acronym> <dd> tag.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Label</emphasis>: prepends a label to the element
- using <classname>Zend_View_Helper_FormLabel</classname>, and wraps it in a
- <dt> tag. If no label is provided, just the definition term tag is
- rendered.
- </para>
- </listitem>
- </itemizedlist>
- <note>
- <title>Default Decorators Do Not Need to Be Loaded</title>
- <para>
- By default, the default decorators are loaded during object
- initialization. You can disable this by passing the
- 'disableLoadDefaultDecorators' option to the constructor:
- </para>
- <programlisting language="php"><![CDATA[
- $element = new Zend_Form_Element('foo',
- array('disableLoadDefaultDecorators' =>
- true)
- );
- ]]></programlisting>
- <para>
- This option may be mixed with any other options you pass,
- both as array options or in a <classname>Zend_Config</classname> object.
- </para>
- </note>
- <para>
- Since the order in which decorators are registered matters- the first
- decorator registered is executed first- you will need to make
- sure you register your decorators in an appropriate order, or
- ensure that you set the placement options in a sane fashion. To
- give an example, here is the code that registers the default
- decorators:
- </para>
- <programlisting language="php"><![CDATA[
- $this->addDecorators(array(
- array('ViewHelper'),
- array('Errors'),
- array('Description', array('tag' => 'p', 'class' => 'description')),
- array('HtmlTag', array('tag' => 'dd')),
- array('Label', array('tag' => 'dt')),
- ));
- ]]></programlisting>
- <para>
- The initial content is created by the 'ViewHelper' decorator, which
- creates the form element itself. Next, the 'Errors' decorator
- fetches error messages from the element, and, if any are present,
- passes them to the 'FormErrors' view helper to render. If a
- description is present, the 'Description' decorator will append a
- paragraph of class 'description' containing the descriptive text to
- the aggregated content. The next decorator, 'HtmlTag', wraps the
- element, errors, and description in an <acronym>HTML</acronym> <dd> tag.
- Finally, the last decorator, 'label', retrieves the element's label
- and passes it to the 'FormLabel' view helper, wrapping it in an <acronym>HTML</acronym>
- <dt> tag; the value is prepended to the content by default.
- The resulting output looks basically like this:
- </para>
- <programlisting language="html"><![CDATA[
- <dt><label for="foo" class="optional">Foo</label></dt>
- <dd>
- <input type="text" name="foo" id="foo" value="123" />
- <ul class="errors">
- <li>"123" is not an alphanumeric value</li>
- </ul>
- <p class="description">
- This is some descriptive text regarding the element.
- </p>
- </dd>
- ]]></programlisting>
- <para>
- For more information on decorators, read the <link
- linkend="zend.form.decorators">Zend_Form_Decorator section</link>.
- </para>
- <note>
- <title>Using Multiple Decorators of the Same Type</title>
- <para>
- Internally, <classname>Zend_Form_Element</classname> uses a decorator's
- class as the lookup mechanism when retrieving decorators. As a
- result, you cannot register multiple decorators of the same
- type; subsequent decorators will simply overwrite those that
- existed before.
- </para>
- <para>
- To get around this, you can use <emphasis>aliases</emphasis>.
- Instead of passing a decorator or decorator name as the first
- argument to <methodname>addDecorator()</methodname>, pass an array with a
- single element, with the alias pointing to the decorator object
- or name:
- </para>
- <programlisting language="php"><![CDATA[
- // Alias to 'FooBar':
- $element->addDecorator(array('FooBar' => 'HtmlTag'),
- array('tag' => 'div'));
- // And retrieve later:
- $decorator = $element->getDecorator('FooBar');
- ]]></programlisting>
- <para>
- In the <methodname>addDecorators()</methodname> and
- <methodname>setDecorators()</methodname> methods, you will need to pass
- the 'decorator' option in the array representing the decorator:
- </para>
- <programlisting language="php"><![CDATA[
- // Add two 'HtmlTag' decorators, aliasing one to 'FooBar':
- $element->addDecorators(
- array('HtmlTag', array('tag' => 'div')),
- array(
- 'decorator' => array('FooBar' => 'HtmlTag'),
- 'options' => array('tag' => 'dd')
- ),
- );
- // And retrieve later:
- $htmlTag = $element->getDecorator('HtmlTag');
- $fooBar = $element->getDecorator('FooBar');
- ]]></programlisting>
- </note>
- <para>
- Methods associated with decorators include:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>addDecorator($nameOrDecorator, array $options = null)</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>addDecorators(array $decorators)</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setDecorators(array $decorators)</methodname> (overwrites all
- decorators)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getDecorator($name)</methodname> (retrieve a decorator object by
- name)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getDecorators()</methodname> (retrieve all decorators)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>removeDecorator($name)</methodname> (remove decorator by name)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearDecorators()</methodname> (remove all decorators)
- </para>
- </listitem>
- </itemizedlist>
- <para>
- <classname>Zend_Form_Element</classname> also uses overloading to allow rendering
- specific decorators. <methodname>__call()</methodname> will intercept methods
- that lead with the text 'render' and use the remainder of the method
- name to lookup a decorator; if found, it will then render that
- <emphasis>single</emphasis> decorator. Any arguments passed to the
- method call will be used as content to pass to the decorator's
- <methodname>render()</methodname> method. As an example:
- </para>
- <programlisting language="php"><![CDATA[
- // Render only the ViewHelper decorator:
- echo $element->renderViewHelper();
- // Render only the HtmlTag decorator, passing in content:
- echo $element->renderHtmlTag("This is the html tag content");
- ]]></programlisting>
- <para>
- If the decorator does not exist, an exception is raised.
- </para>
- </sect2>
- <sect2 id="zend.form.elements.metadata">
- <title>Metadata and Attributes</title>
- <para>
- <classname>Zend_Form_Element</classname> handles a variety of attributes and
- element metadata. Basic attributes include:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>name</emphasis>: the element name. Uses the
- <methodname>setName()</methodname> and <methodname>getName()</methodname>
- accessors.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>label</emphasis>: the element label. Uses the
- <methodname>setLabel()</methodname> and <methodname>getLabel()</methodname>
- accessors.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>order</emphasis>: the index at which an element
- should appear in the form. Uses the <methodname>setOrder()</methodname> and
- <methodname>getOrder()</methodname> accessors.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>value</emphasis>: the current element value. Uses the
- <methodname>setValue()</methodname> and <methodname>getValue()</methodname>
- accessors.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>description</emphasis>: a description of the element;
- often used to provide tooltip or javascript contextual hinting
- describing the purpose of the element. Uses the
- <methodname>setDescription()</methodname> and
- <methodname>getDescription()</methodname> accessors.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>required</emphasis>: flag indicating whether or not
- the element is required when performing form validation. Uses
- the <methodname>setRequired()</methodname> and
- <methodname>isRequired()</methodname> accessors. This flag is
- <constant>FALSE</constant> by default.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>allowEmpty</emphasis>: flag indicating whether or not
- a non-required (optional) element should attempt to validate
- empty values. If it is set to <constant>TRUE</constant> and the required flag is
- <constant>FALSE</constant>, empty values are not passed to the validator chain
- and are presumed <constant>TRUE</constant>. Uses the
- <methodname>setAllowEmpty()</methodname> and
- <methodname>getAllowEmpty()</methodname> accessors. This flag is
- <constant>TRUE</constant> by default.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>autoInsertNotEmptyValidator</emphasis>: flag
- indicating whether or not to insert a 'NotEmpty' validator when
- the element is required. By default, this flag is <constant>TRUE</constant>. Set
- the flag with <methodname>setAutoInsertNotEmptyValidator($flag)</methodname> and
- determine the value with
- <methodname>autoInsertNotEmptyValidator()</methodname>.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Form elements may require additional metadata. For <acronym>XHTML</acronym> form
- elements, for instance, you may want to specify attributes such as
- the class or id. To facilitate this are a set of accessors:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>setAttrib($name, $value)</emphasis>: add an attribute
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>setAttribs(array $attribs)</emphasis>: like
- addAttribs(), but overwrites
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>getAttrib($name)</emphasis>: retrieve a single
- attribute value
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>getAttribs()</emphasis>: retrieve all attributes as
- key/value pairs
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Most of the time, however, you can simply access them as object
- properties, as <classname>Zend_Form_Element</classname> utilizes overloading
- to facilitate access to them:
- </para>
- <programlisting language="php"><![CDATA[
- // Equivalent to $element->setAttrib('class', 'text'):
- $element->class = 'text;
- ]]></programlisting>
- <para>
- By default, all attributes are passed to the view helper used by
- the element during rendering, and rendered as <acronym>HTML</acronym> attributes of
- the element tag.
- </para>
- </sect2>
- <sect2 id="zend.form.elements.standard">
- <title>Standard Elements</title>
- <para>
- <classname>Zend_Form</classname> ships with a number of standard elements; please read
- the <link linkend="zend.form.standardElements">Standard Elements</link>
- chapter for full details.
- </para>
- </sect2>
- <sect2 id="zend.form.elements.methods">
- <title>Zend_Form_Element Methods</title>
- <para>
- <classname>Zend_Form_Element</classname> has many, many methods. What follows
- is a quick summary of their signatures, grouped by type:
- </para>
- <itemizedlist>
- <listitem>
- <para>Configuration:</para>
- <itemizedlist>
- <listitem>
- <para><methodname>setOptions(array $options)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>setConfig(Zend_Config $config)</methodname></para>
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>I18n:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setTranslator(Zend_Translate_Adapter $translator
- = null)</methodname>
- </para>
- </listitem>
- <listitem><para><methodname>getTranslator()</methodname></para></listitem>
- <listitem>
- <para><methodname>setDisableTranslator($flag)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>translatorIsDisabled()</methodname></para>
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>Properties:</para>
- <itemizedlist>
- <listitem><para><methodname>setName($name)</methodname></para></listitem>
- <listitem><para><methodname>getName()</methodname></para></listitem>
- <listitem><para><methodname>setValue($value)</methodname></para></listitem>
- <listitem><para><methodname>getValue()</methodname></para></listitem>
- <listitem><para><methodname>getUnfilteredValue()</methodname></para></listitem>
- <listitem><para><methodname>setLabel($label)</methodname></para></listitem>
- <listitem><para><methodname>getLabel()</methodname></para></listitem>
- <listitem>
- <para><methodname>setDescription($description)</methodname></para>
- </listitem>
- <listitem><para><methodname>getDescription()</methodname></para></listitem>
- <listitem><para><methodname>setOrder($order)</methodname></para></listitem>
- <listitem><para><methodname>getOrder()</methodname></para></listitem>
- <listitem><para><methodname>setRequired($flag)</methodname></para></listitem>
- <listitem><para><methodname>isRequired()</methodname></para></listitem>
- <listitem><para><methodname>setAllowEmpty($flag)</methodname></para></listitem>
- <listitem><para><methodname>getAllowEmpty()</methodname></para></listitem>
- <listitem>
- <para><methodname>setAutoInsertNotEmptyValidator($flag)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>autoInsertNotEmptyValidator()</methodname></para>
- </listitem>
- <listitem><para><methodname>setIgnore($flag)</methodname></para></listitem>
- <listitem><para><methodname>getIgnore()</methodname></para></listitem>
- <listitem><para><methodname>getType()</methodname></para></listitem>
- <listitem>
- <para><methodname>setAttrib($name, $value)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>setAttribs(array $attribs)</methodname></para>
- </listitem>
- <listitem><para><methodname>getAttrib($name)</methodname></para></listitem>
- <listitem><para><methodname>getAttribs()</methodname></para></listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>Plugin loaders and paths:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setPluginLoader(Zend_Loader_PluginLoader_Interface $loader,
- $type)</methodname>
- </para>
- </listitem>
- <listitem>
- <para><methodname>getPluginLoader($type)</methodname></para>
- </listitem>
- <listitem>
- <para>
- <methodname>addPrefixPath($prefix, $path, $type = null)</methodname>
- </para>
- </listitem>
- <listitem>
- <para><methodname>addPrefixPaths(array $spec)</methodname></para>
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>Validation:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>addValidator($validator, $breakChainOnFailure = false,
- $options = array())</methodname>
- </para>
- </listitem>
- <listitem>
- <para><methodname>addValidators(array $validators)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>setValidators(array $validators)</methodname></para>
- </listitem>
- <listitem><para><methodname>getValidator($name)</methodname></para></listitem>
- <listitem><para><methodname>getValidators()</methodname></para></listitem>
- <listitem>
- <para><methodname>removeValidator($name)</methodname></para>
- </listitem>
- <listitem><para><methodname>clearValidators()</methodname></para></listitem>
- <listitem>
- <para><methodname>isValid($value, $context = null)</methodname></para>
- </listitem>
- <listitem><para><methodname>getErrors()</methodname></para></listitem>
- <listitem><para><methodname>getMessages()</methodname></para></listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>Filters:</para>
- <itemizedlist>
- <listitem>
- <para><methodname>addFilter($filter, $options = array())</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>addFilters(array $filters)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>setFilters(array $filters)</methodname></para>
- </listitem>
- <listitem><para><methodname>getFilter($name)</methodname></para></listitem>
- <listitem><para><methodname>getFilters()</methodname></para></listitem>
- <listitem><para><methodname>removeFilter($name)</methodname></para></listitem>
- <listitem><para><methodname>clearFilters()</methodname></para></listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>Rendering:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setView(Zend_View_Interface $view = null)</methodname>
- </para>
- </listitem>
- <listitem><para><methodname>getView()</methodname></para></listitem>
- <listitem>
- <para>
- <methodname>addDecorator($decorator, $options = null)</methodname>
- </para>
- </listitem>
- <listitem>
- <para><methodname>addDecorators(array $decorators)</methodname></para>
- </listitem>
- <listitem>
- <para><methodname>setDecorators(array $decorators)</methodname></para>
- </listitem>
- <listitem><para><methodname>getDecorator($name)</methodname></para></listitem>
- <listitem><para><methodname>getDecorators()</methodname></para></listitem>
- <listitem>
- <para><methodname>removeDecorator($name)</methodname></para>
- </listitem>
- <listitem><para><methodname>clearDecorators()</methodname></para></listitem>
- <listitem>
- <para>
- <methodname>render(Zend_View_Interface $view = null)</methodname>
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.form.elements.config">
- <title>Configuration</title>
- <para>
- <classname>Zend_Form_Element</classname>'s constructor accepts either an
- array of options or a <classname>Zend_Config</classname> object containing
- options, and it can also be configured using either
- <methodname>setOptions()</methodname> or <methodname>setConfig()</methodname>. Generally
- speaking, keys are named as follows:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- If 'set' + key refers to a <classname>Zend_Form_Element</classname>
- method, then the value provided will be passed to that method.
- </para>
- </listitem>
- <listitem>
- <para>
- Otherwise, the value will be used to set an attribute.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Exceptions to the rule include the following:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <property>prefixPath</property> will be passed to
- <methodname>addPrefixPaths()</methodname>
- </para>
- </listitem>
- <listitem>
- <para>
- The following setters cannot be set in this way:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <property>setAttrib</property> (though
- <property>setAttribs</property> <emphasis>will</emphasis> work)
- </para>
- </listitem>
- <listitem><para><property>setConfig</property></para></listitem>
- <listitem><para><property>setOptions</property></para></listitem>
- <listitem><para><property>setPluginLoader</property></para></listitem>
- <listitem><para><property>setTranslator</property></para></listitem>
- <listitem><para><property>setView</property></para></listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- <para>
- As an example, here is a config file that passes configuration for
- every type of configurable data:
- </para>
- <programlisting language="ini"><![CDATA[
- [element]
- name = "foo"
- value = "foobar"
- label = "Foo:"
- order = 10
- required = true
- allowEmpty = false
- autoInsertNotEmptyValidator = true
- description = "Foo elements are for examples"
- ignore = false
- attribs.id = "foo"
- attribs.class = "element"
- ; For radio button elements
- escape = true
- listsep = "<br />\n"
- ; sets 'onclick' attribute
- onclick = "autoComplete(this, '/form/autocomplete/element')"
- prefixPaths.decorator.prefix = "My_Decorator"
- prefixPaths.decorator.path = "My/Decorator/"
- disableTranslator = 0
- validators.required.validator = "NotEmpty"
- validators.required.breakChainOnFailure = true
- validators.alpha.validator = "alpha"
- validators.regex.validator = "regex"
- validators.regex.options.pattern = "/^[A-F].*/$"
- filters.ucase.filter = "StringToUpper"
- decorators.element.decorator = "ViewHelper"
- decorators.element.options.helper = "FormText"
- decorators.label.decorator = "Label"
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.elements.custom">
- <title>Custom Elements</title>
- <para>
- You can create your own custom elements by simply extending the
- <classname>Zend_Form_Element</classname> class. Common reasons to do so
- include:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Elements that share common validators and/or filters
- </para>
- </listitem>
- <listitem>
- <para>
- Elements that have custom decorator functionality
- </para>
- </listitem>
- </itemizedlist>
- <para>
- There are two methods typically used to extend an element:
- <methodname>init()</methodname>, which can be used to add custom initialization
- logic to your element, and <methodname>loadDefaultDecorators()</methodname>,
- which can be used to set a list of default decorators used by your
- element.
- </para>
- <para>
- As an example, let's say that all text elements in a form you are
- creating need to be filtered with <classname>StringTrim</classname>,
- validated with a common regular expression, and that you want to
- use a custom decorator you've created for displaying them,
- 'My_Decorator_TextItem'. In addition, you have a number of standard
- attributes, including 'size', 'maxLength', and 'class' you wish to
- specify. You could define an element to accomplish this as follows:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Element_Text extends Zend_Form_Element
- {
- public function init()
- {
- $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator')
- ->addFilters('StringTrim')
- ->addValidator('Regex', false, array('/^[a-z0-9]{6,}$/i'))
- ->addDecorator('TextItem')
- ->setAttrib('size', 30)
- ->setAttrib('maxLength', 45)
- ->setAttrib('class', 'text');
- }
- }
- ]]></programlisting>
- <para>
- You could then inform your form object about the prefix path for
- such elements, and start creating elements:
- </para>
- <programlisting language="php"><![CDATA[
- $form->addPrefixPath('My_Element', 'My/Element/', 'element')
- ->addElement('text', 'foo');
- ]]></programlisting>
- <para>
- The 'foo' element will now be of type <classname>My_Element_Text</classname>,
- and exhibit the behaviour you've outlined.
- </para>
- <para>
- Another method you may want to override when extending
- <classname>Zend_Form_Element</classname> is the
- <methodname>loadDefaultDecorators()</methodname> method. This method
- conditionally loads a set of default decorators for your element;
- you may wish to substitute your own decorators in your extending
- class:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Element_Text extends Zend_Form_Element
- {
- public function loadDefaultDecorators()
- {
- $this->addDecorator('ViewHelper')
- ->addDecorator('DisplayError')
- ->addDecorator('Label')
- ->addDecorator('HtmlTag',
- array('tag' => 'div', 'class' => 'element'));
- }
- }
- ]]></programlisting>
- <para>
- There are many ways to customize elements. Read the <acronym>API</acronym>
- documentation of <classname>Zend_Form_Element</classname> to learn about all of the
- available methods.
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 tw=80 et:
- -->
|