1

我想知道是否有一种方法可以将一组元素添加到 zend 表单中,就好像它们是一个元素一样,我想很像一个子表单,但似乎子表单的功能可能太多了......

这是我的用例。我创建了一个处理多页表单的类。我希望能够编写逻辑来根据我所在的表单页面更改表单底部的按钮。 表格第 1 页表格第 2 页表格第 3 页

我原本以为 Zend-Form-DisplayGroup 会解决我的问题,但是您必须先将项目添加到表单中,然后将它们添加到显示组中,并且不能通过带有附加元素的函数传递显示组。我想要一个类似的功能

public function setSubmitButtonGroup($submitButtonGroupElements)
{
     /*Code to set button group*/
}

使用元素数组的想法现在让我想到了,而不是其他东西,并添加了逻辑以将元素数组添加到渲染时的表单中......但是有人有任何“更好”的想法或以前做过吗?

顺便说一句,如果有人想知道...我将我的初始设计松散地基于本节:Zend Framework Advance Form Usage。

4

3 回答 3

1

你可以让自己成为一个接收三个参数的工厂,你的表单元素,当前控制器和当前动作。然后在那个工厂中,您可以根据控制器/操作组合调用构建器并传递您的表单。

在您的构建器中,您可以根据存储在不同组件中的相应控制器/操作要求添加 1、2 或 3 个按钮。完成后,您将表格退回工厂,工厂将表格退回。

My_Form // your Zend_Form object

My_Form_Factory // Your new factory (see below)

My_Form_Factory_Builder_Controller_Action  // One of your builder (see below)

My_Form_Factory_Component // Extends the corresponding Zend_Form_Elements

// basic factory that can be called like My_Factory::factory($form, $controller, $action)
class My_Form_Factory {
    static public function factory($form, $controller, $action)
        $builderClass = "My_Form_Factory_Builder_" . $controller . '_' . $action;
        $builder = new $builderClass($form);
        return $builder->buildForm();
}

// Basic builder
class My_Form_Factory_Builder_Controller_Action
{
    protected $_form;
    protected $_previousComponent ;
    protected $_nextComponent ;
    protected $_cancelComponent ;

    public function __construct($form)
    {
        $this->_form = $form;
        $this->_previousComponent = new My_Form_Factory_Component_Previous();
        $this->_nextComponent = new My_Form_Factory_Component_Next();
        $this->_cancelComponent = new My_Form_Factory_Component_Cancel();
    }

    public function buildForm()
    {
        $this->_form->addElement($previousCompnent);
        $this->_form->addElement($nextComponent);
        $this->_form->addElement($cancelComponent);

        return $this->_form;
    }
}

如果您想自动化实例化,您可以在抽象类中初始化您可能需要的所有不同组件,并且在方法 buildForm() 中只添加当前接口所需的元素。(我宁愿在每个构建器中重复代码,也不愿依赖这种“魔法”,但这是一种可行的方法)。

于 2011-07-29T17:05:43.523 回答
1

不确定我是否正确理解了您的问题,但这就是我做某些事情的方式。

在 Zend_Form 对象中,您可以使用 `addElements($elements) 在数组中添加元素作为组。对于提交按钮等。我有一个类,我从中获取 $elements 数组,然后我只需将其弹出。我还添加了一个 displayGroup,但单独且简单地控制按钮的位置。因为表单是一个对象,你可以做如下简单的事情,但我总是添加一个引用来显示我的意图。

更新:洗牌按钮操作

function addButtons(&$form,$nextName = null) {
    $buttons = $this->getButtons();  // this will be an array with your buttons
    // make sure you have the element names in your buttons arrays
    if ( is_string($nextName) ) {
        $buttons['nextButton']->setLabel($nextName);
    } elseif ( is_bool($nextName) && false === $nextName ) {
        unset($buttons['nextButton'];
    }
    // repeat for other buttons

    $form->addElements($buttons);
    $elementNames = array_keys($buttons);
    $form->addDisplayGroup($elementNames,'buttonGroup',array('legend'=>'Click some buttons'));

}

$this->addButtons($form,'Finish');
于 2011-07-29T17:53:44.290 回答
0

因此,我的问题的复杂性在于知道多页表单的哪一页。使用数组和上面提到的 addElements() 有所帮助。

简单的答案

我的问题的答案是一个数组,可以说是在“构建”表单之后但在渲染之前可以操作的数组,以便我可以使用 addElements() 添加到表单中。

长答案

为了获得全貌,想象每次您点击下一个或上一个按钮时,您都在遍历一组子表单。在这种情况下,需要一个函数来处理按钮渲染。我最终使用了一个案例陈述,虽然它不是世界上最好的实现(在父类 Form_MultiPage 中不可重用),但它确实有效:

在我的 mulipage 表单类的扩展中,我有

public function setSubmitControls()
{
    $previous = new Zend_Form_Element_Submit('previous',array(
        'label'=>'previous',
        'required'=>false,
        'ignore'=>false,
        'order'=>9000
    ));
    $cancel = new Zend_Form_Element_Submit('cancel',array(
        'label'=>'Cancel',
        'required'=>false,
        'ignore'=>false,
        'order'=>9003
    ));
    $next = new Zend_Form_Element_Submit('next',array(
        'label'=>'Next',
        'required'=>false,
        'ignore'=>false,
        'order'=>9002
    ));
    $finished = new Zend_Form_Element_submit('finish',array(
        'label'=>'Finish',
        'required'=>false,
        'ignore'=>false,
        'order'=>9004
    ));
    $submitControls = array();
    echo var_dump($this->getCurrentSubForm()->getName());
    switch($this->getCurrentSubForm()->getName())
    {
        case 'billInfo':
            $submitControls = array(
                $next,
                $cancel
            );
        break;
        case 'payerInfo':
            $submitControls = array(
                $previous,
                $next,
                $cancel
            );
        break;
//So on for other subforms
    }
    $this->setSubmitButtonGroup($submitControls);
}

在我的父类 Form_Multipage 中,我有

public function setSubmitButtonGroup(array $elements)
{
    $this->_submitButton = $elements;   
}

public function addSubmitButtonGroupToSubForm(Zend_Form_SubForm $subForm)
{
    $subForm->addElements($this->_submitButton);
    return $subForm;
}

当我用这个函数渲染表单的“页面”时调用它

public function prepareSubForm($spec)
{
    if (is_string($spec)) {
        $subForm = $this->{$spec};
    } elseif ($spec instanceof Zend_Form_SubForm) {
        $subForm = $spec;
    } else {
        throw new Exception('Invalid argument passed to ' .
                            __FUNCTION__ . '()');
    }
    $subform = $this->setSubFormDecorators($subForm);
    $subform = $this->addSubmitButtonGroupToSubForm($subForm);
    $subform = $this->addSubFormActions($subForm);
    $subform->setMethod($this->getMethod());
    return $subForm;
}
于 2011-08-05T20:11:04.220 回答