我已多次阅读本手册,我已经仔细阅读了谷歌提供的关于这个主题的帖子,我甚至买了几本与ZF有关的书。现在,为什么我仍然困惑?
我可以使用Zend_Form创建一个验证和运行良好的表单。我无法做到的是一个看起来完全像我希望它看到我想要它的错误消息的表单。我想要自定义按钮,我想要时髦的布局,我想在表格中间插入文字等。
有没有人有一种简单的方法来实现这些事情?让我觉得这个框架的东西能节省我的时间而不是花钱吗?我可以放弃Zend Form ...制作我自己的表单,让它的动作点击页面来验证和处理发布的数据,我可以尽可能快地输入,但我真的想“得到”这个并且能够使用它,因为它显然是有意的。
有什么建议吗?任何简单的“如何做”自定义按钮,时髦的布局和基本(或者相当高级,因为有大量的基本教程可以跳过更难的问题)“以完成形式完成任务”?
答案 0 :(得分:26)
您可以做的一件事是在视图脚本中创建一个表单,该表单包含与表单类同名的元素。
您的HTML表单:
<form action="/login/" method="post">
<fieldset>
<label for="username">Username:</label>
<input type="text" size="10" name="username" />
<label for="password">Password:</label>
<input type="password" size="10" name="password" />
<input type="submit" />
</fieldset>
</form>
你的班级:
class LoginForm extends Zend_Form
{
public function init()
{
$username = $this->createElement('text','username');
$username->setRequired(true);
$this->addElement($username);
$password = $this->createElement('password','password');
$password->setRequired(true);
$this->addElement($password);
}
}
您的表单类反映了您的HTML表单,您的类中的每个元素都有自己的验证器和要求。回到您的操作中,您可以创建表单类的实例,并针对该表单验证您的发布/获取变量:
$form = new LoginForm();
if ($this->_request->isPost()) {
if ($form->isValid($this->_request->getParams())) {
// do whatever you need to do
} else {
$this->view->errors = $form->getMessages();
}
}
您可以使用此方法在一个组中的表单顶部显示错误消息。
这是一个基本示例,但它允许您完全控制表单的表示,而无需花时间学习使用装饰器。在我看来,Zend_Form的大部分优势在于其验证和过滤属性。这给了你力量。回到这样的解决方案的主要原因是您的视图脚本HTML表单可能与您的表单类不同步。
答案 1 :(得分:11)
在视图中单独渲染每个元素 - 例如
<!-- view script here -->
<form method="POST">
Name: <?php echo $this->myForm->getElement('name')->render(); ?>
some other text between the fields
Birthdate: <?php echo $this->myForm->getElement('birthdate')->render(); ?>
<input type="submit" />
</form>
这保持了使用Zend_Form视图助手的能力(即,在验证失败时显示错误消息并维护表单字段的值),但为您提供完全自定义功能。
如果你想更进一步,那么关闭各个表单元素的默认装饰器,然后连接你自己以进一步自定义使用的标签(即错误消息和标签)或不使用装饰器all(除了渲染表单元素本身)然后手动编写所有周围的HTML。完整的自定义功能,同时在表单级别和视图级别都不会失去Zend_Form的优势。
答案 2 :(得分:9)
Matthew Weier O'Phinney已经发布了一系列有关Zend_Form装饰器的博客文章:
答案 3 :(得分:5)
目前我们已经拥有了新的闪亮Zend\Form
,它比旧组件更复杂,但也更加可控,封装和强大。所以,我在下面说的不适用。新组件是恕我直言,这是一个巨大的进步,因为它......
我真的无法帮助,因为我有完全相同的问题。我认为Zend_Form装饰器功能强大,但到目前为止,我见过的程序员友好且不直观的ZF,我已经在各种项目中使用了ZF的主要部分。
那说我只能从我的经验中得到一些提示:
从右侧的相关问题到显而易见,Zend_Form缺乏全面的文档,特别是考虑到它的非直观性。我真的很想看到ZF的人就像Zend Framework一样对此做些什么。
所以这个答案可能只是让你知道你并不是唯一一个遇到这个问题的人。
或者你当然可以使用 jedi mind trick !
答案 4 :(得分:4)
添加到上面说的内容:
不要害怕装饰者,如果你决定坚持使用Zend_Form,你将会使用它们。一旦你“得到它”,这是相当简单的,不幸的是,文档很弱并且玩它几乎是到达那里的唯一方法。
ViewScript和ViewHelper装饰器为您提供了强大的功能。
不要害怕挖掘存在的不同装饰者的来源,看看他们是如何做事的(我比较原始装饰者和道场装扮者获得了相当多的洞察力。)
我认为肖恩所建议的是你不需要调用form-&gt;渲染,你可以在你的视图中使用这样的东西。
<someHtmlThingy name="blah" value="<?php echo $this->formInstance->getElement('whatever')->getValue(); ?>" />
我参与了一个项目(pre Zend_Form),我们在其中构建了一组验证器并一直使用标准的视图脚本。这是一个更多的工作(错误消息的管道等),但与使用Zend_Form创建元素相比并不过分。
答案 5 :(得分:3)
如果您只想在不使用ViewScript装饰器的情况下在表单元素之前或之后添加任意标记,则可以使用我的AnyMarkup装饰器: http://www.zfsnippets.com/snippets/view/id/62
例如,以下是如何在包装器标签内添加带有图像的输入字段(需要包含正确设置自动加载的路径):
$form->addElement('text', 'my_field', array( 'label' => 'Enter Info:', 'decorators' => array( 'ViewHelper', array('AnyMarkup', array( 'markup' => '<span class="imgwrapper">'. '<img src="info.png" alt="info icon"/></span>'), 'placement' => 'prepend' ), 'HtmlTag', 'Label' ) );
答案 6 :(得分:2)
跳过表单范围的装饰器(IE - 打印表单的各个元素而不是仅仅依靠Form的标准View Helper来处理所有内容)是获得一堆控制权的一种方法。
另一个选择是简单地手工编写表单,只使用ZF来处理验证和过滤。
答案 7 :(得分:2)
不幸的是,更复杂的问题被忽略了,因为没有真正的特定目的或目标,编写示例或操作方法真的很难。我花了一些时间帮助那些想要modify the way hidden elements were displayed的SO的另一位开发人员,但他的案例非常具体,所以更容易深入细节。
大多数更复杂的任务实际上都归结为扩展特定字段类型的默认帮助程序。例如,我有一个项目,我希望将类“错误”应用于在提交表单后未通过验证的所有字段,而不是写出验证错误文本:
<label for="field">Label:</label>
<input type="text" name="field" id="field" class="error">
这是一个相当复杂的过程,因为默认情况下视图助手不能使用实际的表单元素,因此帮助程序无法检查该元素是否存在验证错误。所以我进行了以下过程:
formXXX()
方法,并添加一个检查以查看该元素是否有错误。另外,我添加了一个setElement()
方法,装饰者可以调用该方法来设置元素的实例,这样我的助手就可以检查错误。Zend_Form_Decorator_ViewHelper
。在其中,我访问了视图并实例化了表单元素类型的帮助器,并检查了我在视图助手中创建的setElement()
方法是否存在,如果存在则设置它。通过这样做,我可以扩展一些表单元素类型,而不是破坏整个脚本。 addElementPrefixPath('My_Form_Decorator'), 'path/to/decorator')
),它指向我的新表单装饰器。addHelperPath('/path/to/helpers', 'My_View_Helper');
你可以看到为什么编写复杂的教程确实需要现实世界的问题。设置这些辅助工具或复杂的装饰器方案的重要部分是,它都是令人讨厌的,它允许您非常轻松地创建许多符合相同设计方案的形式,并且如果更改,可以非常快速地修改它们的输出需要制作。但另一方面,如果你觉得你花了很多时间来确定如何为一个表格的利益做一个简单的任务,我会说跳过它!
如果您想要更具体的帮助,我会非常乐意提供帮助。只是提出另一个问题(或更新这个问题),我会尽力帮忙。
答案 8 :(得分:2)
whycantitbemorethan25c上面提到了它们,但ViewScripts为渲染表单提供了非常精细的控制。 Zend_Form意味着很快,因此它假定许多默认值,如标准装饰器,并按照它们添加到表单对象的方式对元素进行排序。使用ViewScript,您可以跳过大部分内容,并将所有元素放在普通HTML中。
不要完全跳过装饰器的概念。即使稍后在ViewScript中使用它们,它们也会对各个元素进行样式化。例如,您可以像其他人所建议的那样将它们用于错误消息。
如果您的表单非常复杂,且具有多个具有相似操作的数据点(请考虑具有活动/非活动按钮的用户列表以及每个按钮的删除按钮),您应该考虑Zend_Form_SubForm。子表单可以像普通表单一样使用ViewScripts,如果使用带有自己的ViewScripts的子表单的ViewScript级联表单,最终会得到包含很好的逻辑和表示,而不仅仅是直接表单。
答案 9 :(得分:1)
我为Zend_Form和装饰器编写了一些子类,使其在&lt; table&gt;中布局表单。它甚至还有一些特殊的技巧可以让你在同一行上显示多个提交按钮。
整整一天的黑客攻击让它发挥作用。它是针对Zend 1.5.1编写的,所以不知道它是否适用于当前版本,但如果你感兴趣我可以在某处上传源代码。
这似乎是对Zend Forms的一个非常普遍的抱怨。
(我知道我会因为使用表格来布局表格而被CSS纯粹主义者嘲笑,虽然我同意CSS对大多数事情更好,但我还没有看到使用CSS的好的表单布局看起来像是一个丑陋的kludge。使用表格,表格'只是工作'几乎在我需要的每个浏览器上。)
编辑:好的,谈到对不起的kludges,我已经把我的代码用于在github中生成表格的zend表单。转here查看。 (因为gaoshan88要求它。)答案 10 :(得分:1)
在这里回答。希望它会帮助你。我找到了正常数量的信息,直到找到它为止。
<table>
<tr>
<td>Page name: *</td>
<td><?php echo $this->pageForm->header_title;?></td>
</tr>
<tr>
<td>H1 tag: *</td>
<td><?php echo $this->pageForm->h1_tag;?></td>
</tr>
<tr>
<td>Page URL: *</td>
<td><?php echo $this->pageForm->url;?></td>
</tr>
<tr>
<td>Meta Description: </td>
<td><?php echo $this->pageForm->meta_description;?></td>
</tr>
<tr>
<td>Meta Keywords: </td>
<td><?php echo $this->pageForm->meta_keywords;?></td>
</tr>
<tr>
<td>Short Description: *</td>
<td><?php echo $this->pageForm->short_description;?></td>
</tr>
<tr>
<td colspan="2"><a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true"
title="add a caption to title attribute / or leave blank" class="thickbox">Open iFrame Modal</a></td>
<td>
<a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true" onclick="javascript:getDataFromAddPage()" title="Select Template For Page" class="thickbox" > TEST FORM </a>
</td>
</tr>
<tr>
<td>Featured: </td>
<td><?php echo $this->pageForm->featured;?></td>
</tr>
<tr>
<td>Mark as 404: </td>
<td><?php echo $this->pageForm->is_404page;?></td>
</tr>
<tr>
<td>Show in Navigation Menu: </td>
<td><?php echo $this->pageForm->in_navmain;?></td>
</tr>
<tr>
<td>Show in Static Menu:</td>
<td><?php echo $this->pageForm->in_navstatic;?></td>
</tr>
<tr>
<td><?php echo $this->pageForm->submit;?></td>
<td><?php echo $this->pageForm->button_close;?></td>
</tr>
</table>
答案 11 :(得分:1)
你现在可能已经解决了这个问题,但我一直在做一些工作,需要一个类似的解决方案。
form->getSubform('subform'); foreach ($subform as $key => $value) { //some markup and custom code here print $value; //some markup and custom code here } ?>在foreach循环中,您可以添加表格标记。如果您已正确命名表行的键,则它们应与表单键匹配。您甚至可以使用循环来按键获取相应的子表单,甚至可以使用键来获取元素。如果你知道键,你可以跳过foreach循环,只需说print $ subform ['somekey'];假设您通过说$ form-&gt; setIsArray(true)来设置主窗体; (不确定最后一部分是否是绝对必要的,但对于复杂的表格,无论如何都应该这样设置。
我删除了默认装饰器,因此我可以完全控制每个元素中的打印。 Zend_Form应该有一个内置的方法来更轻松地抓取单个元素..但我认为这很有效。
希望这对某人有帮助!
答案 12 :(得分:0)
Sean McSomething的第一个建议是找我的方法。我一直认为用<?php echo $this->form ?>
来渲染表单太神奇了。我会更进一步,通过$element->renderDecorator()
魔术方法渲染单个装饰器而不是单个元素。这样,您就不必担心定义装饰器的顺序。你只需要他们在那里,你就不必添加那些讨厌的,不直观的HtmlTag
装饰者。 I made a blog post about this
答案 13 :(得分:-1)
我不确定Zend是否已经拥有该功能,但是,一个快速的解决方案是扩展该类,使其接受一个html模板。
例如:
<?php
$form = new zend_form_whatever($field_list + $validators + $template);
echo $form;
?>
模板:
<form id="my_custom_form">
<label>{label.email}</label>
{input.email}
<span class="red">{error.email}</span>
<div>
{label.password}
{error.password}
{input.password}
</div>
<div class="purple">{input.submit}<div>
</form>