使用 Zend_Form 生成表单
虽然由 最基本的事情是实例化一个表单对象: <?php // Generic form object: $form = new Zend_Form(); // Custom form object: $form = new My_Form() ?> 你可以可选地传递配置参数,它用来设置对象状态以及可能生成新元素: <?php // Passing in configuration options: $form = new Zend_Form($config); ?>
插件加载器
下列加载器类型和不同的插件加载器方法 'element' 和 'decorator' 一起来使用。类型名大小写敏感。 用来和插件加载器结合使用的方法如下:
另外,也可以用下列方法为所有通过
定制元素和装饰器是在表单和封装定制函数之间共享功能的简便方法。在元素文档(elements documentation)中参见 Custom Label example ,看定制元素如何用来替换标准类。 元素(Elements)
添加元素的最基本的方法是 如一些例子: <?php // Using an element instance: $element = new Zend_Form_Element_Text('foo'); $form->addElement($element); // Using a factory // // Creates an element of type Zend_Form_Element_Text with the // name of 'foo': $form->addElement('text', 'foo'); // Pass label option to the element: $form->addElement('text', 'foo', array('label' => 'Foo:')); ?>
一旦元素被添加到表单,可以用名字来读取。通过使用 <?php // getElement(): $foo = $form->getElement('foo'); // As object property: $foo = $form->foo; ?>
偶尔地,你只想生成一个元素并不想把它加到表单上(例如,你想利用众多的用表单注册的插件路径,但稍后把这些对象加到子表单上)。 <?php // $username becomes a Zend_Form_Element_Text object: $username = $form->createElement('text', 'username'); ?> 组装和读取数值
校验表单之后,你一般需要读取它的数值以便执行其它操作,如更新数据库或通知一个 web 服务。你可以通过 <?php // Get all values: $values = $form->getValues(); // Get only 'foo' element's value: $value = $form->getValue('foo'); ?>
有时候,在解析之前,你想用特定的值来组装表单,可以通过 <?php $form->setDefaults($data); $form->populate($data); ?>
在另一面,你可能想在组装和校验之前清除一个表单,可使用 $form->reset(); 全局操作偶尔,你想用对所有元素进行特定的操作,一般的情形包括需要为所有元素设置插件前缀路径、装饰器和过滤器,如下例: Example #1 为所有元素设置前缀路径 可以通过类型来为所有的元素设置前缀路径,或者使用全局前缀,如这些例子: <?php // Set global prefix path: // Creates paths for prefixes My_Foo_Filter, My_Foo_Validate, // and My_Foo_Decorator $form->addElementPrefixPath('My_Foo', 'My/Foo/'); // Just filter paths: $form->addElementPrefixPath('My_Foo_Filter', 'My/Foo/Filter', 'filter'); // Just validator paths: $form->addElementPrefixPath('My_Foo_Validate', 'My/Foo/Validate', 'validate'); // Just decorator paths: $form->addElementPrefixPath('My_Foo_Decorator', 'My/Foo/Decorator', 'decorator'); ?> Example #2 为所有元素设置装饰器(Decorators)
你可以为所有元素设置装饰器。 <?php $form->setElementDecorators(array( 'ViewHelper', 'Label' )); ?> Example #3 为某些元素设置装饰器
你也可以对一个元素的子集设置装饰器,包含和排除都可以。
在下面的片段中,我们只对 'foo' 和 'bar' 元素使用视图助手和标签装饰器: $form->setElementDecorators( array( 'ViewHelper', 'Label' ), array( 'foo', 'bar' ) ); 另一方面,在这个片段中,我们对除了'foo' 元素 'bar'之外的所以元素使用视图助手和标签装饰器: $form->setElementDecorators( array( 'ViewHelper', 'Label' ), array( 'foo', 'bar' ), false );
Example #4 为所有元素设置过滤器
大多数情况下,你想对所有元素应用同一个过滤器,一个通常的用法是 <?php $form->setElementFilters(array('StringTrim')); ?> 和元素交互使用的方法下面的方法用来和元素交互使用:
显示组(Display Groups)显示组是生成要显示的虚拟元素组的一种方法。所有元素在表单中保持用名字可访问,但是当迭代或解析(rendering)所有表单的时候,任何在显示组中的元素将被一起解析(rendered)。最普通的用例是把(数据库表中的)字段组成一组元素。
显示组的基本类是 假定元素 'username' 和 'password'已经在表单中,下面的代码将把它们组成一个 'login'显示组: <?php $form->addDisplayGroup(array('username', 'password'), 'login'); ?>
你可以用 <?php // Using getDisplayGroup(): $login = $form->getDisplayGroup('login'); // Using overloading: $login = $form->login; ?>
全局操作就像对元素一样,一些操作可能影响所有的显示组,包括设置装饰器和寻找装饰器的插件路径。 Example #5 为所有的显示组设置装饰器前缀路径
缺省地,显示组继承表单所使用的任何一个装饰器的路径,然而,如果它们在另外的位置,可以使用这个方法: <?php $form->addDisplayGroupPrefixPath('My_Foo_Decorator', 'My/Foo/Decorator'); ?> Example #6 为所有显示组设置装饰器
你可以为所有的显示组设置装饰器。 <?php $form->setDisplayGroupDecorators(array( 'FormElements', 'Fieldset' )); ?> 使用定制的显示组类
缺省地, <?php // Use the 'My_DisplayGroup' class $form->addDisplayGroup( array('username', 'password'), 'user', array('displayGroupClass' => 'My_DisplayGroup') ); ?>
如果类没有加载, 你也可以指定一个缺省的显示组类来和表单一起使用,这样所有用这个表单对象生成的显示组将使用那个类: <?php // Use the 'My_DisplayGroup' class for all display groups: $form->setDefaultDisplayGroupClass('My_DisplayGroup'); ?> 这个设置可能在配置中指定为 'defaultDisplayGroupClass',并在早期加载以确保所有的显示组使用那个类。 和显示组交互使用的方法下列方法用来和显示组一起交互使用:
Zend_Form_DisplayGroup 方法
子表单子表单服务于如干目的:
子表单可以是 <?php $form->addSubForm($subForm, 'subform'); ?>
可以用 <?php // Using getSubForm(): $subForm = $form->getSubForm('subform'); // Using overloading: $subForm = $form->subform; ?> 虽然子表单包含的元素不包含在表单迭代中,但子表单包含在其中。 全局操作
像元素和显示组一样,有些操作可以影响所有的子表单。然而不像显示组和元素,子表单从主表单对象继承了最多的功能,并且唯一的需要全局执行的操作是为子表单设置装饰器, <?php $form->setSubFormDecorators(array( 'FormElements', 'Fieldset' )); ?> 和子表单交互使用的方法下列方法用来和子表单交互使用:
元数据(Metadata)和属性(Attributes)虽然表单的有效性基本源于它所包含的元素,但它也可以包含其它元数据,如名称(在 HTML 标记语言中经常用作唯一的 ID)、表单动作和方法、许多元素、组、它所包含的子表单和属性元数据(通常用做为表单标签自己设置 HTML 属性)。 可以使用名字访问器来设置和读取表单的名字: <?php // Set the name: $form->setName('registration'); // Retrieve the name: $name = $form->getName(); ?> 为了设置动作(到表单提交的 url )和方法(提交的方法如 'POST' 或 'GET'),使用动作和方法访问器: <?php // Set the action and method: $form->setAction('/user/login') ->setMethod('post'); ?>
你也可以指定特别使用 enctype 访问器的表单编码类型。
Zend_Form 定义了两个常量,
<?php // Set the action, method, and enctype: $form->setAction('/user/login') ->setMethod('post') ->setEnctype(Zend_Form::ENCTYPE_MULTIPART); ?>
<?php $numItems = count($form); ?>
设置任意元数据可通过属性访问器来完成。因为在 <?php // Setting attributes: $form->setAttrib('class', 'zend-form') ->addAttribs(array( 'id' => 'registration', 'onSubmit' => 'validate(this)', )); // Retrieving attributes: $class = $form->getAttrib('class'); $attribs = $form->getAttribs(); // Remove an attribute: $form->removeAttrib('onSubmit'); // Clear all attributes: $form->clearAttribs(); ?> 装饰器
为表单生成 markup 通常是一件耗时的任务,特别是如果打算重复使用同一个 markup 来显示校验错误、提交的值等。
<?php $form->setDecorators(array( 'FormElements', array('HtmlTag', array('tag' => 'dl')), 'Form' )); ?> 生成输出如下: <form action="/form/action" method="post"> <dl> ... </dl> </form>
在表单对象中的任何属性设置将用做
为生成表单,你可以生成自己的装饰器。一个通常的用例是如果你知道额外的你想用的 HTML,你的装饰器可以潜在地使用从独立的元素或显示组来的装饰器生成额外的 HTML 并返回它。 下列方法可以用来和装饰器交互使用:
校验
表单的一个基本用例是校验提交的数据。
为了校验整个表单,使用 <?php if (!$form->isValid($_POST)) { // failed validation } ?>
有时候你可能只需要校验数据的一个子集,可以使用 <?php if (!$form->isValidPartial($data)) { // failed validation } ?>
当为 AJAX 请求校验元素或元素组,你一般要校验表单的一个子集,并想要响应返回到 JSON。用 <?php $json = $form->processAjax($data); ?> 你可以发送 JSON 响应到客户端。如果表单有效,这将是个布尔 true 响应,如果表单无效,则是个包含 key/message 对的 javascript 对象,这里,每个 'message' 是校验错误消息的数组。
对于校验失败的表单,你可以分别使用 <?php $codes = $form->getErrors(); $messages = $form->getMessage(); ?>
你可以通过传递元素名为单个元素来获取代码和错误消息; <?php $codes = $form->getErrors('username'); $messages = $form->getMessages('username'); ?>
定制错误消息有时,你想定制一条或多条特定的错误消息来替代由附加到元素上的校验器所带的错误消息。 另外,有时候你想自己标记表单无效,从 1.6.0 版开始,通过下列方法来实现这个功能。
所有用这个方式设置的错误可以被翻译。 另外,你可以插入占位符 "%value%" 来表示元素的值;当读取到错误消息时,这个当前元素值将被替换。 方法
下面是
配置
作为通用的规则,如果 'set' + 选项键涉及 规则的异常包括下列这些:
作为一个例子,这里是一个为每个可配置数据传递配置的配置文件: [element] name = "registration" action = "/user/register" method = "post" attribs.class = "zend_form" attribs.onclick = "validate(this)" disableTranslator = 0 prefixPath.element.prefix = "My_Element" prefixPath.element.path = "My/Element/" elementPrefixPath.validate.prefix = "My_Validate" elementPrefixPath.validate.path = "My/Validate/" displayGroupPrefixPath.prefix = "My_Group" displayGroupPrefixPath.path = "My/Group/" elements.username.type = "text" elements.username.options.label = "Username" elements.username.options.validators.alpha.validator = "Alpha" elements.username.options.filters.lcase = "StringToLower" ; more elements, of course... elementFilters.trim = "StringTrim" ;elementDecorators.trim = "StringTrim" displayGroups.login.elements.username = "username" displayGroups.login.elements.password = "password" displayGroupDecorators.elements.decorator = "FormElements" displayGroupDecorators.fieldset.decorator = "Fieldset" decorators.elements.decorator = "FormElements" decorators.fieldset.decorator = "FieldSet" decorators.fieldset.decorator.options.class = "zend_form" decorators.form.decorator = "Form" ?> 上述可以很容易被抽象成 XML 或 PHP 基于数组的配置文件。 定制表单
一个使用基于配置的表单的替代方法是继承
最典型的用例是使用 <?php class My_Form_Login extends Zend_Form { public function init() { $username = new Zend_Form_Element_Text('username'); $username->class = 'formtext'; $username->setLabel('Username:') ->setDecorators(array( array('ViewHelper', array('helper' => 'formText')), array('Label', array('class' => 'label')) )); $password = new Zend_Form_Element_Password('password'); $password->class = 'formtext'; $password->setLabel('Username:') ->setDecorators(array( array('ViewHelper', array('helper' => 'formPassword')), array('Label', array('class' => 'label')) )); $submit = new Zend_Form_Element_Submit('login'); $submit->class = 'formsubmit'; $submit->setValue('Login') ->setDecorators(array( array('ViewHelper', array('helper' => 'formSubmit')) )); $this->addElements(array( $username, $password, $submit )); $this->setDecorators(array( 'FormElements', 'Fieldset', 'Form' )); } } ?> 这个表单可以简单地实例化: <?php $form = new My_Form_Login(); ?> 所有的功能已经设置并准备好了,不需要配置文件。(注意这个例子非常简化,因为它没有为元素包含校验器和过滤器。)
另一个普通的扩展原因是定义一组缺省的装饰器,可以通过覆盖(overriding) <?php class My_Form_Login extends Zend_Form { public function loadDefaultDecorators() { $this->setDecorators(array( 'FormElements', 'Fieldset', 'Form' )); } }
|