2011-09-28 139 views
6

我想使用视图脚本来渲染我的zend窗体,因为它似乎是 控制窗体布局/设计的最佳方式,同时仍然使用Zend_Elements类。在嵌套子窗体上使用ViewScript装饰器(Zend窗体)

从视图脚本中,我使用$this->element->getElement('elementName')呈现元素。

我遇到了元素名称的问题。这实际上是表单内子表单内的子表单。

当我使用FormElements装饰器时,元素的完全限定名称是form [subForm] [subForm] [element],这很好。 我移动到viewScript装饰器,它改变为subForm [subForm] [element]。

我知道我需要使用PrepareElements装饰器来解决这个问题,但是这导致了名称改变了form [subForm] [form] [subForm] [subForm] [elements](它将前两个名字加倍开始)。

任何想法我应该如何处理?

谢谢。

更新:我试图调试PrepareElements,我真的不明白在做什么。 看起来它在第一次迭代中工作正常,但是当它在中间子窗体中的一个上运行时,它再次添​​加形式[子形式]前缀。当我不使用PrepareElements装饰器时,我只是在名称(即,而不是form [subForm] [element],我只得到subForm [element])中缺少了“表单”前缀)。

可能是我可以修正这个莫名其妙?

我试图改变belongsTo但只替换了“subForm”前缀。

它实际上好像缺少的是subForm上的belongsTo方法。

再一次,这都是因为ViewScript装饰器。它适用于FormElements装饰器。

更新2:只是为了澄清,我不介意这个名称的变化,但它会导致我的字段不填充时,我调用form->填充。

编辑:我认为我已经收窄的问题:当我得到我的价值观回来setDefaults,他们被下令这样的:

array(
\"formElements1-name\" => value1... \"subFormName\" => array(
\"parentFormName\" => array(
\"subFormName\" => subForm-values-array 
) 
) 

... 这里的主要问题是"parentFormName" => "subFormNAme"..它重复了什么?我已经在主要形式。我猜这是因为我设置了setElementsBelongTo(formName[subFormName]),但如果我不这样做,那么我会得到我的子表单值完全独立于表格,即

