Zend Framework form_TableForm需要有多个表

时间:2012-06-06 21:56:16

标签: php zend-framework zend-form

好的,我是Zend Framework的新手,请原谅我,如果这有点无知。

现在我有一个内置于表格中的表单构建,表格看起来像

<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>

最初建造它的人为我正在努力寻找的人留下了一些东西。这些人现在想要的布局基本上都是......

<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>
<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>

该表目前通过foreach语句推出,因为字段是动态的并且是基于角色的。本质上,代码会吐出一个完整的表单元素数组,而foreach会将其构建出来。我对它了解很多。但我的主要问题是,有没有办法摆脱桌面然后推出另一个?

总体而言,我想在某些方面注入</tr></table><br><table>,以便我可以拥有2个不同的表格。

使用循环 进行更新 我必须排除一些变量和一些类似的东西,因为它是正在进行的propietray工作的一部分所以我不允许在网上发布任何代码,所以说这是一个最小的版本,剥夺任何可能使其显着的< / p>

$form = new form_TableForm(self::CHANGEPREFS);
        $form->setAction($this->_helper->url('saveprefs'));
    foreach ($defaults as $name => $value)
            {
               if ($name == 'xxx1' && (!xxx::eval('xxx','view') || $zzz)) continue;
               if ($name == 'xxx2' && !xxx::eval('xxx','view')) continue;
               if ($name == 'xxx3' && !xxx::eval('xxx','alerts')) continue;
               if ($name == 'xxx4' && !xxx::eval('xxx','alerts')) continue;

               $element = new Zend_Form_Element_Checkbox($name);
               $element->setLabel($this->_helper->Literal->xxx($name));
               if ($value) $element->setValue($value);
               $element->setOptions(array(
                   'required' => false,
                   'fullrow' => true
                   ));
               $form->addElement($element);
               //if($name == 'xxx5'){$form .= "</table><table>";}
               //bad attempt at injection above
            }
        $form->addDisplayGroup(array('savebutton'), 'buttonsgroup', array('fullrow' => true));
        return $form;

1 个答案:

答案 0 :(得分:1)

自从我使用Zend_Form_Decorators已经很长时间了,但我认为解决方案将与那些人一起使用。

Zend_Form和装饰器的简要概述可能有所帮助。

Zend_Form是Zend_Form_Element项的主容器。这些类具有默认的“装饰器”,当您打印整个Zend_Form对象时,该类将循环遍历所有对象并吐出在其类中设置的HTML格式。

您可以在创建Zend_Form_Element对象时设置装饰器HTML。在foreach循环中,您将创建元素,以便您可以执行条件来修改应关闭/打开新表的特定元素。但是由于Zend_Form如何生成它的HTML,因此开始工作可能很棘手。我记得需要创建一个自定义装饰器,因为它不可能用标准装饰器做一些相当容易的事情。

在上面的例子中,你不能只是将一些HTML代码附加到$ form对象,因为$ form对象是一个复杂的类。

无论如何,说得够多。尝试这样的事情:

// create the form element
$element = new Zend_Form_Element_Checkbox($name);
... // same code as above

// do something different for 'special' items
if($name == 'xxx5'){

    $element->setDecorators(array(
        array('ViewHelper'),
        // you might need to do this instead of the above
        // array('ViewHelper', array('helper' => 'formCheckbox')),
        array('HtmlTag', array(
            'tag' => 'table', 
            'placement'=>'APPEND', 
            'closeOnly' => true)),
        array(
            'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
            'options' => array(
                'tag' => 'table', 
                'placement'=>'APPEND', 
                'openOnly' => true)
        ),
    ));
}

// now add the element to the form object
$form->addElement($element);

让我试着为你解决这个问题。

$element->setDecorators( array($d1, $d2, [...]) );

这将为此元素设置装饰器。每个装饰器($ d1,$ d2等)都是从前一个装饰器构建的。想想看,因为$ d1将吐出一个HTML字符串,然后$ d2会将它的HTML字符串附加/前置到$ d1。

array('ViewHelper'),

这是甚至到达要显示的元素的默认装饰器。如果你没有这个,就没有什么可以展示的了。每个元素都有一个标准装饰器。我相信这可能包含它,但您可能需要强制使用默认值:

array('ViewHelper', array('helper' => 'formCheckbox')),

两者兼顾。此时生成的HTML应为:

<input type="checkbox" />

或者它可能包括表格行/单元格标签。这部分我有点生气。

<tr><td><input type="checkbox" /></td></tr>

如果没有,我们可以通过定义它们来添加它们。但让我们继续......

array('HtmlTag', array(
        'tag' => 'table', 
        'placement'=>'APPEND', 
        'closeOnly' => true)),

“HtmlTag”是Zend_Framework附带的标准装饰器。它基本上允许您添加所需的任何HTML标记。我设置的选项告诉它使用“table”标签,将其附加到前一个装饰器HTML字符串,并仅使用close标签(&lt; / table&gt;)。

此时我们假设我们只是为了简洁而拥有输入标签。我们现在有:

<input type="checkbox" /></table>

现在我们还要添加一个开始表装饰器:

array(
        'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
        'options' => array(
            'tag' => 'table', 
            'placement'=>'APPEND', 
            'openOnly' => true)
    ),

这部分可能有点令人困惑。 Zend_Form不允许您在给定元素上多次使用相同的装饰器。原因是代码如何生成。基本上,装饰器名称就像命名空间一样使用。如果添加两个相同的装饰器,则后一个装饰器会覆盖前一个装饰器。

要解决这个问题,你可以给它一个别名,这就是这段代码所做的事情:

'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),

“My_Alias_HtmlTag”可以是您想要的任何内容,但遵循相同的规则不要使用别名两次。每次都需要一个新的别名。

其余的代码应该是不言而喻的。我想在我当前的HTML字符串中添加一个开始表标记。最终结果应该是:

<input type="checkbox" /></table><table>

因此,当您打印出$ form对象时,当它遇到“特殊装饰”元素时,它应该生成上面的HTML代码。

当然,这需要一些玩法。就像我提到的那样,我对整个Zend_Form和装饰器都有点生疏。

还有一个问题是自定义Zend_Form类可能会做出意想不到的事情,这可能无法使其正常工作。

但试一试。

我认为Matthew Weier O'Phinney撰写的这篇博文有很多帮助:http://devzone.zend.com/1240/decorators-with-zend_form/

我希望有所帮助!

干杯!

更新

我有一个错字。 “'tag'=&gt;'true'”应该是“'tag'=&gt;'table'”。我更新了以前的代码。