svn: /pear/peardoc/trunk/en/package/html/ html-quickform2/rules.xml html-quickform2.xml
[email protected] (Alexey Borzov) Sat, 12 Mar 2011 12:02:38 +0000
| Newsgroups | php.pear.doc |
|---|---|
| Message-ID | <[email protected]> |
avb Sat, 12 Mar 2011 12:02:38 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=309133
Log:
Validation in QF2
Changed paths:
A pear/peardoc/trunk/en/package/html/html-quickform2/rules.xml
U pear/peardoc/trunk/en/package/html/html-quickform2.xml
svn-diffs-309133.txt
(text/x-diff, 25.1 KB)
Added: pear/peardoc/trunk/en/package/html/html-quickform2/rules.xml
===================================================================
--- pear/peardoc/trunk/en/package/html/html-quickform2/rules.xml (rev 0)
+++ pear/peardoc/trunk/en/package/html/html-quickform2/rules.xml 2011-03-12 12:02:38 UTC (rev 309133)
@@ -0,0 +1,550 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:phd="http://www.php.net/ns/phd"
+ version="lillet"
+ xml:id="package.html.html-quickform2.rules"
+>
+ <refnamediv>
+ <refname>Rules and validation</refname>
+ <refpurpose>Checking that you get the values you need</refpurpose>
+ </refnamediv>
+ <refsection xml:id="package.html.html-quickform2.rules.intro">
+ <info>
+ <title>Introduction</title>
+ </info>
+ <para>
+ Server-side validation in HTML_QuickForm2 is performed by <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2::validate" /> method. Validation
+ rules doing actual checks on element values are implemented as subclasses of <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule" />, they are added to
+ elements via <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Node::addRule" />.
+ </para>
+ <para>
+ Basically, the form is invalid if it contains at least one invalid element. The element is
+ considered invalid if it has an error message (accessible by <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Node::getError" />) set and valid
+ otherwise. That error can appear in two different ways:
+ <itemizedlist>
+ <listitem><simpara>You can manually set an error message for an element using <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Node::setError"
+ />.</simpara></listitem>
+ <listitem><simpara>A rule added to the element will set an error message if it has such a message
+ and its validation routine returned &false;.</simpara></listitem>
+ </itemizedlist>
+ The latter happens in the course of executing <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2::validate" />. It iterates over all form's elements, for each
+ element calling <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Rule::validate">validate()</phd:pearapi> methods of all its rules in
+ the order they were added. As soon as an error is set on an element, its validation stops.
+ </para>
+ <tip>
+ <para>
+ Do not forget to provide an error message to the rule, otherwise the element will be considered
+ valid even if rule's validation routine returns &false;. Not setting an error message is only
+ useful when chaining (see below).
+ </para>
+ </tip>
+ <tip>
+ <para>
+ Some of the elements may perform additional hardcoded validation. For example, file uploads will
+ check the value of <literal>'error'</literal> field in <varname>$_FILES</varname> and assign a
+ relevant error message when file upload was attempted but failed.
+ </para>
+ </tip>
+ <example>
+ <info>
+ <title>Instantiating Rule objects directly</title>
+ </info>
+ <programlisting role="php">
+<![CDATA[
+require_once 'HTML/QuickForm2.php';
+require_once 'HTML/QuickForm2/Rule/Required.php';
+require_once 'HTML/QuickForm2/Rule/Regex.php';
+
+$form = new HTML_QuickForm2('tutorial');
+$username = $form->addElement('text', 'username');
+$form->addElement('submit', null, array('value' => 'Send!'));
+
+$username->addRule(new HTML_QuickForm2_Rule_Required(
+ $username, 'Username is required!'
+));
+$username->addRule(new HTML_QuickForm2_Rule_Regex(
+ $username, 'Username should contain only letters, digits and underscores', '/^[a-zA-Z0-9_]+$/'
+));
+
+if ($form->validate()) {
+ // process form
+}
+
+echo $form;
+]]>
+ </programlisting>
+ </example>
+ <para>
+ Of course, you will rarely need to instantiate Rule subclasses directly, Rule objects can be
+ created by <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Node::createRule" /> or automatically by
+ <function>addRule</function> if first parameter is a string representing registered rule type.
+ </para>
+ <example>
+ <info>
+ <title>Automatic creation of Rule objects</title>
+ </info>
+ <programlisting role="php">
+<![CDATA[
+require_once 'HTML/QuickForm2.php';
+
+$form = new HTML_QuickForm2('tutorial');
+$username = $form->addElement('text', 'username');
+$form->addElement('submit', null, array('value' => 'Send!'));
+
+$username->addRule('required', 'Username is required!');
+$username->addRule('regex', 'Username should contain only letters, digits and underscores',
+ '/^[a-zA-Z0-9_]+$/');
+
+if ($form->validate()) {
+ // process form
+}
+
+echo $form;
+]]>
+ </programlisting>
+ </example>
+ <para>
+ New rule types are registered by <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Factory::registerRule" /> which accepts rule type name,
+ corresponding class name and optionally file name containing that class and default configuration
+ data for all rules of the given type.
+ </para>
+ </refsection>
+
+
+ <refsection xml:id="package.html.html-quickform2.rules.list">
+ <info>
+ <title>Built-in validation rules</title>
+ </info>
+ <para>
+ For your convenience, all rules included in the package are already registered with
+ <classname>HTML_QuickForm2_Factory</classname> and can be easily created with
+ <function>createRule</function> / <function>addRule</function>. Some of the rule classes are
+ registered under several names with different configuration data to save keystrokes and improve
+ readability:
+ <programlisting role="php">
+<![CDATA[
+// these calls are identical
+$username->addRule('minlength', 'Username should be at least 4 characters long', 4);
+$username->addRule('length', 'Username should be at least 4 characters long', array('min' => 4));
+
+// as are these
+$start->addRule('lt', 'Start should be less than finish', $finish);
+$start->addRule('compare', 'Start should be less than finish',
+ array('operator' => '<', 'operand' => $finish));
+]]>
+ </programlisting>
+ </para>
+<!--
+ This table will look quite fucked-up due to a bug in current PhD_PEAR
+ See: http://bugs.php.net/bug.php?id=54208
+-->
+ <table>
+ <title>List of validation rules known to <classname>HTML_QuickForm2_Factory</classname></title>
+ <tgroup cols="4">
+ <colspec colname="name" />
+ <colspec colname="classname" />
+ <colspec colname="description" />
+ <colspec colname="config" />
+ <thead>
+ <row>
+ <entry>Rule name</entry>
+ <entry>Class name</entry>
+ <entry>Description</entry>
+ <entry>Configuration</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>nonempty</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Nonempty" /></entry>
+ <entry>Checks that the field is not empty</entry>
+ <entry>Minimum number of nonempty values for Containers / arrays, &type.integer;</entry>
+ </row>
+ <row>
+ <entry><varname>empty</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Empty" /></entry>
+ <entry>Checks that the field is empty</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><varname>required</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Required" /></entry>
+ <entry>Like <varname>nonempty</varname>, but the field is marked as required in output</entry>
+ <entry>Like <varname>nonempty</varname></entry>
+ </row>
+ <row valign="top">
+ <entry><varname>compare</varname></entry>
+ <entry morerows="6"><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Compare" /></entry>
+ <entry>Compares the value of the field with some other value using the given operator</entry>
+ <entry>
+ Either of the following:
+ <itemizedlist>
+ <listitem><simpara>operand</simpara></listitem>
+ <listitem><simpara>array([operator, ]operand)</simpara></listitem>
+ <listitem><simpara>array(['operator' => operator, ]['operand' => operand])</simpara></listitem>
+ </itemizedlist>
+ If operator is missing it will default to <literal>'==='</literal>. Operand can either be a
+ literal value or another form element.
+ </entry>
+ </row>
+ <row valign="top">
+ <entry><varname>eq</varname></entry>
+ <entry>As <varname>compare</varname> rule with hardcoded <literal>'==='</literal> operator</entry>
+ <entry morerows="1">Operand. The values are compared as strings.</entry>
+ </row>
+ <row>
+ <entry><varname>neq</varname></entry>
+ <entry>As <varname>compare</varname> rule with hardcoded <literal>'!=='</literal> operator</entry>
+ </row>
+ <row valign="top">
+ <entry><varname>lt</varname></entry>
+ <entry>As <varname>compare</varname> rule with hardcoded <literal>'<'</literal> operator</entry>
+ <entry morerows="3">Operand. The values are compared as numbers.</entry>
+ </row>
+ <row>
+ <entry><varname>lte</varname></entry>
+ <entry>As <varname>compare</varname> rule with hardcoded <literal>'<='</literal> operator</entry>
+ </row>
+ <row>
+ <entry><varname>gt</varname></entry>
+ <entry>As <varname>compare</varname> rule with hardcoded <literal>'>'</literal> operator</entry>
+ </row>
+ <row>
+ <entry><varname>gte</varname></entry>
+ <entry>As <varname>compare</varname> rule with hardcoded <literal>'>='</literal> operator</entry>
+ </row>
+ <row>
+ <entry><varname>regex</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Regex" /></entry>
+ <entry>Checks that the field value matches the given regular expression.</entry>
+ <entry>Regular expression, &type.string;. Use slashes for delimiters if you intend to do
+ client-side validation.</entry>
+ </row>
+ <row valign="top">
+ <entry><varname>callback</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Callback" /></entry>
+ <entry>Checks the value using a provided callback function (method). It is expected to return
+ &true; if the element is valid</entry>
+ <entry>Either of
+ <itemizedlist>
+ <listitem><simpara>A valid &type.callback;</simpara></listitem>
+ <listitem><simpara>array ('callback' => validation callback [, 'arguments' => additional arguments]
+ [, 'js_callback' => javascript callback for client-side validation])</simpara></listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row valign="top">
+ <entry><varname>length</varname></entry>
+ <entry morerows="2"><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Length" /></entry>
+ <entry>Checks that the value's length is within the given limits</entry>
+ <entry>
+ Either of
+ <itemizedlist>
+ <listitem><simpara>&type.integer; (rule checks for exact length)</simpara></listitem>
+ <listitem><simpara>array(minlength, maxlength)</simpara></listitem>
+ <listitem><simpara>array(['min' => minlength, ]['max' => maxlength])</simpara></listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row>
+ <entry><varname>minlength</varname></entry>
+ <entry>Checks that the value's length is at least the given number of characters</entry>
+ <entry>Minimal length, &type.integer;</entry>
+ </row>
+ <row>
+ <entry><varname>maxlength</varname></entry>
+ <entry>Checks that the value's length is at most the given number of characters</entry>
+ <entry>Maximal length, &type.integer;</entry>
+ </row>
+ <row>
+ <entry><varname>notcallback</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Rule_NotCallback" /></entry>
+ <entry>Checks the value using a provided callback function (method). It is expected to return
+ &false; if the element is valid.</entry>
+ <entry>Like <varname>callback</varname></entry>
+ </row>
+ <row>
+ <entry><varname>notregex</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_NotRegex" /></entry>
+ <entry>Checks that the field value <emphasis>does not match</emphasis> the given regular
+ expression.</entry>
+ <entry>Like <varname>regex</varname></entry>
+ </row>
+ <row>
+ <entry namest="name" nameend="config">Rules specific for <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Element_InputFile">file
+ uploads</phd:pearapi></entry>
+ </row>
+ <row>
+ <entry><varname>maxfilesize</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_MaxFileSize" /></entry>
+ <entry>Checks that uploaded file size does not exceed the given limit</entry>
+ <entry>Maximum allowed file size, &type.integer;</entry>
+ </row>
+ <row>
+ <entry><varname>mimetype</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_MimeType" /></entry>
+ <entry>Checks that uploaded file is of the correct MIME type</entry>
+ <entry>Allowed MIME type or an array of types</entry>
+ </row>
+ <row>
+ <entry namest="name" nameend="config">Rules specific for <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Container">containers</phd:pearapi></entry>
+ </row>
+ <row>
+ <entry><varname>each</varname></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule_Each" /></entry>
+ <entry>Validates all elements in a Container using a template Rule</entry>
+ <entry>Template Rule, instance of <classname>HTML_QuickForm2_Rule</classname></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <tip>
+ <para>
+ Usage of builtin rules is covered in <filename>builtin-rules.php</filename> example installed
+ with the package.
+ </para>
+ </tip>
+ </refsection>
+
+
+ <refsection xml:id="package.html.html-quickform2.rules.containers">
+ <info>
+ <title>Validating containers</title>
+ </info>
+ <para>
+ Most of the built-in rules are designed to check scalar values and will not work properly if
+ added to a Container (this includes <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Container_Group">Groups</phd:pearapi> and Group-based elements as
+ <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Element_Date">Date</phd:pearapi> and <phd:pearapi
+ phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Element_Hierselect">Hierselect</phd:pearapi>), as Containers return
+ their values in an associative array. One notable exception is <varname>nonempty</varname> /
+ <varname>required</varname> rule that can validate a container (or <literal><select
+ multiple="multiple" /></literal>):
+ </para>
+ <example>
+ <info>
+ <title>Checks that at least two checkboxes in a group are selected</title>
+ </info>
+ <programlisting role="php">
+<![CDATA[
+$boxGroup = $form->addElement('group', 'boxes')->setLabel('Check at least two:');
+$boxGroup->addElement('checkbox', null, array('value' => 'first'))->setContent('First');
+$boxGroup->addElement('checkbox', null, array('value' => 'second'))->setContent('Second');
+$boxGroup->addElement('checkbox', null, array('value' => 'third'))->setContent('Third');
+
+$boxGroup->addRule('required', 'Check at least two boxes', 2);
+]]>
+ </programlisting>
+ </example>
+ <para>
+ It is of course possible to implement a custom rule that will properly handle an associative
+ array as the element's value. It is also possible to leverage existing "scalar" rules
+ to validate Containers by using <varname>each</varname> rule, it applies a template rule to all the
+ elements in a Container and considers Container valid if its validation routine returns &true;
+ for all of them:
+ </para>
+ <example>
+ <info>
+ <title>Checks that all phone fields in a group contain numeric data</title>
+ </info>
+ <programlisting role="php">
+<![CDATA[
+$phones = $form->addElement('group', 'phones')->setLabel('Phones (numeric):')
+ ->setSeparator('<br />');
+$phones->addElement('text', '0');
+$phones->addElement('text', '1');
+
+$phones->addRule('each', 'Phones should be numeric',
+ $phones->createRule('regex', '', '/^\\d+([ -]\\d+)*$/'));
+]]>
+ </programlisting>
+ </example>
+ <tip>
+ <para>
+ More specific rules are run first: rules added to container will be checked after rules added to
+ its contained elements.
+ </para>
+ </tip>
+ </refsection>
+
+
+ <refsection xml:id="package.html.html-quickform2.rules.chaining">
+ <info>
+ <title>Chaining the rules</title>
+ </info>
+ <para>
+ HTML_QuickForm2 allows validation of elements based on values and validation status of other
+ elements. This is done by building a "chain" of validation rules using <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule::and_" /> and <phd:pearapi
+ phd:package="HTML_QuickForm2" phd:linkend="HTML_QuickForm2_Rule::or_" /> methods. Execution of
+ the chain starts with a rule that was added to an element, then results of other rules'
+ validation routines are combined using corresponding logical operators. Error is only set on the
+ element if the whole chain returned &false;.
+ </para>
+ <para>
+ Behaviour of <function>and_</function> and <function>or_</function> is similar to PHP's
+ <varname>and</varname> and <varname>or</varname> operators:
+ <itemizedlist>
+ <listitem><simpara><function>and_</function> has higher precedence than
+ <function>or_</function>.</simpara></listitem>
+ <listitem><simpara>Evaluation is short-circuited. If first argument of <function>and_</function>
+ evaluates to &false; then &false; is returned without evaluating second argument, if first
+ argument of <function>or_</function> evaluates to &true; then &true; is returned without
+ evaluating second argument.</simpara></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Rules that are added to the chain behave the same way as the rules that are added directly to the
+ element they validate (this is not necessarily the same element the chain is added to), they will
+ set an error if the rule itself returns &false;, not the chain. Thus it is often needed
+ <emphasis>not to provide</emphasis> error messages to the rules. It may also make sense to add a
+ chain of rules to a chain (this is similar to adding parentheses to a PHP expression with
+ <varname>and</varname> and <varname>or</varname>).
+ </para>
+ <example>
+ <info>
+ <title>Skips checking email field if "receive email" box is not checked</title>
+ </info>
+ <programlisting role="php">
+<![CDATA[
+$emailPresent = $email->createRule('nonempty', 'Supply a valid email if you want to receive our spam');
+// note lack of error message here, error should only be set by previous rule
+$emailValid = $email->createRule('callback', '', array('callback' => 'filter_var',
+ 'arguments' => array(FILTER_VALIDATE_EMAIL)));
+// note lack of error message for 'empty' rule, we don't want error on a checkbox
+$spamCheck->addRule('empty')
+ ->or_($emailPresent->and_($emailValid));
+]]>
+ </programlisting>
+ </example>
+ <example>
+ <info>
+ <title>Checks password fields in password change form</title>
+ </info>
+ <programlisting role="php">
+<![CDATA[
+$newPassword->addRule('empty')
+ ->and_($repPassword->createRule('empty'))
+ ->or_($newPassword->createRule('minlength', 'The password is too short', 6))
+ ->and_($repPassword->createRule('eq', 'The passwords do not match', $newPassword))
+ ->and_($oldPassword->createRule('nonempty', 'Supply old password if you want to change it'));
+]]>
+ </programlisting>
+ </example>
+ </refsection>
+
+
+ <refsection xml:id="package.html.html-quickform2.rules.clientside">
+ <info>
+ <title>Client-side validation</title>
+ </info>
+ <para>
+ You can tell a rule to also generate Javascript necessary for client-side validation. This is
+ done by passing a <parameter>$runAt</parameter> parameter with
+ <constant>HTML_QuickForm2_Rule::CLIENT</constant> flag set to <function>addRule</function>:
+ <programlisting role="php">
+<![CDATA[
+// if first parameter to addRule() is a string:
+$username->addRule('required', 'Username is required', null,
+ HTML_QuickForm2_Rule::SERVER | HTML_QuickForm2_Rule::CLIENT);
+// if first parameter to addRule() is a Rule instance:
+$username->addRule($username->createRule('required', 'Username is required'),
+ HTML_QuickForm2_Rule::SERVER | HTML_QuickForm2_Rule::CLIENT);
+]]>
+ </programlisting>
+ If more rules were chained to the added one with <function>and_</function> and
+ <function>or_</function>, Javascript will be generated for the whole chain.
+ </para>
+ <note>
+ <para>
+ While it is possible to add a client-side only rule
+ <programlisting role="php">
+<![CDATA[
+$username->addRule('minlength', 'Username should be at least 4 characters long', 4,
+ HTML_QuickForm2_Rule::CLIENT);
+]]>
+ </programlisting>
+ it is not recommended unless you perform the same validation server-side using some other rule.
+ </para>
+ </note>
+ <para>
+ Most of the built-in rules are able to run client-side, the only exceptions are
+ <varname>maxfilesize</varname> and <varname>mimetype</varname> rules specific for file uploads.
+ </para>
+ <tip>
+ <para>
+ If you want to run <varname>callback</varname> rule client-side, you will obviously need to
+ implement a callback in Javascript as well as in PHP. If you don't explicitly set
+ <parameter>'js_callback'</parameter> configuration parameter, <varname>callback</varname> rule
+ will try to run Javascript function having the same name as provided PHP
+ <parameter>'callback'</parameter>. This may be especially useful if you use
+ <classname>HTML_AJAX</classname> to create proxy classes in Javascript.
+ </para>
+ </tip>
+ <para>
+ Javascript for the rules is aggregated by <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_JavascriptBuilder" /> class when rendering a form and usually
+ output by a renderer. That class also tracks what Javascript libraries should be included in the
+ page before the form for client-side validation and javascript-backed elements to work. Libraries
+ are not output by default, you need either
+ <itemizedlist>
+ <listitem><para>
+ Call <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_JavascriptBuilder::getLibraries" /> to inline the libraries,
+ including their contents into the page
+ <programlisting role="php">
+<![CDATA[
+require_once 'HTML/QuickForm2/Renderer.php';
+
+$renderer = HTML_QuickForm2_Renderer::factory('default');
+$form->render($renderer);
+
+echo $renderer->getJavascriptBuilder()->getLibraries(true, true);
+echo $renderer;
+]]>
+ </programlisting>
+ </para></listitem>
+ <listitem><para>
+ Copy/symlink <filename>*.js</filename> files installed into <filename
+ role="dir">HTML_QuickForm2/</filename> directory under PEAR's <parameter>data_dir</parameter>
+ to some directory under your website's document root and provide this information to
+ JavascriptBuilder:
+ <programlisting role="php">
+<![CDATA[
+require_once 'HTML/QuickForm2/Renderer.php';
+require_once 'HTML/QuickForm2/JavascriptBuilder.php';
+
+$renderer = HTML_QuickForm2_Renderer::factory('default');
+// Here '/path/to/libraries' is whatever directory available via HTTP you copied libraries to
+$renderer->setJavascriptBuilder(new HTML_QuickForm2_JavascriptBuilder('/path/to/libraries'));
+$form->render($renderer);
+
+// This will output necessary <script src="/path/to/libraries/..."></script> tags
+foreach ($renderer->getJavascriptBuilder()->getLibraries() as $link) {
+ echo $link . "\n";
+}
+echo $renderer;
+]]>
+ </programlisting>
+ If you have trouble finding where <parameter>data_dir</parameter> is, you can use <link
+ linkend="guide.users.commandline.config">config-show</link> command of PEAR installer.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </refsection>
+</refentry>
Modified: pear/peardoc/trunk/en/package/html/html-quickform2.xml
===================================================================
--- pear/peardoc/trunk/en/package/html/html-quickform2.xml 2011-03-11 23:16:46 UTC (rev 309132)
+++ pear/peardoc/trunk/en/package/html/html-quickform2.xml 2011-03-12 12:02:38 UTC (rev 309133)
@@ -40,6 +40,7 @@
&package.html.html-quickform2.tutorial;
&package.html.html-quickform2.qf-migration;
&package.html.html-quickform2.values-datasources;
+ &package.html.html-quickform2.rules;
</chapter>
</book>