即 值数组=阵列( \ “表格名称\”=>数组( formValues ),\ “subFormNAme \”=>数组( subFormValues )

,虽然我怎样exepct它是

array(
formName => array(
subFormNAme => values-array 
) 
)... 

它甚至有可能使这项工作?

+0

[Zend:ViewScript装饰器和数组表示法]的完全重复(http://stackoverflow.com/questions/7155047/zend-viewscript-decorator-and-array-notation) – Phil

+1

这不是重复的,因为我已经使用建议的解决方案,但效果不佳。 – Ran

+0

Zend表格必须是我所遭受的不幸中最糟糕,最可笑,最疯狂的一段垃圾。我完全感觉到你的痛苦,如果你知道有什么问题,那么请尽量让我知道! – GordonM

回答

2

目前的解决方案是使用的子窗体的PrepareElements装饰与一个变化 - 除去在PrepareElements代码递归调用。另外,不需要“setElementsBelongTo”。

这似乎会生成正确的名称和ID。

+0

您是否修改了Zend的PrepareElements.php? – artsylar

8

你只是使用<?php echo $this->form; ?>从您的视图脚本试图输出表单?

这适用于简单的表单,但对于我更复杂的表单,我倾向于单独呈现每个元素,但不需要在每个单独元素上使用ViewScript装饰器来执行此操作。只是尝试这样的事情从您的视图脚本:

<div class="form"> 
    <fieldset> 
     <legend>Some Form Name</legend> 
     <form action="<?php echo $this->escape($this->form->getAction()) ?>" 
       method="<?php echo $this->escape($this->form->getMethod()) ?>" 
       enctype="multipart/form-data"> 

      <?php echo $this->form->id; // render the id element here ?> 

      <div class="half"> 
       <?php echo $this->form->name; // render the user name field here ?> 
      </div> 
      <div class="half"> 
       <?php echo $this->form->description; // render the description element here ?> 
      </div> 
      <div class="clear"></div> 

      <div class="half"> 
       <?php echo $this->form->address1; // render the address ?> 
      </div> 
      <div class="half"> 
       <?php echo $this->form->address2; // render address2 ?> 
      </div> 
      <div class="clear"></div> 

      <div class="third"> 
       <?php echo $this->form->zip; // render zip code ?> 
      </div> 
      <div class="third"> 
       <?php echo $this->form->city; // render city ?> 
      </div> 
      <div class="third"> 
       <?php echo $this->form->state; // render state ?> 
      </div> 
      <div class="clear"></div> 

      <div class="half"> 
       <?php echo $this->form->country; // render country ?> 
      </div> 
      <div class="clear"></div> 

      <?php echo $this->form->submit; ?> 

     </form> 
    </fieldset> 
</div> 

这是我做了我的大部分形式,因为我想有一些元素占用一半的宽度和其他全宽。

令人惊讶的是,参考指南并没有告诉你,你可以这样做。我似乎记得过去的一个页面,但现在找不到它。当我开始使用Zend Framework时,我认为唯一能让我的表单输出我想要的东西的唯一方法是创建复杂的装饰器,但事实并非如此。

Matthew Weier O'Phinney在rendering Zend_Form decorators individually上有一篇很棒的博客文章,它解释了我在上面做了什么。我希望他们把这个添加到Zend Form的第一页,因为起初这对我来说是令人沮丧的。事实是,我的表单中有90%单独呈现元素,而不是仅仅回显表单本身。

注意:为了阻止ZF将我的表单元素封装在dt和dd标记中,我将这个装饰器应用于所有标准表单元素。我有一个基础表单类,可以扩展我的所有表单,所以我不必在任何地方重复此操作。这是元素的装饰器,所以我可以使用标签来封装我的元素。

public $elementDecorators = array(
    'ViewHelper', 
    'Errors', 
    array('Description', array('tag' => 'p', 'class' => 'description')), 
    array('HtmlTag',  array('tag' => 'div', 'class' => 'form-div')), 
    array('Label',  array('class' => 'form-label', 'requiredSuffix' => '*')) 
); 

对于我的提交按钮我使用

public $buttonDecorators = array(
    'ViewHelper', 
    array('HtmlTag', array('tag' => 'div', 'class' => 'form-button')) 
); 
+1

这正是我想要做的,只有子表单。问题是当我使用ViewScript装饰器时,生成的子表单元素的名称是错误的。 – Ran

0

解决方案将使用belongsTo()表单元素属性。
实施例:

new Zend_Form_Element_Text('<elementName>', array('belongsTo' => '<subformName>')) 

以这种方式,呈现()方法将使用的一种形式的元素名称等

name="<subformName>[<elementName>]" 
0

我有同样的问题,我用装饰

解决了它1:使用元素创建通用子表格

2:使用PrepareElements的特定修饰器

3:变化形式与setIsArray(真)的阵列

实施例:

表格

$i = 4; 
for($i = 0; $i < $nbReclam ; $i++) 
{ 
    $rowForm = new Zend_Form_SubForm($i); 
    $name= new Zend_Form_Element_Textarea('name'); 
    $rowForm->addElement($name); 
    $this->addSubForm($rowForm, $i); 
} 

$this->setDecorators(array(
      'PrepareElements', 
      array('ViewScript', array('viewScript' => 'myDecorator.phtml')), 
    )); 


$this->setIsArray(true); 

装饰

<table> 
<thead> 
    <tr> 
     <th>N°</th> 
     <th>Name</th> 
    </tr> 
</thead> 
<tbody> 
    <?php foreach ($this->element->getSubForms() as $subForm) : ?> 
      <tr> 
       <td> <?php echo $i++?> </td> 
       <?php foreach ($subForm->getElements() as $row) : ?> 
        <td><?php echo $row ?></td> 
       <?php endforeach ?> 
      </tr> 
     <?php endforeach ?> 
    </tbody> 
</table> 

享受

对不起,我的英语,我是法国人