有没有办法将一组元素添加到表单中?

发布于 2024-11-27 03:44:15 字数 825 浏览 1 评论 0原文

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

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

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

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

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

顺便说一句,如果有人想知道......我的初始设计松散地基于本节: Zend Framework 高级表单用法。

I'm wondering if there was a way to add a group of elements to a zend form as if they were one element, I guess much like a subform, but it seems the functionality of a subform may be too much...

Here's my use-case. I've created a class that handles multi-page forms. I want to be able to write logic to change the buttons at the bottom of the form based on the page of the form I'm on.
Form Page 1Form Page 2Form page 3

I originally thought that Zend-Form-DisplayGroup would fix my problem, but you have to add the items to the form first and then add them to the display group and can't pass a display group through a function with attached elements. I would like to have a function that would be something like

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

The idea of using an array of elements just hit me right now as opposed to something else and add logic to add that array of elements to the form on render... but does anyone have any "better" ideas or done this before?

BTW, if anyone is wondering... I'm loosely basing my initial design off of this section: Zend Framework Advance Form Usage.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

那伤。 2024-12-04 03:44:15

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

在 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');

Not sure I understand your problem correctly but this how I do some things.

In a Zend_Form object you can add elements as a group with `addElements($elements) in an array. For the Submit button etc. I have a class where I get the $elements array from and then I simply pop it in. I also add a displayGroup but separately and simply to control where the buttons are. Because a form is an object you can do simple things like the following but I always add a reference to show my intent.

update: shuffled the button manipulation

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');
趁年轻赶紧闹 2024-12-04 03:44:15

您可以为自己创建一个工厂,它接收三个参数:表单元素、当前控制器和当前操作。然后在该工厂中,您可以根据控制器/操作组合调用构建器,然后传递表单。

在您的构建器中,您可以根据存储在不同组件中的相应控制器/操作要求添加 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() 中仅添加当前接口所需的元素。 (我宁愿在每个构建器中重复代码,也不愿依赖这种“魔法”,但这是一种可行的方法)。

You could make yourself a factory that receive three params, your form element, the current controller and the current action. Then in that factory, you could call a builder based on the controller/action combination and you pass your form.

In your builder you add 1, 2 or 3 buttons based on the corresponding controller/action requirement which are stored in diffrent components. Once it is done, you return your form to the factory and the factory return the form.

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

If you want to automatize the instanciation you could initialize all the different compoments you might require in an abstract class and in the method buildForm() only add the elements you need for that current interface. (I would rather repeat the code in each builder than rely on this kind of "magic" but it a viable method to do it).

烟火散人牵绊 2024-12-04 03:44:15

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

简单答案

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

长答案

要了解整个情况,请想象每次单击下一个或上一个按钮时,您都在遍历一系列子表单。在这种情况下,需要一个函数来处理按钮渲染。我最终使用了一个 case 语句,尽管它不是世界上最好的实现(在父类 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;
}

So the complexity of my problem comes with knowing what page of the multipage form. Using an array and the above mentioned addElements() helped.

Simple Answer

The answer to my problem was an array that could be manipulated after the form was "built" so to speak but before it was rendered so that I could add to the form using addElements().

Long Answer

To get the whole picture, imagine each time you hit the next or previous button, you are traversing through an array of subforms. In this case one would need a function to handle the button rendering. I ended up using a case statment, though it's not the best implementation in the world (not reusable in the parent class Form_MultiPage), but it worked:

in my extention of my mulipage form class I have

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);
}

In my parent class, Form_Multipage, I have

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

And

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

Which is called when I render the "page" of the form with this function

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文