单选按钮:在大海捞针中找不到输入?

时间:2017-12-29 02:53:22

标签: forms zend-framework2

每当我提交表单时,我都会收到此消息:

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'
            ),
        )
    ));

3 个答案:

答案 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;
    }
}