如何在Zend_Form文件元素上使用ViewScripts?

Son*_*nny 19 zend-framework decorator zend-form zend-view zend-form-element

我将此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>
Run Code Online (Sandbox Code Playgroud)

尝试单独使用ViewScript会导致错误:

表单捕获的异常:找不到文件装饰器...无法呈现文件元素

看看这个FAQ揭示了我的部分问题,我更新了我的表单元素装饰器,如下所示:

'decorators' => array(
   array('File'),
   array('ViewScript', array('viewScript' => 'form/field.phtml'))
)
Run Code Online (Sandbox Code Playgroud)

现在它将文件元素渲染两次,一次在我的视图脚本中,以及在视图脚本之外使用文件元素的额外元素:

<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>
Run Code Online (Sandbox Code Playgroud)

有关如何使用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),),
));
Run Code Online (Sandbox Code Playgroud)

查看脚本:

<?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>
Run Code Online (Sandbox Code Playgroud)

小智 19

答案相对简单,因为它发生了.您需要做的就是首先指定File装饰器,为文件输入创建特定的视图脚本,并为viewScript装饰器参数中的位置指定false,这将有效地将File装饰器的输出注入viewScript装饰器,例如

$element->setDecorators(array('File', array('ViewScript', array('viewScript' => 'decorators/file.phtml', 'placement' => false))));
Run Code Online (Sandbox Code Playgroud)

然后在新的文件元素视图脚本中,您只需在脚本中回显$ this-> content,您希望放置文件输入标记.这是最近项目的一个例子,如果看起来有点奇怪,请忽略标记,希望它能说明这一点.

<label for="<?php echo $this->element->getName(); ?>" class="element <?php if ($this->element->hasErrors()): ?> error<?php endif; ?>" id="label_<?php echo $this->element->getName(); ?>"> 
<span><?php echo $this->element->getLabel(); ?></span>

<?php echo $this->content; ?>

<?php if ($this->element->hasErrors()): ?>

    <span class="error">
        <?php echo $this->formErrors($this->element->getMessages()); ?>
    </span>

<?php endif; ?>

</label>
Run Code Online (Sandbox Code Playgroud)

渲染时,您将看到该元素的html

<label for="photo" class="element" id="label_photo"> 
<span>Photo</span>

<input type="hidden" name="MAX_FILE_SIZE" value="6291456" id="MAX_FILE_SIZE">
<input type="file" name="photo" id="photo">

</label>
Run Code Online (Sandbox Code Playgroud)