Есть ли способ добавить группу элементов в форму? - PullRequest
1 голос
/ 29 июля 2011

Мне интересно, если бы был способ добавить группу элементов в форму Zend, как если бы они были одним элементом, я думаю, очень похоже на подчиненную форму, но кажется, что функциональность подчиненной формы может быть слишком много .. .

Вот мой вариант использования. Я создал класс, который обрабатывает многостраничные формы. Я хочу иметь возможность писать логику для изменения кнопок в нижней части формы на основе страницы формы, на которой я нахожусь. Form Page 1Form Page 2Form page 3

Первоначально я думал, что Zend-Form-DisplayGroup решит мою проблему, но вы должны сначала добавить элементы в форму, а затем добавить их в группу отображения и не можете передать группу отображения через функцию с прикрепленными элементами , Я хотел бы иметь функцию, которая будет что-то вроде

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

Идея использования массива элементов просто поразила меня прямо сейчас, в отличие от чего-то другого, и добавила логику, чтобы добавить этот массив элементов в форму при рендеринге ... но есть ли у кого-нибудь "лучшие" идеи или это сделано раньше?

Кстати, если кому-то интересно ... Я свободно основываю свой первоначальный дизайн на этом разделе: Использование предварительной формы Zend Framework.

Ответы [ 3 ]

1 голос
/ 29 июля 2011

Не уверен, что я правильно понимаю вашу проблему, но вот как я делаю некоторые вещи.

В объекте Zend_Form вы можете добавлять элементы в виде группы с `addElements ($ elements) в массиве.Для кнопки «Отправить» и т. Д. У меня есть класс, из которого я получаю массив $ elements, а затем просто вставляю его. Я также добавляю displayGroup, но отдельно и просто для управления расположением кнопок.Поскольку форма - это объект, вы можете делать простые вещи, такие как следующие, но я всегда добавляю ссылку, чтобы показать мои намерения.

update: перетасовано манипулирование кнопками

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');
1 голос
/ 29 июля 2011

Вы можете сделать себя фабрикой, которая получает три параметра, ваш элемент формы, текущий контроллер и текущее действие. Затем на этой фабрике вы могли бы вызвать строителя на основе комбинации «контроллер / действие» и передать свою форму.

В вашем компоновщике вы добавляете 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 () добавить только те элементы, которые вам нужны для этого текущего интерфейса. (Я бы лучше повторил код в каждом сборщике, чем полагался на этот вид «магии», но это жизнеспособный способ сделать это).

0 голосов
/ 06 августа 2011

Итак, сложность моей проблемы заключается в том, чтобы знать, какая страница многостраничной формы. Помогло использование массива и вышеупомянутых addElements ().

Простой ответ

Ответом на мою проблему был массив, которым можно было манипулировать после того, как форма была, так сказать, «построена», но до того, как она была визуализирована, чтобы я мог добавить ее в форму с помощью addElements ().

Длинный ответ

Чтобы получить полную картину, представьте, что каждый раз, когда вы нажимаете следующую или предыдущую кнопку, вы просматриваете массив субформ. В этом случае понадобится функция для обработки рендеринга кнопок. Я закончил тем, что использовал регистрацию случая, хотя это не лучшая реализация в мире (не может быть повторно использована в родительском классе Form_MultiPage), но это сработало:

в моем расширении моего многостраничного класса у меня есть

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