如何在 Zend_Form 文件元素上使用 ViewScript?
我将此 ViewScript 用于我的标准表单元素:
<div class="field" id="field_<?php echo $this->element->getId(); ?>">
<?php if (0 < strlen($this->element->getLabel())) : ?>
<?php echo $this->formLabel($this->element->getName(), $this->element->getLabel());?>
<?php endif; ?>
<span class="value"><?php echo $this->{$this->element->helper}(
$this->element->getName(),
$this->element->getValue(),
$this->element->getAttribs()
) ?></span>
<?php if (0 < $this->element->getMessages()->length) : ?>
<?php echo $this->formErrors($this->element->getMessages()); ?>
<?php endif; ?>
<?php if (0 < strlen($this->element->getDescription())) : ?>
<span class="hint"><?php echo $this->element->getDescription(); ?></span>
<?php endif; ?>
</div>
尝试单独使用该 ViewScript 会导致错误:
表单捕获异常:无文件 发现装饰器...无法渲染 文件元素
查看此常见问题解答揭示了我的部分问题,我更新了我的表单像这样的元素装饰器:
'decorators' => array(
array('File'),
array('ViewScript', array('viewScript' => 'form/field.phtml'))
)
现在它渲染文件元素两次,一次在我的视图脚本内,以及在我的视图脚本之外的文件元素的额外元素:
<input type="hidden" name="MAX_FILE_SIZE" value="8388608" id="MAX_FILE_SIZE" />
<input type="hidden" name="UPLOAD_IDENTIFIER" value="4b5f7335a55ee" id="progress_key" />
<input type="file" name="upload_file" id="upload_file" />
<div class="field" id="field_upload_file">
<label for="upload_file">Upload File</label>
<span class="value"><input type="file" name="upload_file" id="upload_file" /></span>
</div>
关于如何使用 ViewScript 正确处理这个问题有什么想法吗?
更新:基于肖恩的解决方案,这是我的最终代码:
表单元素:
$this->addElement('file', 'upload_file', array(
'disableLoadDefaultDecorators' => true,
'decorators' => array('File', array('ViewScript', array(
'viewScript' => '_form/file.phtml',
'placement' => false,
))),
'label' => 'Upload',
'required' => false,
'filters' => array(),
'validators' => array(array('Count', false, 1),),
));
查看脚本:
<?php
$class .= 'field ' . strtolower(end(explode('_',$this->element->getType())));
if ($this->element->isRequired()) {
$class .= ' required';
}
if ($this->element->hasErrors()) {
$class .= ' errors';
}
?>
<div class="<?php echo $class; ?>" id="field_<?php echo $this->element->getId(); ?>">
<?php if (0 < strlen($this->element->getLabel())): ?>
<?php echo $this->formLabel($this->element->getFullyQualifiedName(), $this->element->getLabel());?>
<?php endif; ?>
<span class="value"><?php echo $this->content; ?></span>
<?php if ($this->element->hasErrors()): ?>
<?php echo $this->formErrors($this->element->getMessages()); ?>
<?php endif; ?>
<?php if (0 < strlen($this->element->getDescription())): ?>
<p class="hint"><?php echo $this->element->getDescription(); ?></p>
<?php endif; ?>
</div>
I am using this ViewScript for my standard form elements:
<div class="field" id="field_<?php echo $this->element->getId(); ?>">
<?php if (0 < strlen($this->element->getLabel())) : ?>
<?php echo $this->formLabel($this->element->getName(), $this->element->getLabel());?>
<?php endif; ?>
<span class="value"><?php echo $this->{$this->element->helper}(
$this->element->getName(),
$this->element->getValue(),
$this->element->getAttribs()
) ?></span>
<?php if (0 < $this->element->getMessages()->length) : ?>
<?php echo $this->formErrors($this->element->getMessages()); ?>
<?php endif; ?>
<?php if (0 < strlen($this->element->getDescription())) : ?>
<span class="hint"><?php echo $this->element->getDescription(); ?></span>
<?php endif; ?>
</div>
Trying to use that ViewScript alone results in an error:
Exception caught by form: No file
decorator found... unable to render
file element
Looking at this FAQ revealed part of my problem, and I updated my form element decorators like this:
'decorators' => array(
array('File'),
array('ViewScript', array('viewScript' => 'form/field.phtml'))
)
Now it's rendering the file element twice, once within my view script, and extra elements with the file element outside my view script:
<input type="hidden" name="MAX_FILE_SIZE" value="8388608" id="MAX_FILE_SIZE" />
<input type="hidden" name="UPLOAD_IDENTIFIER" value="4b5f7335a55ee" id="progress_key" />
<input type="file" name="upload_file" id="upload_file" />
<div class="field" id="field_upload_file">
<label for="upload_file">Upload File</label>
<span class="value"><input type="file" name="upload_file" id="upload_file" /></span>
</div>
Any ideas on how to handle this properly with a ViewScript?
UPDATE: Based on Shaun's solution, here's my final code:
Form Element:
$this->addElement('file', 'upload_file', array(
'disableLoadDefaultDecorators' => true,
'decorators' => array('File', array('ViewScript', array(
'viewScript' => '_form/file.phtml',
'placement' => false,
))),
'label' => 'Upload',
'required' => false,
'filters' => array(),
'validators' => array(array('Count', false, 1),),
));
View Script:
<?php
$class .= 'field ' . strtolower(end(explode('_',$this->element->getType())));
if ($this->element->isRequired()) {
$class .= ' required';
}
if ($this->element->hasErrors()) {
$class .= ' errors';
}
?>
<div class="<?php echo $class; ?>" id="field_<?php echo $this->element->getId(); ?>">
<?php if (0 < strlen($this->element->getLabel())): ?>
<?php echo $this->formLabel($this->element->getFullyQualifiedName(), $this->element->getLabel());?>
<?php endif; ?>
<span class="value"><?php echo $this->content; ?></span>
<?php if ($this->element->hasErrors()): ?>
<?php echo $this->formErrors($this->element->getMessages()); ?>
<?php endif; ?>
<?php if (0 < strlen($this->element->getDescription())): ?>
<p class="hint"><?php echo $this->element->getDescription(); ?></p>
<?php endif; ?>
</div>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
答案相对简单。您需要做的就是首先指定文件装饰器,为文件输入创建一个特定的视图脚本,并为 viewScript 装饰器参数中的放置指定 false,这将有效地将文件装饰器的输出注入到 viewScript 装饰器中,例如
然后在新的文件元素视图脚本,您只需在脚本中回显 $this->content 即可放置文件输入标记。这是最近项目中的一个示例,因此如果它看起来有点奇怪,请忽略标记,希望它能说明这一点。
渲染后,您将看到该元素的 html
The answer is relatively simple as it happens. All you need do is specify the File decorator first, create a specific view script for the file input and specify false for the placement in the viewScript decorator arguments, this will effectively inject the output from the File decorator into the viewScript decorator e.g.
Then in the new file element view script you simply echo $this->content in the script where you'd like the file input markup to be placed. Here's an example from a recent project, so ignore the markup if it looks a little odd, hopefully it will illustrate the point.
When rendered you will see this html for the element
这不是一个简单或理想的解决方案,因为它需要文件装饰器的扩展......但令人沮丧的是,他们没有努力将隐藏元素生成逻辑与文件输入生成逻辑分开。我不确定文件视图助手是否处理元素为数组的问题(这似乎是他们这样做的原因。)
文件装饰器的扩展:
(注释掉的部分是导致生成额外输入的原因。)
控制器操作中的表单设置:
在操作视图中:
在元素脚本中:
输出应该是:
这个解决方案的一个问题是隐藏的元素不会在视图脚本中呈现;如果您在客户端脚本中使用 div 作为选择器,这可能会出现问题...
This is not a simple or ideal solution because it requires an extension of the File decorator... but it's rather frustrating that they didn't make the effort to separate the hidden element generation logic from the file input generation logic. I'm not sure if the file view helper handles the issue of an element being an array (that seems to be the reason they did it this way.)
Extension of File Decorator:
(the commented out part is what causes the extra input to be generated.)
Form setup in controller action:
In action view:
In element script:
Output should be:
A problem with this solution is that the hidden elements don't render within the viewscript; this might be a problem if you're using the div as a selector in a client-side script...
我意识到,自定义装饰器类将处理除文件字段之外的大多数字段。
确保您的类实现如下所示的接口:
这对我有用。
What I've realized is, a custom decorator class will handle most fields except File fields.
Make sure your class implements the interface like so:
This worked for me.
这帮助我解决了我的问题。我调整了代码以将文件元素包装在表格内。要使其工作,只需从 viewdecorator 中删除标签并添加 file 元素,如下所示:
This helped me fix my problem. I adjusted the code to wrap the file element inside a table. To make it work, simply remove the label from the viewdecorator and add the file element as follows:
我找到了一种完全避免 ViewScript 的解决方法。
首先,元素定义:
其次,实例化表单类后,我模仿 ViewScript 的行为:
我想我应该研究基于类的装饰器。也许那里有更多的灵活性?
I've found a work-around that avoids the ViewScript altogether.
First, the element definition:
Second, after the form class has been instantiated, I mimic the behavior of my ViewScript:
I guess that I should look into class-based decorators. Maybe there's more flexibility there?
最简单的事情是在自定义文件装饰器中的输出中根本不添加任何标记:
现在您可以在视图脚本中为此文件元素执行任何您想要的操作(输出文件输入字段和您自己需要的所有隐藏字段) )。
The easiest thing to do is to add no markup at all to the output in your custom File Decorator:
now you can do whatever you want in your viewscript for this file element (output the file input field and all hidden fields you need on your own).
以防万一您遵循了 @Shaun 的答案但仍然收到错误:请确保您已禁用相关元素的默认装饰器(请查看第 2 行):
Just in case you have followed @Shaun's answer and you are still getting the error: make sure that you've disabled default decorators for the element in question (take look at line 2):