Заполнение данных формы в ZF2 при использовании наборов полей

В настоящее время я играю с ZF2 beta 4, и я, кажется, застрял, когда пытаюсь использовать наборы полей в форме и возвращать данные в форму при отправке формы. Я не уверен, правильно ли я устанавливаю входные фильтры для наборов полей или что-то упускаю. Например, у меня есть следующее (упрощено, чтобы было понятно):

Контроллер

public function indexAction(){
   $form = new MyForm();
   $request = $this->getRequest();
          if ($request->isPost()) {
                 $form->setData($request->post());
                 if ($form->isValid()) {
                        //Do something
                        print_r($form->getData()); //for debug
                 }
          }
   return array('form' => $form);
}

MyForm.php

class MyForm extends Form
{
    public function __construct()
    {
        parent::__construct();
        $this->setName('myForm');
        $this->setAttribute('method', 'post');

        $this->add(array(
                    'name' => 'title',
                    'attributes' => array(
                    'type'  => 'text',
                    'label' => 'Title',
                    ),
                 ));

        $this->add(new MyFieldset('myfieldset'));

        //setting InputFilters here
        $inputFilter = new InputFilter();
        $factory = new InputFactory();

        $inputFilter->add($factory->createInput(array(
            'name'     => 'title',
            'required' => true,
            'filters'  => array(
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
        )));

        //Now add fieldset Input filter
        foreach($this->getFieldsets() as $fieldset){
              $fieldsetInputFilter = $factory->createInputFilter($fieldset->getInputFilterSpecification());
              $inputFilter->add($fieldsetInputFilter,$fieldset->getName());
        }

        //Set InputFilter
        $this->setInputFilter($inputFilter);
    }
}

MyFieldset.php

class MyFieldset extends Fieldset implements InputFilterProviderInterface{
    public function __construct($name)
    {
        parent::__construct($name);
        $factory = new Factory();

        $this->add($factory->createElement(array(
            'name' => $name . 'foo',
            'attributes' => array(
                'type'  => 'text',
                'label' => 'Foo',
            ),
        )));
    }

    public function getInputFilterSpecification(){
        return array(
            'foo' => array(
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
            ),
        );
    }
}

Я могу вывести форму, как и ожидалось, и в итоге я получаю два элемента ввода с именами «title» и «myfieldsetfoo» (имя, данное при выводе с помощью ViewHelper). Поэтому, конечно, когда я отправлю необработанный пост, будут показаны значения для «заголовок» и «myfieldsetfoo». Однако, когда я использую SetData(), значения для набора полей не заполняются (хотя я вижу значения в необработанном объекте сообщения). Вместо этого, изучая вывод '$form->getData()', я получаю:

Array(
   [title] => Test,
   [myfieldset] => Array(
                         [foo] =>
                        )
)

Что мне не хватает? Что мне нужно сделать, чтобы ZF2 понял, как заполнить набор полей?

Спасибо за любую помощь, это сводит меня с ума.


person Jaime R.    schedule 08.06.2012    source источник


Ответы (3)


Почему я это делаю, так это объединяю InputFilter, чтобы я мог обрабатывать весь опубликованный массив HTML-форм.

<form method="POST">
<input type="text" name="main[name]" />
<input type="text" name="main[location]" />
<input type="text" name="contact[telephone]" />

<input type="submit" value="Send" />
</form>

Это создаст массив, размещенный как

post["main"]["name"]
post["main"]["location"]
post["contact"]["telephone"]

Отфильтровано и проверено с помощью:

use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;

$post = $this->request->getPost();
$inputFilter = new InputFilter();
$factory = new InputFactory();

// $post["main"]
$mainFilter = new InputFilter();
$mainFilter->add($factory->createInput(array(
    'name'     => 'name',
    'required' => true,
    'filters'  => array(
        array('name' => 'StripTags'),
        array('name' => 'StringTrim'),
    ),
    'validators' => array(
        array(
            'name'    => 'StringLength',
            'options' => array(
                'encoding' => 'UTF-8',
                'min'      => 1,
                'max'      => 100,
            ),
        ),
    ),
    )));

$mainFilter->add($factory->createInput(array(
    'name'     => 'location',
    'required' => true,
    'filters'  => array(
        array('name' => 'StripTags'),
        array('name' => 'StringTrim'),
    ),
    'validators' => array(
        array(
            'name'    => 'StringLength',
            'options' => array(
                'encoding' => 'UTF-8',
                'min'      => 1,
                'max'      => 100,
            ),
        ),
    ),
    )));
$inputFilter->add($mainFilter, "main");

// $post["contact"]
$contactFilter = new InputFilter();
$contactFilter->add($factory->createInput(array(
    'name'     => 'name',
    'required' => true,
    'filters'  => array(
        array('name' => 'StripTags'),
        array('name' => 'StringTrim'),
    ),
    'validators' => array(
        array(
            'name'    => 'StringLength',
            'options' => array(
                'encoding' => 'UTF-8',
                'min'      => 1,
                'max'      => 100,
            ),
        ),
    ),
    )));
$contactFilter->add($mainFilter, "contact");

//Set posted data to InputFilter
$inputFilter->setData($post->toArray());

http://www.unexpectedit.com/zf2/inputfilter-validate-and-filter-a-form-data-with-fieldsets

person Ignacio Pascual    schedule 17.08.2012
comment
+1 для этой строки $contactFilter->add($mainFilter, "contact");. Теперь я знаю, как применить фильтр для наборов полей. Спасибо! - person Vinicius Garcia; 17.12.2012

Я думаю, вы забыли подготовить свою форму в контроллере:

return array('form' => $form->prepare());

Это переименует поле «имя» вашего набора полей в «myfieldset [foo]», поэтому вам не нужно добавлять имя набора полей самостоятельно.

Просто используйте

'name' => 'foo'

вместо

'name' => $name . 'foo'

в вашем классе набора полей.

person MaGna    schedule 11.09.2014

Я думаю, проблема в том, что вы объявляете новую форму в своем контроллере. И это очищает предыдущую форму.

$form = new MyForm();

Я использую Service Manager для объявления формы и фильтров. И затем в контроллере я делаю:

$form = $this->getServiceLocator()->get('my_form');

Таким образом, я всегда получаю объект, который хочу

Обновлять

Я больше не использую сервис-менеджер для вызова форм. Я просто вызываю новую форму и выдаю $form->setData($data);

Источником данных также может быть сущность, хотя тогда я бы выдал: $form->bind($entity)

person michaelbn    schedule 09.06.2012
comment
Этот способ объявления формы аналогичен тому, что сделано здесь http://akrabat.com/zend-framework-2-tutorial/. Я вижу проблему только тогда, когда использую наборы полей. Если у меня есть простая форма (и даже элементы, не входящие в набор полей), у меня нет проблем с возвратом данных. - person Jaime R.; 12.06.2012
comment
Метод создания экземпляра формы не имеет абсолютно никакого отношения к этому вопросу. - person Daniel Ingraham; 15.04.2013