Skip to content
This repository was archived by the owner on Jun 4, 2021. It is now read-only.

Core_Form_Multipage

Nikolay Galkin edited this page Jun 7, 2013 · 1 revision

Введение

В качестве примера использования мультиформ будет реализован механизм создания предложений, разделенный на такие этапы:

  1. General information (name, email);
  2. Proposal information (proposal);
  3. Captcha (captcha).

1. Создание формы

В данном примере используется модуль dev

class Dev_Model_Proposal_Form_CreateMulti extends Core_Form_Multipage
{
    protected $_namespace = __CLASS__;

    public function init()
    {

    }
}

Атрибут Core_Form_Multipage::$_namespace является идентификатором данных формы в сессии, можно использовать любое текстовое значение, в примере используется имя класса.

ВНИМАНИЕ! Данный атрибут обязателен и должен быть определен.

Далее необходимо добавить необходимые подформы (SubForms):

General information (name, email);

class Dev_Model_Proposal_Form_CreateMulti_General extends Zend_Form_SubForm
{
    public function init()
    {
        $username = new Zend_Form_Element_Text('login');
        $username->setLabel('Your name')
                 ->setRequired(true)
                 ->addFilter('StripTags')
                 ->addFilter('StringTrim')
                 ->addValidator('Alnum')
                 ->addValidator(
                     'StringLength', false,
                     array(Model_User::MIN_USERNAME_LENGTH,
                           Model_User::MAX_USERNAME_LENGTH)
                 )
                 ->addValidator(
                     'Db_NoRecordExists', false,
                     array(
                         array('table' => 'users',
                               'field' => 'login')
                     )
                 );

        $email = new Zend_Form_Element_Text('email');
        $email->setLabel('Email')
              ->setRequired(true)
              ->setValue(null)
              ->addValidator('StringLength', false, array(6))
              ->addValidator('EmailAddress');

        $this->addElements(array($username, $email));
        $this->setLegend('Step 1/3 Your information (all fields are mandatory)');

        return $this;
    }
}

Proposal information (proposal);

class Dev_Model_Proposal_Form_CreateMulti_Proposal extends Zend_Form_SubForm
{
    public function init()
    {
        $proposal = new Zend_Form_Element_Textarea(
            'comment', array(
                'label'      => 'Your proposal:',
                'cols'       => '50',
                'rows'       => '5',
                'required'   => true,
                'filters'    => array('StringTrim', 'HtmlEntities'),
                'validators' => array(
                    array(
                        'validator' => 'StringLength',
                        'options' => array(1, 250)
                    )
                )
            )
        );

        $this->addElements(array($proposal));
        $this->setLegend('Step 2/3: Proposal text (all fields are mandatory)');

        return $this;
    }
}

Captcha (captcha).

class Dev_Model_Proposal_Form_CreateMulti_Captcha extends Zend_Form_SubForm
{
    public function init()
    {
        $imgDir = dirname(APPLICATION_PATH) . "/public/images/captcha";

        // check captcha path is writeable
        if (is_writable($imgDir)) {
            $captcha = new Zend_Form_Element_Captcha(
                'captcha',
                array(
                    'label' => "Please verify you're a human",
                    'captcha' => 'Image',
                    'captchaOptions' => array(
                        'captcha' => 'Image',
                        'wordLen' => 6,
                        'timeout' => 300,
                        'imgDir' => $imgDir,
                        'font' => dirname(APPLICATION_PATH) .
                                  "/data/fonts/Aksent_Normal.ttf",
                    ),
                )
            );
        } else {
            $captcha = new Zend_Form_Element_Captcha(
                'captcha',
                array(
                    'label' => "Please verify you're a human",
                    'captcha' => 'Figlet',
                    'captchaOptions' => array(
                        'wordLen' => 6,
                        'timeout' => 300,
                    ),
                )
            );
        }

        $this->addElements(array($captcha));
        $this->setLegend('Step 3/3: Captcha (all fields are mandatory)');

        return $this;
    }
}

Подформы (SubForms) созданы, теперь можно привязать из к основной форме:

public function init()
{
    $this->setAction('/dev/proposal/create')->setMethod('post');
    
    $sfGeneral = new Dev_Model_Proposal_Form_CreateMulti_General();
    $sfProposal = new Dev_Model_Proposal_Form_CreateMulti_Proposal();
    $sfCaptcha = new Dev_Model_Proposal_Form_CreateMulti_Captcha();
    
    // Attach sub forms to main form
    $this->addSubForms(array(
        array($sfGeneral, 'general', 10),
        array($sfProposal, 'proposal', 20),
        array($sfCaptcha, 'captcha', 30),
    ));
    
    return $this;
}

Желательно однозначно указать порядковый номер подформ (SubForms)

2. Создание действия в контроллере

public function createAction()
{
    $step = $this->getRequest()->getParam('step', null);
    $reset = $this->getRequest()->getParam('reset', null);

    $multiform = new Dev_Model_Proposal_Form_CreateMulti();

    if ($this->getRequest()->isPost()) {
        if ($multiform->isValid($this->getRequest()->getPost()) ) {
            // Тут можно выполнить необходимые действия с полученными данными
            // например, вывести строкой во всплывающем сообщении
            $formValues = $multiform->getValues();
            $this->_flashMessenger->addMessage(serialize($formValues));

            $multiform->reset();
            $this->_redirect('/dev/proposal/');
        }
    } elseif ($step) {
        $multiform->setCurrent($step);
    } elseif ($reset) {
        $multiform->reset();
        $this->_redirect('/dev/proposal/');
    }

    $this->view->form = $multiform;
}

Как можно заметить, различий между использованием обычной формы и multipage формы практически нет.

3. Создание представления

<h1>Create proposal</h1>
<h3><?php echo $this->form->getCurrent()->getLegend(); ?></h3>
<ul class="form-controls" style="overflow: hidden;">
    <li>Paginator: </li>
    <?php foreach ($this->form->getSubForms(true) as $item): ?>
    <?php if ($item->getName() == $this->form->getCurrent()->getName()): ?>
        <li><?php echo $item->getName(); ?></li>
    <?php else: ?>
        <li><a href="<?php echo $this->url(array('step' => $item->getName())); ?>"><?php echo $item->getName(); ?></a></li>
    <?php endif; ?>
    <?php if (!$this->form->isStored($item)) break; ?>
    <?php endforeach; ?>
    <li>[<a href="<?php echo $this->url(array('module' => 'dev', 'controller' => 'proposal', 'action' => 'create', 'reset' => '1'), null, true); ?>">Reset</a>]</li>
</ul>
<div><?php echo $this->form->getCurrent(); ?></div>

Clone this wiki locally