Zf2 - установить значение в элементе внутри коллекции

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

$form->get('submit')->setValue('Update');

Как я могу установить значение в поле "Адрес", например, "в коллекции" "Я использую Zend Framework 2".

$companies = $this->getCompaniesTable()->getCompanies($id);
$form = new CompaniesForm();
$form->bind($companies);
$form->get('submit')->setValue('Update');
$form->get('submit')->setValue('Update');
$form->get('address')->setValue('test address');

Последняя строка пред. код не работает, что не так?!

Код формы:

<?php

namespace Companies\Form;

//use Zend\Form\Element;
use Zend\Form\Form;

class CompaniesForm extends Form {

    public function __construct($name = null) {
        parent::__construct('companies');
        $this->setAttribute('method', 'post');
        $this->setAttribute('enctype', 'multipart/form-data');

        $this->add(array(
            'name' => 'id',
            'type' => 'Hidden'
        ));

        $this->add(array(
            'name' => 'name',
            'type' => 'Text'
        ));

        // address field
        $this->add(array(
            'type' => 'Zend\Form\Element\Collection',
            'name' => 'address',
            'options' => array(
                'count' => 1,
                'should_create_template' => false,
                'allow_add' => true,
                'template_placeholder' => '__placeholder__',
                'target_element' => array(
                    'type' => 'Companies\Form\AddressFieldset'
                )
            ),
        ));
        // address field

        // email field
        $this->add(array(
            'name' => 'email',
            'type' => 'text',
            'options' => array('label' => 'Email:'),
        ));

        $this->add(array(
            'name' => 'submit',
            'type' => 'Submit',
            'attributes' => array(
                'value' => 'Go',
                'id' => 'submitbutton'
            )
        ));
    }

}

Файл addressFieldset:

<?php

namespace Companies\Form;

use Companies\Entity\Address;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;

class AddressField {

    /**
     * @var string
      \ */
    protected $name;

    /**
     * @param string $name
     * @return Address
      \ */
    public function setName($name) {
        $this->name = $name;
        return $this;
    }

    /**
     * @return string
      \ */
    public function getName() {
        return $this->name;
    }

}

class AddressFieldset extends Fieldset implements InputFilterProviderInterface {

    public function __construct() {
        parent::__construct('Address');
        $this->setHydrator(new ClassMethodsHydrator(false))->setObject(new AddressField());

        $this->add(array(
            'name' => 'name',
            'options' => array(
                'label' => 'Address: '
            )
        ));
    }

    /**
     * @return array
      \ */
    public function getInputFilterSpecification() {
        return array(
            'name' => array(
                //'required' => true,
            )
        );
    }

}

4 ответа

Вам нужно взять коллекцию как элемент из вашей формы, и вы получите список наборов полей вашей коллекции. По вашему мнению:

$collection = $form->get('address');
$fieldSets = $collection->getFieldsets();

// In your example you use one element as field set count = 1
// I guess you want to change field named address in your collection of the same name

$address = $fieldSets[0]->get('address');
$address->setValue('test adress');

//If you have more field sets in your collection for example count = 3 and you want this    
//value for all of them just iterate your field sets.

foreach($fieldsets as $fieldset){
    $fieldset->get('address')->setValue('test adress');
}

Для этого вы можете использовать Form populateValues ​​() вместо метода setValue(): http://framework.zend.com/apidoc/2.3/classes/Zend.Form.Form.html

Так что в вашем случае вы должны вставить в свой контроллер:

$form = new CompaniesForm();
$addresses = array(
    array(
        'name' => 'address field 1 name'
    ),
    array(
        'name' => 'address field 2 name'
    ),
);
$form->get('address')->populateValues($addresses);

Например, вы можете создать массив адресов, используя данные из вашей БД.

Если вы хотите сделать это в контроллере с помощью getTargetElement() вернет элемент или набор полей, назначенные в коллекции.

$fieldset = $form->get('parent_fieldset');
$collection = $fieldset->get('collection');
$collectionFieldset = $collection->getTargetElement();
$collectionFieldset->get('element')->setValue($value);

Ладно, похоже, что некоторые вещи перепутаны здесь. Вы пытаетесь вручную назначить значения полей внутри EditForm, Это не хорошо.

Представьте себе простую форму

UserForm
   textInput ("name")
   textInput ("surname")
   numberInput ("age")

Теперь вы хотите редактировать User, Таким образом, вы получаете данные из БД

//$userData = $db->get('userdata')...
$userData = array(
    'name'    => 'Peter',
    'surname' => 'Parker',
    'age'     => 23
);

Чтобы вставить существующие значения в форму, все, что вам нужно сделать, это установить ФОРМУ в эти данные.

$form->setData($userData);

И это все. В вашем случае, очевидно, структура данных немного отличается и сложнее. Вы должны иметь любой основной объект, который вы могли бы $form->bind() или ваш массив, который вы устанавливаете данные форм для использования $form->setData() должен быть изменен. В вашем случае это будет:

$data = array(
    'id' => 1, // your objects id
    'name' => 'someName',
    'email' => 'foo@bar.baz',
    'address' => array(
        0 => array(
            'streetName'   => 'FooStreet',
            'streetNumber' => 42
        ),
        1 => array(
            'streetName'   => 'OofStreet',
            'streetNumber' => 24
        ),
    )
)

Когда вы делаете $form->setData($data) В приведенном выше случае ваша форма будет предварительно заполнена данными, поступающими из массива. Естественно, вам придется получать данные из БД, а не записывать массив вручную.

Другие вопросы по тегам