我目前正在玩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输出时给出的名称)。所以当然我提交原始帖子时会显示'title'和'myfieldsetfoo'的值。但是,当我使用SetData()时,字段集的值没有被填充(尽管我可以看到原始post对象中的值)。相反,检查'$ form-> getData()'的输出我收到:
Array(
[title] => Test,
[myfieldset] => Array(
[foo] =>
)
)
我错过了什么?我需要做什么才能让ZF2了解如何填充字段集?
感谢您的帮助,这让我发疯。
答案 0 :(得分:8)
为什么我这样做是连接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
答案 1 :(得分:0)
我想你忘记在控制器中准备你的表格了:
return array('form' => $form->prepare());
这会将您的fieldset的“name”字段重命名为“myfieldset [foo]”,因此您不必自行添加字段集名称。
只需使用
'name' => 'foo'
而不是
'name' => $name . 'foo'
在你的fieldset类中。
答案 2 :(得分:-1)
我认为问题在于您在控制器中声明了一个新表单。这清楚了以前的形式。
$form = new MyForm();
我使用服务管理器来声明表单和过滤器。 然后在控制器中我做:
$form = $this->getServiceLocator()->get('my_form');
这样我总能得到我想要的对象
我不再使用服务管理器来调用表单。我只需要调用一个新表单并发出$ form-&gt; setData($ data);
数据的来源也可以是实体,但我会发出:$ form-&gt; bind($ entity)