每当我提交表单时,我都会收到此消息:
The input was not found in the haystack.
这是针对shipping-method
元素(单选按钮)。无法弄清楚它的含义,该元素的POST数据不为空。
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
// Some other basic filters
$inputFilter->add(array(
'name' => 'shipping-method',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim')
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'max' => 20,
),
),
array(
'name' => 'Db\RecordExists',
'options' => array(
'table' => 'shipping',
'field' => 'shipping_method',
'adapter' => $this->dbAdapter
)
),
),
));
$inputFilter->get('shipping-address-2')->setRequired(false);
$inputFilter->get('shipping-address-3')->setRequired(false);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
我只会继续寻找<select>
的解决方案。
这是示例POST数据:
object(Zend\Stdlib\Parameters)#143 (1) {
["storage":"ArrayObject":private] => array(9) {
["shipping-name"] => string(4) "TEST"
["shipping-address-1"] => string(4) "test"
["shipping-address-2"] => string(0) ""
["shipping-address-3"] => string(0) ""
["shipping-city"] => string(4) "TEST"
["shipping-state"] => string(4) "TEST"
["shipping-country"] => string(4) "TEST"
["shipping-method"] => string(6) "Ground"
["submit-cart-shipping"] => string(0) ""
}
}
更新: form.phtml
<div class="form-group">
<?= $this->formRow($form->get('shipping-method')); ?>
<?= $this->formRadio($form->get('shipping-method')
->setValueOptions(array(
'Ground' => 'Ground',
'Expedited' => 'Expedited'))
->setDisableInArrayValidator(true)); ?>
</div>
ShippingForm.php
$this->add(array(
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Shipping Method',
'label_attributes' => array(
'class' => 'lbl-shipping-method'
),
)
));
答案 0 :(得分:0)
昨天发生了这件事。
select和multi select ZF2 +元素有一个内置的in_array验证器。
记住过滤器在验证器之前发生。
你可能在这里做得太多了 - 很少需要在ZF2表单中过滤或添加验证器或选择和多选表单元素。内置元素验证器非常强大,ZF为我们做了很多工作。
尝试删除元素的过滤器和验证器,例如:
<ul>
<li>lorem</li>
<li>lorem</li>
<li>lorem</li>
<li>lorem</li>
<li>
lorem
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</li>
</ul>
我见过另一个边缘情况:在控制器(或视图)中的某处更改select元素的valueOptions,导致在视图与表单验证中使用不同的valueOptions(在我们的例子中,它在更换元素之前使用新元素验证)。
答案 1 :(得分:0)
我认为你的问题在于你在设置了InArray验证器之后添加了你的值选项,因此验证器没有干草堆。
试试这个
$this->add(array(
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Shipping Method',
'label_attributes' => array(
'class' => 'lbl-shipping-method'
),
'value_options' => array(
'Ground' => 'Ground',
'Expedited' => 'Expedited'
),
'disable_inarray_validator' => TRUE,
)
));
并从视图中删除setValueOptions和setDisableInArrayValidator。
希望这有效。
答案 2 :(得分:0)
问题出在您使用setValueOptions()
和setDisableInArrayValidator()
时。您应该在代码中提前执行此操作,因为在验证表单之前从未设置它,因此inputfilter仍然包含默认值InArray
验证程序。在验证后检查inputfilter,您可以为shipping_methods设置不同的选项。
您应该在setValueOptions()
之前移动setDisableInArrayValidator()
和$form->isValid()
。通过在表单中设置正确的选项或在控制器中执行此操作。最好的方法是将所有选项保存在一个位置并在表单类中进行。
$this->add([
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => [
'value_options' => [
'Ground' => 'Ground',
'Expedited' => 'Expedited'
],
'disable_inarray_validator' => true,
'label' => 'Shipping Method',
'label_attributes' => [
'class' => 'lbl-shipping-method',
],
],
]);
您可能想要更改的另一个小细节是设置值选项。它们现在是硬编码的,但是您的inputfilter正在检查数据库记录是否存在。使用数据库记录填充值选项。如果代码仍包含旧方法但数据库有一些新方法,则它们不同步。
class ShippingForm extends Form
{
private $dbAdapter;
public function __construct(AdapterInterface $dbAdapter, $name = 'shipping-form', $options = [])
{
parent::__construct($name, $options)
// inject the databaseAdapter into your form
$this->dbAdapter = $dbAdapter;
}
public function init()
{
// adding form elements to the form
// we use the init method to add form elements as from this point
// we also have access to custom form elements which the constructor doesn't
$this->add([
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => [
'value_options' => $this->getDbValueOptions(),
'disable_inarray_validator' => true,
'label' => 'Shipping Method',
'label_attributes' => [
'class' => 'lbl-shipping-method',
],
],
]);
}
private function getDbValueOptions()
{
$statement = $this->dbAdapter->query('SELECT shipping_method FROM shipping');
$rows = $statement->execute();
$valueOptions = [];
foreach ($rows as $row) {
$valueOptions[$row['shipping_method']] = $row['shipping_method'];
}
return $valueOptions;
}
}