Zend_Form-Forms.xml 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.form.forms">
  4. <title>Creating Forms Using Zend_Form</title>
  5. <para>
  6. The <classname>Zend_Form</classname> class is used to aggregate form elements,
  7. display groups, and subforms. It can then perform the following actions
  8. on those items:
  9. </para>
  10. <itemizedlist>
  11. <listitem><para>
  12. Validation, including retrieving error codes and messages
  13. </para></listitem>
  14. <listitem><para>
  15. Value aggregation, including populating items and retrieving both
  16. filtered and unfiltered values from all items
  17. </para></listitem>
  18. <listitem><para>
  19. Iteration over all items, in the order in which they are entered or
  20. based on the order hints retrieved from each item
  21. </para></listitem>
  22. <listitem><para>
  23. Rendering of the entire form, either via a single decorator that
  24. performs custom rendering or by iterating over each item in the form
  25. </para></listitem>
  26. </itemizedlist>
  27. <para>
  28. While forms created with <classname>Zend_Form</classname> may be complex, probably
  29. the best use case is for simple forms; its best use is for Rapid
  30. Application Development (RAD) and prototyping.
  31. </para>
  32. <para>
  33. At its most basic, you simply instantiate a form object:
  34. </para>
  35. <programlisting language="php"><![CDATA[
  36. // Generic form object:
  37. $form = new Zend_Form();
  38. // Custom form object:
  39. $form = new My_Form()
  40. ]]></programlisting>
  41. <para>
  42. You can optionally pass in a instance of <classname>Zend_Config</classname> or an array,
  43. which will be used to set object state and potentially create new elements:
  44. </para>
  45. <programlisting language="php"><![CDATA[
  46. // Passing in configuration options:
  47. $form = new Zend_Form($config);
  48. ]]></programlisting>
  49. <para>
  50. <classname>Zend_Form</classname> is iterable, and will iterate over elements,
  51. display groups, and subforms, using the order they were registered and
  52. any order index each may have. This is useful in cases where you wish to
  53. render the elements manually in the appropriate order.
  54. </para>
  55. <para>
  56. <classname>Zend_Form</classname>'s magic lies in its ability to serve as a factory
  57. for elements and display groups, as well as the ability to render itself
  58. through decorators.
  59. </para>
  60. <sect2 id="zend.form.forms.plugins">
  61. <title>Plugin Loaders</title>
  62. <para>
  63. <classname>Zend_Form</classname> makes use of
  64. <classname>Zend_Loader_PluginLoader</classname> to allow developers to specify
  65. the locations of alternate elements and decorators. Each has its own
  66. plugin loader associated with it, and general accessors are used to
  67. retrieve and modify each.
  68. </para>
  69. <para>
  70. The following loader types are used with the various plugin loader
  71. methods: 'element' and 'decorator'. The type names are case
  72. insensitive.
  73. </para>
  74. <para>
  75. The methods used to interact with plugin loaders are as follows:
  76. </para>
  77. <itemizedlist>
  78. <listitem><para>
  79. <code>setPluginLoader($loader, $type)</code>: $loader is the
  80. plugin loader object itself, while type is one of the types
  81. specified above. This sets the plugin loader for the given type
  82. to the newly specified loader object.
  83. </para></listitem>
  84. <listitem><para>
  85. <code>getPluginLoader($type)</code>: retrieves the plugin loader
  86. associated with $type.
  87. </para></listitem>
  88. <listitem><para>
  89. <code>addPrefixPath($prefix, $path, $type = null)</code>: adds a
  90. prefix/path association to the loader specified by $type. If
  91. $type is null, it will attempt to add the path to all loaders,
  92. by appending the prefix with each of "_Element" and
  93. "_Decorator"; and appending the path with "Element/" and
  94. "Decorator/". If you have all your extra form element classes
  95. under a common hierarchy, this is a convenience method for
  96. setting the base prefix for them.
  97. </para></listitem>
  98. <listitem><para>
  99. <code>addPrefixPaths(array $spec)</code>: allows you to add many
  100. paths at once to one or more plugin loaders. It expects each
  101. array item to be an array with the keys 'path', 'prefix', and
  102. 'type'.
  103. </para></listitem>
  104. </itemizedlist>
  105. <para>
  106. Additionally, you can specify prefix paths for all elements and
  107. display groups created through a <classname>Zend_Form</classname> instance
  108. using the following methods:
  109. </para>
  110. <itemizedlist>
  111. <listitem><para>
  112. <code>addElementPrefixPath($prefix, $path, $type = null)</code>:
  113. Just like <code>addPrefixPath()</code>, you must specify a class
  114. prefix and a path. <code>$type</code>, when specified, must be
  115. one of the plugin loader types specified by
  116. <classname>Zend_Form_Element</classname>; see the <link
  117. linkend="zend.form.elements.loaders">element plugins
  118. section</link> for more information on valid
  119. <code>$type</code> values. If no <code>$type</code> is
  120. specified, the method will assume it is a general prefix for all
  121. types.
  122. </para></listitem>
  123. <listitem><para>
  124. <code>addDisplayGroupPrefixPath($prefix, $path)</code>:
  125. Just like <code>addPrefixPath()</code>, you must specify a class
  126. prefix and a path; however, since display groups only support
  127. decorators as plugins, no <code>$type</code> is necessary.
  128. </para></listitem>
  129. </itemizedlist>
  130. <para>
  131. Custom elements and decorators are an easy way to share
  132. functionality between forms and encapsulate custom functionality.
  133. See the <link
  134. linkend="zend.form.elements.loaders.customLabel">Custom Label
  135. example</link> in the elements documentation for an example of
  136. how custom elements can be used as replacements for standard
  137. classes.
  138. </para>
  139. </sect2>
  140. <sect2 id="zend.form.forms.elements">
  141. <title>Elements</title>
  142. <para>
  143. <classname>Zend_Form</classname> provides several accessors for adding and
  144. removing form elements from a form. These can take element object
  145. instances or serve as factories for instantiating the element
  146. objects themselves.
  147. </para>
  148. <para>
  149. The most basic method for adding an element is
  150. <code>addElement()</code>. This method can take either an object of
  151. type <classname>Zend_Form_Element</classname> (or of a class extending
  152. <classname>Zend_Form_Element</classname>), or arguments for building a new
  153. element -- including the element type, name, and any configuration
  154. options.
  155. </para>
  156. <para>
  157. Some examples:
  158. </para>
  159. <programlisting language="php"><![CDATA[
  160. // Using an element instance:
  161. $element = new Zend_Form_Element_Text('foo');
  162. $form->addElement($element);
  163. // Using a factory
  164. //
  165. // Creates an element of type Zend_Form_Element_Text with the
  166. // name of 'foo':
  167. $form->addElement('text', 'foo');
  168. // Pass label option to the element:
  169. $form->addElement('text', 'foo', array('label' => 'Foo:'));
  170. ]]></programlisting>
  171. <note>
  172. <title>addElement() Implements Fluent Interface</title>
  173. <para>
  174. <code>addElement()</code> implements a fluent interface; that is
  175. to say, it returns the <classname>Zend_Form</classname> object, and not
  176. the element. This is done to allow you to chain together
  177. multiple addElement() methods or other form methods that
  178. implement the fluent interface (all setters in <classname>Zend_Form</classname>
  179. implement the pattern).
  180. </para>
  181. <para>
  182. If you wish to return the element instead, use
  183. <code>createElement()</code>, which is outlined below. Be aware,
  184. however, that <code>createElement()</code> does not attach the
  185. element to the form.
  186. </para>
  187. <para>
  188. Internally, <code>addElement()</code> actually uses
  189. <code>createElement()</code> to create the element before
  190. attaching it to the form.
  191. </para>
  192. </note>
  193. <para>
  194. Once an element has been added to the form, you can retrieve it by
  195. name. This can be done either by using the <code>getElement()</code>
  196. method or by using overloading to access the element as an object
  197. property:
  198. </para>
  199. <programlisting language="php"><![CDATA[
  200. // getElement():
  201. $foo = $form->getElement('foo');
  202. // As object property:
  203. $foo = $form->foo;
  204. ]]></programlisting>
  205. <para>
  206. Occasionally, you may want to create an element without attaching it
  207. to the form (for instance, if you wish to make use of the various
  208. plugin paths registered with the form, but wish to later attach the
  209. object to a sub form). The <code>createElement()</code> method
  210. allows you to do so:
  211. </para>
  212. <programlisting language="php"><![CDATA[
  213. // $username becomes a Zend_Form_Element_Text object:
  214. $username = $form->createElement('text', 'username');
  215. ]]></programlisting>
  216. <sect3 id="zend.form.forms.elements.values">
  217. <title>Populating and Retrieving Values</title>
  218. <para>
  219. After validating a form, you will typically need to retrieve the
  220. values so you can perform other operations, such as updating a
  221. database or notifying a web service. You can retrieve all values
  222. for all elements using <code>getValues()</code>;
  223. <code>getValue($name)</code> allows you to retrieve a single
  224. element's value by element name:
  225. </para>
  226. <programlisting language="php"><![CDATA[
  227. // Get all values:
  228. $values = $form->getValues();
  229. // Get only 'foo' element's value:
  230. $value = $form->getValue('foo');
  231. ]]></programlisting>
  232. <para>
  233. Sometimes you'll want to populate the form with specified values
  234. prior to rendering. This can be done with either the
  235. <code>setDefaults()</code> or <code>populate()</code>
  236. methods:
  237. </para>
  238. <programlisting language="php"><![CDATA[
  239. $form->setDefaults($data);
  240. $form->populate($data);
  241. ]]></programlisting>
  242. <para>
  243. On the flip side, you may want to clear a form after populating
  244. or validating it; this can be done using the
  245. <code>reset()</code> method:
  246. </para>
  247. <programlisting language="php"><![CDATA[
  248. $form->reset();
  249. ]]></programlisting>
  250. </sect3>
  251. <sect3 id="zend.form.forms.elements.global">
  252. <title>Global Operations</title>
  253. <para>
  254. Occasionally you will want certain operations to affect all
  255. elements. Common scenarios include needing to set plugin prefix
  256. paths for all elements, setting decorators for all elements, and
  257. setting filters for all elements. As examples:
  258. </para>
  259. <example id="zend.form.forms.elements.global.allpaths">
  260. <title>Setting Prefix Paths for All Elements</title>
  261. <para>
  262. You can set prefix paths for all elements by type, or using
  263. a global prefix. Some examples:
  264. </para>
  265. <programlisting language="php"><![CDATA[
  266. // Set global prefix path:
  267. // Creates paths for prefixes My_Foo_Filter, My_Foo_Validate,
  268. // and My_Foo_Decorator
  269. $form->addElementPrefixPath('My_Foo', 'My/Foo/');
  270. // Just filter paths:
  271. $form->addElementPrefixPath('My_Foo_Filter',
  272. 'My/Foo/Filter',
  273. 'filter');
  274. // Just validator paths:
  275. $form->addElementPrefixPath('My_Foo_Validate',
  276. 'My/Foo/Validate',
  277. 'validate');
  278. // Just decorator paths:
  279. $form->addElementPrefixPath('My_Foo_Decorator',
  280. 'My/Foo/Decorator',
  281. 'decorator');
  282. ]]></programlisting>
  283. </example>
  284. <example id="zend.form.forms.elements.global.decorators">
  285. <title>Setting Decorators for All Elements</title>
  286. <para>
  287. You can set decorators for all elements.
  288. <code>setElementDecorators()</code> accepts an array of
  289. decorators, just like <code>setDecorators()</code>, and will
  290. overwrite any previously set decorators in each element. In
  291. this example, we set the decorators to simply a ViewHelper
  292. and a Label:
  293. </para>
  294. <programlisting language="php"><![CDATA[
  295. $form->setElementDecorators(array(
  296. 'ViewHelper',
  297. 'Label'
  298. ));
  299. ]]></programlisting>
  300. </example>
  301. <example id="zend.form.forms.elements.global.decoratorsFilter">
  302. <title>Setting Decorators for Some Elements</title>
  303. <para>
  304. You can also set decorators for a subset of elements,
  305. either by inclusion or exclusion. The second argument to
  306. <code>setElementDecorators()</code> may be an array of
  307. element names; by default, specifying such an array will
  308. set the specified decorators on those elements only. You
  309. may also pass a third argument, a flag indicating whether
  310. this list of elements is for inclusion or exclusion
  311. purposes. If the flag is false, it will decorate all elements
  312. <emphasis>except</emphasis> those in the passed list.
  313. As with standard usage of the method, any decorators passed
  314. will overwrite any previously set decorators in each
  315. element.
  316. </para>
  317. <para>
  318. In the following snippet, we indicate that we want only the
  319. ViewHelper and Label decorators for the 'foo' and 'bar'
  320. elements:
  321. </para>
  322. <programlisting language="php"><![CDATA[
  323. $form->setElementDecorators(
  324. array(
  325. 'ViewHelper',
  326. 'Label'
  327. ),
  328. array(
  329. 'foo',
  330. 'bar'
  331. )
  332. );
  333. ]]></programlisting>
  334. <para>
  335. On the flip side, with this snippet, we'll now indicate
  336. that we want to use only the ViewHelper and Label
  337. decorators for every element <emphasis>except</emphasis>
  338. the 'foo' and 'bar' elements:
  339. </para>
  340. <programlisting language="php"><![CDATA[
  341. $form->setElementDecorators(
  342. array(
  343. 'ViewHelper',
  344. 'Label'
  345. ),
  346. array(
  347. 'foo',
  348. 'bar'
  349. ),
  350. false
  351. );
  352. ]]></programlisting>
  353. </example>
  354. <note>
  355. <title>Some Decorators are Inappropriate for Some Elements</title>
  356. <para>
  357. While <code>setElementDecorators()</code> may seem like
  358. a good solution, there are some cases where it may
  359. actually end up with unexpected results. For example,
  360. the various button elements (Submit, Button, Reset)
  361. currently use the label as the value of the button,
  362. and only use ViewHelper and DtDdWrapper decorators --
  363. preventing an additional labels, errors, and hints from
  364. being rendered. The example above would duplicate some
  365. content (the label) for button elements.
  366. </para>
  367. <para>
  368. You can use the inclusion/exclusion array to overcome
  369. this issue as noted in the previous example.
  370. </para>
  371. <para>
  372. So, use this method wisely, and realize that you may
  373. need to exclude some elements or manually change some elements' decorators
  374. to prevent unwanted output.
  375. </para>
  376. </note>
  377. <example id="zend.form.forms.elements.global.filters">
  378. <title>Setting Filters for All Elements</title>
  379. <para>
  380. In some cases, you may want to apply the same filter to all
  381. elements; a common case is to <code>trim()</code> all values:
  382. </para>
  383. <programlisting language="php"><![CDATA[
  384. $form->setElementFilters(array('StringTrim'));
  385. ]]></programlisting>
  386. </example>
  387. </sect3>
  388. <sect3 id="zend.form.forms.elements.methods">
  389. <title>Methods For Interacting With Elements</title>
  390. <para>
  391. The following methods may be used to interact with elements:
  392. </para>
  393. <itemizedlist>
  394. <listitem><para>
  395. <code>createElement($element, $name = null, $options = null)</code>
  396. </para></listitem>
  397. <listitem><para>
  398. <code>addElement($element, $name = null, $options = null)</code>
  399. </para></listitem>
  400. <listitem><para>
  401. <code>addElements(array $elements)</code>
  402. </para></listitem>
  403. <listitem><para>
  404. <code>setElements(array $elements)</code>
  405. </para></listitem>
  406. <listitem><para>
  407. <code>getElement($name)</code>
  408. </para></listitem>
  409. <listitem><para>
  410. <code>getElements()</code>
  411. </para></listitem>
  412. <listitem><para>
  413. <code>removeElement($name)</code>
  414. </para></listitem>
  415. <listitem><para>
  416. <code>clearElements()</code>
  417. </para></listitem>
  418. <listitem><para>
  419. <code>setDefaults(array $defaults)</code>
  420. </para></listitem>
  421. <listitem><para>
  422. <code>setDefault($name, $value)</code>
  423. </para></listitem>
  424. <listitem><para>
  425. <code>getValue($name)</code>
  426. </para></listitem>
  427. <listitem><para>
  428. <code>getValues()</code>
  429. </para></listitem>
  430. <listitem><para>
  431. <code>getUnfilteredValue($name)</code>
  432. </para></listitem>
  433. <listitem><para>
  434. <code>getUnfilteredValues()</code>
  435. </para></listitem>
  436. <listitem><para>
  437. <code>setElementFilters(array $filters)</code>
  438. </para></listitem>
  439. <listitem><para>
  440. <code>setElementDecorators(array $decorators)</code>
  441. </para></listitem>
  442. <listitem><para>
  443. <code>addElementPrefixPath($prefix, $path, $type = null)</code>
  444. </para></listitem>
  445. <listitem><para>
  446. <code>addElementPrefixPaths(array $spec)</code>
  447. </para></listitem>
  448. </itemizedlist>
  449. </sect3>
  450. </sect2>
  451. <sect2 id="zend.form.forms.displaygroups">
  452. <title>Display Groups</title>
  453. <para>
  454. Display groups are a way to create virtual groupings of elements for
  455. display purposes. All elements remain accessible by name in the
  456. form, but when iterating over the form or rendering, any elements in
  457. a display group are rendered together. The most common use case for
  458. this is for grouping elements in fieldsets.
  459. </para>
  460. <para>
  461. The base class for display groups is
  462. <classname>Zend_Form_DisplayGroup</classname>. While it can be instantiated
  463. directly, it is usually best to use <classname>Zend_Form</classname>'s
  464. <code>addDisplayGroup()</code> method to do so. This method takes an
  465. array of elements as its first argument, and a name for the display
  466. group as its second argument. You may optionally pass in an array of
  467. options or a <classname>Zend_Config</classname> object as the third argument.
  468. </para>
  469. <para>
  470. Assuming that the elements 'username' and 'password' are already set
  471. in the form, the following code would group these elements in a
  472. 'login' display group:
  473. </para>
  474. <programlisting language="php"><![CDATA[
  475. $form->addDisplayGroup(array('username', 'password'), 'login');
  476. ]]></programlisting>
  477. <para>
  478. You can access display groups using the
  479. <code>getDisplayGroup()</code> method, or via overloading using the
  480. display group's name:
  481. </para>
  482. <programlisting language="php"><![CDATA[
  483. // Using getDisplayGroup():
  484. $login = $form->getDisplayGroup('login');
  485. // Using overloading:
  486. $login = $form->login;
  487. ]]></programlisting>
  488. <note>
  489. <title>Default Decorators Do Not Need to Be Loaded</title>
  490. <para>
  491. By default, the default decorators are loaded during object
  492. initialization. You can disable this by passing the
  493. 'disableLoadDefaultDecorators' option when creating a display
  494. group:
  495. </para>
  496. <programlisting language="php"><![CDATA[
  497. $form->addDisplayGroup(
  498. array('foo', 'bar'),
  499. 'foobar',
  500. array('disableLoadDefaultDecorators' => true)
  501. );
  502. ]]></programlisting>
  503. <para>
  504. This option may be mixed with any other options you pass,
  505. both as array options or in a <classname>Zend_Config</classname> object.
  506. </para>
  507. </note>
  508. <sect3 id="zend.form.forms.displaygroups.global">
  509. <title>Global Operations</title>
  510. <para>
  511. Just as with elements, there are some operations which might
  512. affect all display groups; these include setting decorators and
  513. setting the plugin path in which to look for decorators.
  514. </para>
  515. <example id="zend.form.forms.displaygroups.global.paths">
  516. <title>Setting Decorator Prefix Path for All Display Groups</title>
  517. <para>
  518. By default, display groups inherit whichever decorator paths
  519. the form uses; however, if they should look in alternate
  520. locations, you can use the
  521. <code>addDisplayGroupPrefixPath()</code> method.
  522. </para>
  523. <programlisting language="php"><![CDATA[
  524. $form->addDisplayGroupPrefixPath('My_Foo_Decorator', 'My/Foo/Decorator');
  525. ]]></programlisting>
  526. </example>
  527. <example id="zend.form.forms.displaygroups.global.decorators">
  528. <title>Setting Decorators for All Display Groups</title>
  529. <para>
  530. You can set decorators for all display groups.
  531. <code>setDisplayGroupDecorators()</code> accepts an array of
  532. decorators, just like <code>setDecorators()</code>, and will
  533. overwrite any previously set decorators in each display
  534. group. In this example, we set the decorators to simply a
  535. fieldset (the FormElements decorator is necessary to ensure
  536. that the elements are iterated):
  537. </para>
  538. <programlisting language="php"><![CDATA[
  539. $form->setDisplayGroupDecorators(array(
  540. 'FormElements',
  541. 'Fieldset'
  542. ));
  543. ]]></programlisting>
  544. </example>
  545. </sect3>
  546. <sect3 id="zend.form.forms.displaygroups.customClasses">
  547. <title>Using Custom Display Group Classes</title>
  548. <para>
  549. By default, <classname>Zend_Form</classname> uses the
  550. <classname>Zend_Form_DisplayGroup</classname> class for display groups.
  551. You may find you need to extend this class in order to provided
  552. custom functionality. <code>addDisplayGroup()</code> does not
  553. allow passing in a concrete instance, but does allow specifying
  554. the class to use as one of its options, using the
  555. 'displayGroupClass' key:
  556. </para>
  557. <programlisting language="php"><![CDATA[
  558. // Use the 'My_DisplayGroup' class
  559. $form->addDisplayGroup(
  560. array('username', 'password'),
  561. 'user',
  562. array('displayGroupClass' => 'My_DisplayGroup')
  563. );
  564. ]]></programlisting>
  565. <para>
  566. If the class has not yet been loaded, <classname>Zend_Form</classname>
  567. will attempt to do so using <classname>Zend_Loader</classname>.
  568. </para>
  569. <para>
  570. You can also specify a default display group class to use with
  571. the form such that all display groups created with the form
  572. object will use that class:
  573. </para>
  574. <programlisting language="php"><![CDATA[
  575. // Use the 'My_DisplayGroup' class for all display groups:
  576. $form->setDefaultDisplayGroupClass('My_DisplayGroup');
  577. ]]></programlisting>
  578. <para>
  579. This setting may be specified in configurations as
  580. 'defaultDisplayGroupClass', and will be loaded early to ensure
  581. all display groups use that class.
  582. </para>
  583. </sect3>
  584. <sect3 id="zend.form.forms.displaygroups.interactionmethods">
  585. <title>Methods for Interacting With Display Groups</title>
  586. <para>
  587. The following methods may be used to interact with display
  588. groups:
  589. </para>
  590. <itemizedlist>
  591. <listitem><para>
  592. <code>addDisplayGroup(array $elements, $name, $options = null)</code>
  593. </para></listitem>
  594. <listitem><para>
  595. <code>addDisplayGroups(array $groups)</code>
  596. </para></listitem>
  597. <listitem><para>
  598. <code>setDisplayGroups(array $groups)</code>
  599. </para></listitem>
  600. <listitem><para>
  601. <code>getDisplayGroup($name)</code>
  602. </para></listitem>
  603. <listitem><para>
  604. <code>getDisplayGroups()</code>
  605. </para></listitem>
  606. <listitem><para>
  607. <code>removeDisplayGroup($name)</code>
  608. </para></listitem>
  609. <listitem><para>
  610. <code>clearDisplayGroups()</code>
  611. </para></listitem>
  612. <listitem><para>
  613. <code>setDisplayGroupDecorators(array $decorators)</code>
  614. </para></listitem>
  615. <listitem><para>
  616. <code>addDisplayGroupPrefixPath($prefix, $path)</code>
  617. </para></listitem>
  618. <listitem><para>
  619. <code>setDefaultDisplayGroupClass($class)</code>
  620. </para></listitem>
  621. <listitem><para>
  622. <code>getDefaultDisplayGroupClass($class)</code>
  623. </para></listitem>
  624. </itemizedlist>
  625. </sect3>
  626. <sect3 id="zend.form.forms.displaygroups.methods">
  627. <title>Zend_Form_DisplayGroup Methods</title>
  628. <para>
  629. <classname>Zend_Form_DisplayGroup</classname> has the following methods,
  630. grouped by type:
  631. </para>
  632. <itemizedlist>
  633. <listitem><para>Configuration:</para>
  634. <itemizedlist>
  635. <listitem><para><code>setOptions(array $options)</code></para></listitem>
  636. <listitem>
  637. <para><code>setConfig(Zend_Config $config)</code></para>
  638. </listitem>
  639. </itemizedlist>
  640. </listitem>
  641. <listitem><para>Metadata:</para>
  642. <itemizedlist>
  643. <listitem><para><code>setAttrib($key, $value)</code></para></listitem>
  644. <listitem><para><code>addAttribs(array $attribs)</code></para></listitem>
  645. <listitem><para><code>setAttribs(array $attribs)</code></para></listitem>
  646. <listitem><para><code>getAttrib($key)</code></para></listitem>
  647. <listitem><para><code>getAttribs()</code></para></listitem>
  648. <listitem><para><code>removeAttrib($key)</code></para></listitem>
  649. <listitem><para><code>clearAttribs()</code></para></listitem>
  650. <listitem><para><code>setName($name)</code></para></listitem>
  651. <listitem><para><code>getName()</code></para></listitem>
  652. <listitem><para><code>setDescription($value)</code></para></listitem>
  653. <listitem><para><code>getDescription()</code></para></listitem>
  654. <listitem><para><code>setLegend($legend)</code></para></listitem>
  655. <listitem><para><code>getLegend()</code></para></listitem>
  656. <listitem><para><code>setOrder($order)</code></para></listitem>
  657. <listitem><para><code>getOrder()</code></para></listitem>
  658. </itemizedlist>
  659. </listitem>
  660. <listitem><para>Elements:</para>
  661. <itemizedlist>
  662. <listitem>
  663. <para>
  664. <code>createElement($type, $name, array $options = array())</code>
  665. </para>
  666. </listitem>
  667. <listitem>
  668. <para>
  669. <code>addElement($typeOrElement, $name, array $options =
  670. array())</code>
  671. </para>
  672. </listitem>
  673. <listitem><para><code>addElements(array $elements)</code></para></listitem>
  674. <listitem><para><code>setElements(array $elements)</code></para></listitem>
  675. <listitem><para><code>getElement($name)</code></para></listitem>
  676. <listitem><para><code>getElements()</code></para></listitem>
  677. <listitem><para><code>removeElement($name)</code></para></listitem>
  678. <listitem><para><code>clearElements()</code></para></listitem>
  679. </itemizedlist>
  680. </listitem>
  681. <listitem><para>Plugin loaders:</para>
  682. <itemizedlist>
  683. <listitem>
  684. <para>
  685. <code>setPluginLoader(Zend_Loader_PluginLoader $loader)</code>
  686. </para>
  687. </listitem>
  688. <listitem><para><code>getPluginLoader()</code></para></listitem>
  689. <listitem><para><code>addPrefixPath($prefix, $path)</code></para></listitem>
  690. <listitem><para><code>addPrefixPaths(array $spec)</code></para></listitem>
  691. </itemizedlist>
  692. </listitem>
  693. <listitem><para>Decorators:</para>
  694. <itemizedlist>
  695. <listitem>
  696. <para><code>addDecorator($decorator, $options = null)</code></para>
  697. </listitem>
  698. <listitem>
  699. <para><code>addDecorators(array $decorators)</code></para>
  700. </listitem>
  701. <listitem>
  702. <para><code>setDecorators(array $decorators)</code></para>
  703. </listitem>
  704. <listitem><para><code>getDecorator($name)</code></para></listitem>
  705. <listitem><para><code>getDecorators()</code></para></listitem>
  706. <listitem><para><code>removeDecorator($name)</code></para></listitem>
  707. <listitem><para><code>clearDecorators()</code></para></listitem>
  708. </itemizedlist>
  709. </listitem>
  710. <listitem><para>Rendering:</para>
  711. <itemizedlist>
  712. <listitem>
  713. <para><code>setView(Zend_View_Interface $view = null)</code></para>
  714. </listitem>
  715. <listitem><para><code>getView()</code></para></listitem>
  716. <listitem>
  717. <para><code>render(Zend_View_Interface $view = null)</code></para>
  718. </listitem>
  719. </itemizedlist>
  720. </listitem>
  721. <listitem><para>I18n:</para>
  722. <itemizedlist>
  723. <listitem>
  724. <para>
  725. <code>setTranslator(Zend_Translate_Adapter $translator =
  726. null)</code>
  727. </para>
  728. </listitem>
  729. <listitem><para><code>getTranslator()</code></para></listitem>
  730. <listitem><para><code>setDisableTranslator($flag)</code></para></listitem>
  731. <listitem><para><code>translatorIsDisabled()</code></para></listitem>
  732. </itemizedlist>
  733. </listitem>
  734. </itemizedlist>
  735. </sect3>
  736. </sect2>
  737. <sect2 id="zend.form.forms.subforms">
  738. <title>Sub Forms</title>
  739. <para>
  740. Sub forms serve several purposes:
  741. </para>
  742. <itemizedlist>
  743. <listitem><para>
  744. Creating logical element groups. Since sub forms are simply
  745. forms, you can validate subforms as individual entities.
  746. </para></listitem>
  747. <listitem><para>
  748. Creating multi-page forms. Since sub forms are simply forms, you
  749. can display a separate sub form per page, building up multi-page
  750. forms where each form has its own validation logic. Only once
  751. all sub forms validate would the form be considered complete.
  752. </para></listitem>
  753. <listitem><para>
  754. Display groupings. Like display groups, sub forms, when rendered
  755. as part of a larger form, can be used to group elements. Be
  756. aware, however, that the master form object will have no
  757. awareness of the elements in sub forms.
  758. </para></listitem>
  759. </itemizedlist>
  760. <para>
  761. A sub form may be a <classname>Zend_Form</classname> object, or, more
  762. typically, a <classname>Zend_Form_SubForm</classname> object. The latter
  763. contains decorators suitable for inclusion in a larger form (i.e.,
  764. it does not render additional HTML form tags, but does group
  765. elements). To attach a sub form, simply add it to the form and give
  766. it a name:
  767. </para>
  768. <programlisting language="php"><![CDATA[
  769. $form->addSubForm($subForm, 'subform');
  770. ]]></programlisting>
  771. <para>
  772. You can retrieve a sub form using either
  773. <code>getSubForm($name)</code> or overloading using the sub form
  774. name:
  775. </para>
  776. <programlisting language="php"><![CDATA[
  777. // Using getSubForm():
  778. $subForm = $form->getSubForm('subform');
  779. // Using overloading:
  780. $subForm = $form->subform;
  781. ]]></programlisting>
  782. <para>
  783. Sub forms are included in form iteration, although the elements they
  784. contain are not.
  785. </para>
  786. <sect3 id="zend.form.forms.subforms.global">
  787. <title>Global Operations</title>
  788. <para>
  789. Like elements and display groups, there are some operations that
  790. might need to affect all sub forms. Unlike display groups and
  791. elements, however, sub forms inherit most functionality from the
  792. master form object, and the only real operation that may need to
  793. be performed globally is setting decorators for sub forms. For
  794. this purpose, there is the <code>setSubFormDecorators()</code>
  795. method. In the next example, we'll set the decorator for all
  796. subforms to be simply a fieldset (the FormElements decorator is
  797. needed to ensure its elements are iterated):
  798. </para>
  799. <programlisting language="php"><![CDATA[
  800. $form->setSubFormDecorators(array(
  801. 'FormElements',
  802. 'Fieldset'
  803. ));
  804. ]]></programlisting>
  805. </sect3>
  806. <sect3 id="zend.form.forms.subforms.methods">
  807. <title>Methods for Interacting With Sub Forms</title>
  808. <para>
  809. The following methods may be used to interact with sub forms:
  810. </para>
  811. <itemizedlist>
  812. <listitem><para>
  813. <code>addSubForm(Zend_Form $form, $name, $order = null)</code>
  814. </para></listitem>
  815. <listitem><para>
  816. <code>addSubForms(array $subForms)</code>
  817. </para></listitem>
  818. <listitem><para>
  819. <code>setSubForms(array $subForms)</code>
  820. </para></listitem>
  821. <listitem><para>
  822. <code>getSubForm($name)</code>
  823. </para></listitem>
  824. <listitem><para>
  825. <code>getSubForms()</code>
  826. </para></listitem>
  827. <listitem><para>
  828. <code>removeSubForm($name)</code>
  829. </para></listitem>
  830. <listitem><para>
  831. <code>clearSubForms()</code>
  832. </para></listitem>
  833. <listitem><para>
  834. <code>setSubFormDecorators(array $decorators)</code>
  835. </para></listitem>
  836. </itemizedlist>
  837. </sect3>
  838. </sect2>
  839. <sect2 id="zend.form.forms.metadata">
  840. <title>Metadata and Attributes</title>
  841. <para>
  842. While a form's usefulness primarily derives from the elements it
  843. contains, it can also contain other metadata, such as a name (often
  844. used as a unique ID in the HTML markup); the form action and method;
  845. the number of elements, groups, and sub forms it contains; and
  846. arbitrary metadata (usually used to set HTML attributes for the form
  847. tag itself).
  848. </para>
  849. <para>
  850. You can set and retrieve a form's name using the name accessors:
  851. </para>
  852. <programlisting language="php"><![CDATA[
  853. // Set the name:
  854. $form->setName('registration');
  855. // Retrieve the name:
  856. $name = $form->getName();
  857. ]]></programlisting>
  858. <para>
  859. To set the action (url to which the form submits) and method (method
  860. by which it should submit, e.g., 'POST' or 'GET'), use the action
  861. and method accessors:
  862. </para>
  863. <programlisting language="php"><![CDATA[
  864. // Set the action and method:
  865. $form->setAction('/user/login')
  866. ->setMethod('post');
  867. ]]></programlisting>
  868. <para>
  869. You may also specify the form encoding type specifically using the
  870. enctype accessors. <classname>Zend_Form</classname> defines two constants,
  871. <classname>Zend_Form::ENCTYPE_URLENCODED</classname> and
  872. <classname>Zend_Form::ENCTYPE_MULTIPART</classname>, corresponding to the
  873. values 'application/x-www-form-urlencoded' and
  874. 'multipart/form-data', respectively; however, you can set this to
  875. any arbitrary encoding type.
  876. </para>
  877. <programlisting language="php"><![CDATA[
  878. // Set the action, method, and enctype:
  879. $form->setAction('/user/login')
  880. ->setMethod('post')
  881. ->setEnctype(Zend_Form::ENCTYPE_MULTIPART);
  882. ]]></programlisting>
  883. <note>
  884. <para>
  885. The method, action, and enctype are only used internally for rendering,
  886. and not for any sort of validation.
  887. </para>
  888. </note>
  889. <para>
  890. <classname>Zend_Form</classname> implements the <code>Countable</code>
  891. interface, allowing you to pass it as an argument to count:
  892. </para>
  893. <programlisting language="php"><![CDATA[
  894. $numItems = count($form);
  895. ]]></programlisting>
  896. <para>
  897. Setting arbitrary metadata is done through the attribs accessors.
  898. Since overloading in <classname>Zend_Form</classname> is used to access
  899. elements, display groups, and sub forms, this is the only method for
  900. accessing metadata.
  901. </para>
  902. <programlisting language="php"><![CDATA[
  903. // Setting attributes:
  904. $form->setAttrib('class', 'zend-form')
  905. ->addAttribs(array(
  906. 'id' => 'registration',
  907. 'onSubmit' => 'validate(this)',
  908. ));
  909. // Retrieving attributes:
  910. $class = $form->getAttrib('class');
  911. $attribs = $form->getAttribs();
  912. // Remove an attribute:
  913. $form->removeAttrib('onSubmit');
  914. // Clear all attributes:
  915. $form->clearAttribs();
  916. ]]></programlisting>
  917. </sect2>
  918. <sect2 id="zend.form.forms.decorators">
  919. <title>Decorators</title>
  920. <para>
  921. Creating the markup for a form is often a time-consuming task,
  922. particularly if you plan on re-using the same markup to show things
  923. such as validation errors, submitted values, etc.
  924. <classname>Zend_Form</classname>'s answer to this issue is
  925. <emphasis>decorators</emphasis>.
  926. </para>
  927. <para>
  928. Decorators for <classname>Zend_Form</classname> objects can be used to render
  929. a form. The FormElements decorator will iterate through all items in
  930. a form -- elements, display groups, and sub forms -- and render
  931. them, returning the result. Additional decorators may then be used
  932. to wrap this content, or append or prepend it.
  933. </para>
  934. <para>
  935. The default decorators for <classname>Zend_Form</classname> are FormElements,
  936. HtmlTag (wraps in a definition list), and Form; the equivalent code
  937. for creating them is as follows:
  938. </para>
  939. <programlisting language="php"><![CDATA[
  940. $form->setDecorators(array(
  941. 'FormElements',
  942. array('HtmlTag', array('tag' => 'dl')),
  943. 'Form'
  944. ));
  945. ]]></programlisting>
  946. <para>
  947. This creates output like the following:
  948. </para>
  949. <programlisting language="html"><![CDATA[
  950. <form action="/form/action" method="post">
  951. <dl>
  952. ...
  953. </dl>
  954. </form>
  955. ]]></programlisting>
  956. <para>
  957. Any attributes set on the form object will be used as HTML
  958. attributes of the <code>&lt;form&gt;</code> tag.
  959. </para>
  960. <note>
  961. <title>Default Decorators Do Not Need to Be Loaded</title>
  962. <para>
  963. By default, the default decorators are loaded during object
  964. initialization. You can disable this by passing the
  965. 'disableLoadDefaultDecorators' option to the constructor:
  966. </para>
  967. <programlisting language="php"><![CDATA[
  968. $form = new Zend_Form(array('disableLoadDefaultDecorators' => true));
  969. ]]></programlisting>
  970. <para>
  971. This option may be mixed with any other options you pass,
  972. both as array options or in a <classname>Zend_Config</classname> object.
  973. </para>
  974. </note>
  975. <note>
  976. <title>Using Multiple Decorators of the Same Type</title>
  977. <para>
  978. Internally, <classname>Zend_Form</classname> uses a decorator's
  979. class as the lookup mechanism when retrieving decorators. As a
  980. result, you cannot register multiple decorators of the same
  981. type; subsequent decorators will simply overwrite those that
  982. existed before.
  983. </para>
  984. <para>
  985. To get around this, you can use aliases. Instead of passing a
  986. decorator or decorator name as the first argument to
  987. <code>addDecorator()</code>, pass an array with a single
  988. element, with the alias pointing to the decorator object or
  989. name:
  990. </para>
  991. <programlisting language="php"><![CDATA[
  992. // Alias to 'FooBar':
  993. $form->addDecorator(array('FooBar' => 'HtmlTag'), array('tag' => 'div'));
  994. // And retrieve later:
  995. $form = $element->getDecorator('FooBar');
  996. ]]></programlisting>
  997. <para>
  998. In the <code>addDecorators()</code> and
  999. <code>setDecorators()</code> methods, you will need to pass
  1000. the 'decorator' option in the array representing the decorator:
  1001. </para>
  1002. <programlisting language="php"><![CDATA[
  1003. // Add two 'HtmlTag' decorators, aliasing one to 'FooBar':
  1004. $form->addDecorators(
  1005. array('HtmlTag', array('tag' => 'div')),
  1006. array(
  1007. 'decorator' => array('FooBar' => 'HtmlTag'),
  1008. 'options' => array('tag' => 'dd')
  1009. ),
  1010. );
  1011. // And retrieve later:
  1012. $htmlTag = $form->getDecorator('HtmlTag');
  1013. $fooBar = $form->getDecorator('FooBar');
  1014. ]]></programlisting>
  1015. </note>
  1016. <para>
  1017. You may create your own decorators for generating the form. One
  1018. common use case is if you know the exact HTML you wish to use; your
  1019. decorator could create the exact HTML and simply return it,
  1020. potentially using the decorators from individual elements or display
  1021. groups.
  1022. </para>
  1023. <para>
  1024. The following methods may be used to interact with decorators:
  1025. </para>
  1026. <itemizedlist>
  1027. <listitem><para>
  1028. <code>addDecorator($decorator, $options = null)</code>
  1029. </para></listitem>
  1030. <listitem><para>
  1031. <code>addDecorators(array $decorators)</code>
  1032. </para></listitem>
  1033. <listitem><para>
  1034. <code>setDecorators(array $decorators)</code>
  1035. </para></listitem>
  1036. <listitem><para>
  1037. <code>getDecorator($name)</code>
  1038. </para></listitem>
  1039. <listitem><para>
  1040. <code>getDecorators()</code>
  1041. </para></listitem>
  1042. <listitem><para>
  1043. <code>removeDecorator($name)</code>
  1044. </para></listitem>
  1045. <listitem><para>
  1046. <code>clearDecorators()</code>
  1047. </para></listitem>
  1048. </itemizedlist>
  1049. <para>
  1050. <classname>Zend_Form</classname> also uses overloading to allow rendering
  1051. specific decorators. <code>__call()</code> will intercept methods
  1052. that lead with the text 'render' and use the remainder of the method
  1053. name to lookup a decorator; if found, it will then render that
  1054. <emphasis>single</emphasis> decorator. Any arguments passed to the
  1055. method call will be used as content to pass to the decorator's
  1056. <code>render()</code> method. As an example:
  1057. </para>
  1058. <programlisting language="php"><![CDATA[
  1059. // Render only the FormElements decorator:
  1060. echo $form->renderFormElements();
  1061. // Render only the fieldset decorator, passing in content:
  1062. echo $form->renderFieldset("<p>This is fieldset content</p>");
  1063. ]]></programlisting>
  1064. <para>
  1065. If the decorator does not exist, an exception is raised.
  1066. </para>
  1067. </sect2>
  1068. <sect2 id="zend.form.forms.validation">
  1069. <title>Validation</title>
  1070. <para>
  1071. A primary use case for forms is validating submitted data.
  1072. <classname>Zend_Form</classname> allows you to validate an entire form, a partial form,
  1073. or responses for XmlHttpRequests (AJAX). If the submitted data is not valid, it has
  1074. methods for retrieving the various error codes and messages for
  1075. elements and sub forms.
  1076. </para>
  1077. <para>
  1078. To validate a full form, use the <code>isValid()</code> method:
  1079. </para>
  1080. <programlisting language="php"><![CDATA[
  1081. if (!$form->isValid($_POST)) {
  1082. // failed validation
  1083. }
  1084. ]]></programlisting>
  1085. <para>
  1086. <code>isValid()</code> will validate every required element, and any
  1087. unrequired element contained in the submitted data.
  1088. </para>
  1089. <para>
  1090. Sometimes you may need to validate only a subset of the data; for
  1091. this, use <code>isValidPartial($data)</code>:
  1092. </para>
  1093. <programlisting language="php"><![CDATA[
  1094. if (!$form->isValidPartial($data)) {
  1095. // failed validation
  1096. }
  1097. ]]></programlisting>
  1098. <para>
  1099. <code>isValidPartial()</code> only attempts to validate those items
  1100. in the data for which there are matching elements; if an element is
  1101. not represented in the data, it is skipped.
  1102. </para>
  1103. <para>
  1104. When validating elements or groups of elements for an AJAX request,
  1105. you will typically be validating a subset of the form, and want the
  1106. response back in JSON. <code>processAjax()</code> does precisely
  1107. that:
  1108. </para>
  1109. <programlisting language="php"><![CDATA[
  1110. $json = $form->processAjax($data);
  1111. ]]></programlisting>
  1112. <para>
  1113. You can then simply send the JSON response to the client. If the
  1114. form is valid, this will be a boolean true response. If not, it will
  1115. be a javascript object containing key/message pairs, where each
  1116. 'message' is an array of validation error messages.
  1117. </para>
  1118. <para>
  1119. For forms that fail validation, you can retrieve both error codes
  1120. and error messages, using <code>getErrors()</code> and
  1121. <code>getMessages()</code>, respectively:
  1122. </para>
  1123. <programlisting language="php"><![CDATA[
  1124. $codes = $form->getErrors();
  1125. $messages = $form->getMessages();
  1126. ]]></programlisting>
  1127. <note>
  1128. <para>
  1129. Since the messages returned by <code>getMessages()</code> are an
  1130. array of error code/message pairs, <code>getErrors()</code> is
  1131. typically not needed.
  1132. </para>
  1133. </note>
  1134. <para>
  1135. You can retrieve codes and error messages for individual elements by
  1136. simply passing the element name to each:
  1137. </para>
  1138. <programlisting language="php"><![CDATA[
  1139. $codes = $form->getErrors('username');
  1140. $messages = $form->getMessages('username');
  1141. ]]></programlisting>
  1142. <note>
  1143. <para>
  1144. Note: When validating elements, <classname>Zend_Form</classname> sends a
  1145. second argument to each element's <code>isValid()</code> method:
  1146. the array of data being validated. This can then be used by
  1147. individual validators to allow them to utilize other submitted
  1148. values when determining the validity of the data. An example
  1149. would be a registration form that requires both a password and
  1150. password confirmation; the password element could use the
  1151. password confirmation as part of its validation.
  1152. </para>
  1153. </note>
  1154. <sect3 id="zend.form.forms.validation.errors">
  1155. <title>Custom Error Messages</title>
  1156. <para>
  1157. At times, you may want to specify one or more specific error
  1158. messages to use instead of the error messages generated by the
  1159. validators attached to your elements. Additionally, at times you
  1160. may want to mark the form invalid yourself. This
  1161. functionality is possible via the following methods.
  1162. </para>
  1163. <itemizedlist>
  1164. <listitem><para>
  1165. <code>addErrorMessage($message)</code>: add an error message
  1166. to display on form validation errors. You may call this more
  1167. than once, and new messages are appended to the stack.
  1168. </para></listitem>
  1169. <listitem><para>
  1170. <code>addErrorMessages(array $messages)</code>: add multiple
  1171. error messages to display on form validation errors.
  1172. </para></listitem>
  1173. <listitem><para>
  1174. <code>setErrorMessages(array $messages)</code>: add multiple
  1175. error messages to display on form validation errors,
  1176. overwriting all previously set error messages.
  1177. </para></listitem>
  1178. <listitem><para>
  1179. <code>getErrorMessages()</code>: retrieve the list of
  1180. custom error messages that have been defined.
  1181. </para></listitem>
  1182. <listitem><para>
  1183. <code>clearErrorMessages()</code>: remove all custom error
  1184. messages that have been defined.
  1185. </para></listitem>
  1186. <listitem><para>
  1187. <code>markAsError()</code>: mark the form as having
  1188. failed validation.
  1189. </para></listitem>
  1190. <listitem><para>
  1191. <code>addError($message)</code>: add a message to the custom
  1192. error messages stack and flag the form as invalid.
  1193. </para></listitem>
  1194. <listitem><para>
  1195. <code>addErrors(array $messages)</code>: add several
  1196. messages to the custom error messages stack and flag the
  1197. form as invalid.
  1198. </para></listitem>
  1199. <listitem><para>
  1200. <code>setErrors(array $messages)</code>: overwrite the
  1201. custom error messages stack with the provided messages and
  1202. flag the form as invalid.
  1203. </para></listitem>
  1204. </itemizedlist>
  1205. <para>
  1206. All errors set in this fashion may be translated.
  1207. </para>
  1208. </sect3>
  1209. </sect2>
  1210. <sect2 id="zend.form.forms.methods">
  1211. <title>Methods</title>
  1212. <para>
  1213. The following is a full list of methods available to
  1214. <classname>Zend_Form</classname>, grouped by type:
  1215. </para>
  1216. <itemizedlist>
  1217. <listitem><para>Configuration and Options:</para>
  1218. <itemizedlist>
  1219. <listitem><para><code>setOptions(array $options)</code></para></listitem>
  1220. <listitem><para><code>setConfig(Zend_Config $config)</code></para></listitem>
  1221. </itemizedlist>
  1222. </listitem>
  1223. <listitem><para>Plugin Loaders and paths:</para>
  1224. <itemizedlist>
  1225. <listitem>
  1226. <para>
  1227. <code>setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type
  1228. = null)</code>
  1229. </para>
  1230. </listitem>
  1231. <listitem><para><code>getPluginLoader($type = null)</code></para></listitem>
  1232. <listitem>
  1233. <para><code>addPrefixPath($prefix, $path, $type = null) </code></para>
  1234. </listitem>
  1235. <listitem><para><code>addPrefixPaths(array $spec)</code></para></listitem>
  1236. <listitem>
  1237. <para><code>addElementPrefixPath($prefix, $path, $type = null)</code></para>
  1238. </listitem>
  1239. <listitem>
  1240. <para><code>addElementPrefixPaths(array $spec)</code></para>
  1241. </listitem>
  1242. <listitem>
  1243. <para><code>addDisplayGroupPrefixPath($prefix, $path)</code></para>
  1244. </listitem>
  1245. </itemizedlist>
  1246. </listitem>
  1247. <listitem><para>Metadata:</para>
  1248. <itemizedlist>
  1249. <listitem><para><code>setAttrib($key, $value)</code></para></listitem>
  1250. <listitem><para><code>addAttribs(array $attribs)</code></para></listitem>
  1251. <listitem><para><code>setAttribs(array $attribs)</code></para></listitem>
  1252. <listitem><para><code>getAttrib($key)</code></para></listitem>
  1253. <listitem><para><code>getAttribs()</code></para></listitem>
  1254. <listitem><para><code>removeAttrib($key)</code></para></listitem>
  1255. <listitem><para><code>clearAttribs()</code></para></listitem>
  1256. <listitem><para><code>setAction($action)</code></para></listitem>
  1257. <listitem><para><code>getAction()</code></para></listitem>
  1258. <listitem><para><code>setMethod($method)</code></para></listitem>
  1259. <listitem><para><code>getMethod()</code></para></listitem>
  1260. <listitem><para><code>setName($name)</code></para></listitem>
  1261. <listitem><para><code>getName()</code></para></listitem>
  1262. </itemizedlist>
  1263. </listitem>
  1264. <listitem><para>Elements:</para>
  1265. <itemizedlist>
  1266. <listitem><para><code>addElement($element, $name = null, $options = null)</code></para></listitem>
  1267. <listitem><para><code>addElements(array $elements)</code></para></listitem>
  1268. <listitem><para><code>setElements(array $elements)</code></para></listitem>
  1269. <listitem><para><code>getElement($name)</code></para></listitem>
  1270. <listitem><para><code>getElements()</code></para></listitem>
  1271. <listitem><para><code>removeElement($name)</code></para></listitem>
  1272. <listitem><para><code>clearElements()</code></para></listitem>
  1273. <listitem><para><code>setDefaults(array $defaults)</code></para></listitem>
  1274. <listitem><para><code>setDefault($name, $value)</code></para></listitem>
  1275. <listitem><para><code>getValue($name)</code></para></listitem>
  1276. <listitem><para><code>getValues()</code></para></listitem>
  1277. <listitem><para><code>getUnfilteredValue($name)</code></para></listitem>
  1278. <listitem><para><code>getUnfilteredValues()</code></para></listitem>
  1279. <listitem><para><code>setElementFilters(array $filters)</code></para></listitem>
  1280. <listitem>
  1281. <para><code>setElementDecorators(array $decorators)</code></para>
  1282. </listitem>
  1283. </itemizedlist>
  1284. </listitem>
  1285. <listitem><para>Sub forms:</para>
  1286. <itemizedlist>
  1287. <listitem>
  1288. <para><code>addSubForm(Zend_Form $form, $name, $order = null)</code></para>
  1289. </listitem>
  1290. <listitem><para><code>addSubForms(array $subForms)</code></para></listitem>
  1291. <listitem><para><code>setSubForms(array $subForms)</code></para></listitem>
  1292. <listitem><para><code>getSubForm($name)</code></para></listitem>
  1293. <listitem><para><code>getSubForms()</code></para></listitem>
  1294. <listitem><para><code>removeSubForm($name)</code></para></listitem>
  1295. <listitem><para><code>clearSubForms()</code></para></listitem>
  1296. <listitem>
  1297. <para><code>setSubFormDecorators(array $decorators)</code></para>
  1298. </listitem>
  1299. </itemizedlist>
  1300. </listitem>
  1301. <listitem><para>Display groups:</para>
  1302. <itemizedlist>
  1303. <listitem>
  1304. <para>
  1305. <code>addDisplayGroup(array $elements, $name, $options = null)</code>
  1306. </para>
  1307. </listitem>
  1308. <listitem><para><code>addDisplayGroups(array $groups)</code></para></listitem>
  1309. <listitem><para><code>setDisplayGroups(array $groups)</code></para></listitem>
  1310. <listitem><para><code>getDisplayGroup($name)</code></para></listitem>
  1311. <listitem><para><code>getDisplayGroups()</code></para></listitem>
  1312. <listitem><para><code>removeDisplayGroup($name)</code></para></listitem>
  1313. <listitem><para><code>clearDisplayGroups()</code></para></listitem>
  1314. <listitem>
  1315. <para><code>setDisplayGroupDecorators(array $decorators)</code></para>
  1316. </listitem>
  1317. </itemizedlist>
  1318. </listitem>
  1319. <listitem><para>Validation</para>
  1320. <itemizedlist>
  1321. <listitem><para><code>populate(array $values)</code></para></listitem>
  1322. <listitem><para><code>isValid(array $data)</code></para></listitem>
  1323. <listitem><para><code>isValidPartial(array $data)</code></para></listitem>
  1324. <listitem><para><code>processAjax(array $data)</code></para></listitem>
  1325. <listitem><para><code>persistData()</code></para></listitem>
  1326. <listitem><para><code>getErrors($name = null)</code></para></listitem>
  1327. <listitem><para><code>getMessages($name = null)</code></para></listitem>
  1328. </itemizedlist>
  1329. </listitem>
  1330. <listitem><para>Rendering:</para>
  1331. <itemizedlist>
  1332. <listitem>
  1333. <para><code>setView(Zend_View_Interface $view = null)</code></para>
  1334. </listitem>
  1335. <listitem><para><code>getView()</code></para></listitem>
  1336. <listitem>
  1337. <para><code>addDecorator($decorator, $options = null)</code></para>
  1338. </listitem>
  1339. <listitem><para><code>addDecorators(array $decorators)</code></para></listitem>
  1340. <listitem><para><code>setDecorators(array $decorators)</code></para></listitem>
  1341. <listitem><para><code>getDecorator($name)</code></para></listitem>
  1342. <listitem><para><code>getDecorators()</code></para></listitem>
  1343. <listitem><para><code>removeDecorator($name)</code></para></listitem>
  1344. <listitem><para><code>clearDecorators()</code></para></listitem>
  1345. <listitem>
  1346. <para><code>render(Zend_View_Interface $view = null)</code></para>
  1347. </listitem>
  1348. </itemizedlist>
  1349. </listitem>
  1350. <listitem><para>I18n:</para>
  1351. <itemizedlist>
  1352. <listitem>
  1353. <para>
  1354. <code>setTranslator(Zend_Translate_Adapter $translator = null)</code>
  1355. </para>
  1356. </listitem>
  1357. <listitem><para><code>getTranslator()</code></para></listitem>
  1358. <listitem><para><code>setDisableTranslator($flag)</code></para></listitem>
  1359. <listitem><para><code>translatorIsDisabled()</code></para></listitem>
  1360. </itemizedlist>
  1361. </listitem>
  1362. </itemizedlist>
  1363. </sect2>
  1364. <sect2 id="zend.form.forms.config">
  1365. <title>Configuration</title>
  1366. <para>
  1367. <classname>Zend_Form</classname> is fully configurable via
  1368. <code>setOptions()</code> and <code>setConfig()</code> (or by
  1369. passing options or a <classname>Zend_Config</classname> object to the
  1370. constructor). Using these methods, you can specify form elements,
  1371. display groups, decorators, and metadata.
  1372. </para>
  1373. <para>
  1374. As a general rule, if 'set' + the option key refers to a
  1375. <classname>Zend_Form</classname> method, then the value provided will be
  1376. passed to that method. If the accessor does not exist, the key is
  1377. assumed to reference an attribute, and will be passed to
  1378. <code>setAttrib()</code>.
  1379. </para>
  1380. <para>
  1381. Exceptions to the rule include the following:
  1382. </para>
  1383. <itemizedlist>
  1384. <listitem><para>
  1385. <code>prefixPaths</code> will be passed to
  1386. <code>addPrefixPaths()</code>
  1387. </para></listitem>
  1388. <listitem><para>
  1389. <code>elementPrefixPaths</code> will be passed to
  1390. <code>addElementPrefixPaths()</code>
  1391. </para></listitem>
  1392. <listitem><para>
  1393. <code>displayGroupPrefixPaths</code> will be passed to
  1394. <code>addDisplayGroupPrefixPaths()</code>
  1395. </para></listitem>
  1396. <listitem>
  1397. <para>the following setters cannot be set in this way:</para>
  1398. <itemizedlist>
  1399. <listitem>
  1400. <para><code>setAttrib (though setAttribs *will* work)</code></para>
  1401. </listitem>
  1402. <listitem><para><code>setConfig</code></para></listitem>
  1403. <listitem><para><code>setDefault</code></para></listitem>
  1404. <listitem><para><code>setOptions</code></para></listitem>
  1405. <listitem><para><code>setPluginLoader</code></para></listitem>
  1406. <listitem><para><code>setSubForms</code></para></listitem>
  1407. <listitem><para><code>setTranslator</code></para></listitem>
  1408. <listitem><para><code>setView</code></para></listitem>
  1409. </itemizedlist>
  1410. </listitem>
  1411. </itemizedlist>
  1412. <para>
  1413. As an example, here is a config file that passes configuration for
  1414. every type of configurable data:
  1415. </para>
  1416. <programlisting language="ini"><![CDATA[
  1417. [element]
  1418. name = "registration"
  1419. action = "/user/register"
  1420. method = "post"
  1421. attribs.class = "zend_form"
  1422. attribs.onclick = "validate(this)"
  1423. disableTranslator = 0
  1424. prefixPath.element.prefix = "My_Element"
  1425. prefixPath.element.path = "My/Element/"
  1426. elementPrefixPath.validate.prefix = "My_Validate"
  1427. elementPrefixPath.validate.path = "My/Validate/"
  1428. displayGroupPrefixPath.prefix = "My_Group"
  1429. displayGroupPrefixPath.path = "My/Group/"
  1430. elements.username.type = "text"
  1431. elements.username.options.label = "Username"
  1432. elements.username.options.validators.alpha.validator = "Alpha"
  1433. elements.username.options.filters.lcase = "StringToLower"
  1434. ; more elements, of course...
  1435. elementFilters.trim = "StringTrim"
  1436. ;elementDecorators.trim = "StringTrim"
  1437. displayGroups.login.elements.username = "username"
  1438. displayGroups.login.elements.password = "password"
  1439. displayGroupDecorators.elements.decorator = "FormElements"
  1440. displayGroupDecorators.fieldset.decorator = "Fieldset"
  1441. decorators.elements.decorator = "FormElements"
  1442. decorators.fieldset.decorator = "FieldSet"
  1443. decorators.fieldset.decorator.options.class = "zend_form"
  1444. decorators.form.decorator = "Form"
  1445. ]]></programlisting>
  1446. <para>
  1447. The above could easily be abstracted to an XML or PHP array-based
  1448. configuration file.
  1449. </para>
  1450. </sect2>
  1451. <sect2 id="zend.form.forms.custom">
  1452. <title>Custom forms</title>
  1453. <para>
  1454. An alternative to using configuration-based forms is to subclass
  1455. <classname>Zend_Form</classname>. This has several benefits:
  1456. </para>
  1457. <itemizedlist>
  1458. <listitem><para>
  1459. You can unit test your form easily to ensure validations and
  1460. rendering perform as expected.
  1461. </para></listitem>
  1462. <listitem><para>
  1463. Fine-grained control over individual elements.
  1464. </para></listitem>
  1465. <listitem><para>
  1466. Re-use of form objects, and greater portability (no need to
  1467. track config files).
  1468. </para></listitem>
  1469. <listitem><para>
  1470. Implementing custom functionality.
  1471. </para></listitem>
  1472. </itemizedlist>
  1473. <para>
  1474. The most typical use case would be to use the
  1475. <code>init()</code> method to setup specific form elements and
  1476. configuration:
  1477. </para>
  1478. <programlisting language="php"><![CDATA[
  1479. class My_Form_Login extends Zend_Form
  1480. {
  1481. public function init()
  1482. {
  1483. $username = new Zend_Form_Element_Text('username');
  1484. $username->class = 'formtext';
  1485. $username->setLabel('Username:')
  1486. ->setDecorators(array(
  1487. array('ViewHelper',
  1488. array('helper' => 'formText')),
  1489. array('Label',
  1490. array('class' => 'label'))
  1491. ));
  1492. $password = new Zend_Form_Element_Password('password');
  1493. $password->class = 'formtext';
  1494. $password->setLabel('Username:')
  1495. ->setDecorators(array(
  1496. array('ViewHelper',
  1497. array('helper' => 'formPassword')),
  1498. array('Label',
  1499. array('class' => 'label'))
  1500. ));
  1501. $submit = new Zend_Form_Element_Submit('login');
  1502. $submit->class = 'formsubmit';
  1503. $submit->setValue('Login')
  1504. ->setDecorators(array(
  1505. array('ViewHelper',
  1506. array('helper' => 'formSubmit'))
  1507. ));
  1508. $this->addElements(array(
  1509. $username,
  1510. $password,
  1511. $submit
  1512. ));
  1513. $this->setDecorators(array(
  1514. 'FormElements',
  1515. 'Fieldset',
  1516. 'Form'
  1517. ));
  1518. }
  1519. }
  1520. ]]></programlisting>
  1521. <para>
  1522. This form can then be instantiated with simply:
  1523. </para>
  1524. <programlisting language="php"><![CDATA[
  1525. $form = new My_Form_Login();
  1526. ]]></programlisting>
  1527. <para>
  1528. and all functionality is already setup and ready; no config files
  1529. needed. (Note that this example is greatly simplified, as it
  1530. contains no validators or filters for the elements.)
  1531. </para>
  1532. <para>
  1533. Another common reason for extension is to define a set of
  1534. default decorators. You can do this by overriding the
  1535. <code>loadDefaultDecorators()</code> method:
  1536. </para>
  1537. <programlisting language="php"><![CDATA[
  1538. class My_Form_Login extends Zend_Form
  1539. {
  1540. public function loadDefaultDecorators()
  1541. {
  1542. $this->setDecorators(array(
  1543. 'FormElements',
  1544. 'Fieldset',
  1545. 'Form'
  1546. ));
  1547. }
  1548. }
  1549. ]]></programlisting>
  1550. </sect2>
  1551. </sect1>
  1552. <!--
  1553. vim:se ts=4 sw=4 et:
  1554. -->