【问题标题】:Zend Framework form_TableForm need to have multiple tablesZend Framework form_TableForm 需要有多个表
【发布时间】:2012-06-06 21:56:15
【问题描述】:

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

现在我在表格中构建了一个表格,表格看起来像

<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 将其构建出来。我对此非常了解。但我的主要问题是,有没有办法可以打破表态,然后推出另一个?

总的来说,我想以某种方式注入&lt;/tr&gt;&lt;/table&gt;&lt;br&gt;&lt;table&gt;,这样我就可以拥有两个不同的表。

循环更新 我必须排除一些变量和一些类似的东西,作为正在进行的propietray的一部分,所以我不允许在网上发布任何代码,所以说这是一个最小版本,去掉任何可能使它引人注目的东西

$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;

【问题讨论】:

  • 这听起来不像是 Zend Framework 相关的问题,因为它听起来不像您使用 Zend_Form 类。对您的问题的一般回答是,是的,您可以在循环中添加条件语句以添加一些额外的 HTML 标记,从而有效地关闭和打开新表。你只需要知道什么时候(有条件地)你想这样做。如果你有一些代码和细节,比如你想关闭你的桌子,我会为你破解代码。应该不会太难。
  • 它在 foreach 循环中使用 $form = new form_TableForm(self::CHANGEPREFS)Zend_Form_Element_Checkbox 来遍历提到的数组,从我收集的内容中可以构建一个类似于第一个提到的表。这就是我被卡住的原因,因为如果它自动滚动表格,那么循环的每一次通过只添加一个 tr, td 集,我想不出一种方法来添加我想要的条件。或者等一下,我可能只是在输入这个..
  • 不,我错了..希望它像沿着循环查找添加最后一个元素的位置一样简单,然后在它注入一点点时,我想结束一张桌子并开始另一个。
  • Hmm.. 看起来 form_TableForm 可能是 Zend_Form 类,因为 Zend_Form_Element_Checkbox 是 Zend_Form 的一个元素。我曾经使用 Zend_Form 有一段时间,但因为太复杂而停止了。如果您发布循环代码,如果这只是装饰器问题并帮助制作自定义装饰器,我可能会提供帮助。
  • 我明白了。 form_TableForm 必须是扩展 Zend_Form 的自定义类。 foreach 循环根据$defaults 中设置的内容将表单元素添加到表单,但它们都必须是复选框元素,因为这就是它要添加的内容。但是,此代码实际上并不是打印 HTML 代码的内容,但它确实设置了表单元素的显示方式。要修改 HTML 输出,您必须熟悉装饰器。 framework.zend.com/manual/en/zend.form.standardDecorators.html。您只想为$name == xxx5 创建一个新表吗?

标签: php zend-framework zend-form


【解决方案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 字符串中,并且只使用关闭标签 ()。

为了简洁起见,现在假设我们只有输入标签。我们现在有:

<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' => 'true'”应该是“'tag' => 'table'”。我更新了之前的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多