【问题标题】:How to create custom form element in Zend Framework 2?如何在 Zend Framework 2 中创建自定义表单元素?
【发布时间】:2012-12-08 10:06:52
【问题描述】:

如何在 ZF2 中使用自定义验证器创建自定义表单元素?我想创建使用 jQuery 的自定义类别选择器,并且该元素的内容应该从 phtml 脚本呈现。在 ZF1 中这很容易,但在 ZF2 中我不知道从哪里开始。

【问题讨论】:

    标签: zend-framework2


    【解决方案1】:

    表单元素必须实现Zend\Form\ElementInterface。默认类是Zend\Form\Element,您可以将其用作基本形式:

    <?php
    namespace MyModule\Form\Element;
    
    use Zend\Form\Element;
    
    class Foo extends Element
    {
    }
    

    自定义验证器

    您可以让元素直接分配自定义验证器。然后你必须实现Zend\InputFilter\InputProviderInterface

    <?php
    namespace MyModule\Form\Element;
    
    use Zend\Form\Element;
    use Zend\InputFilter\InputProviderInterface;
    use MyModule\InputFilter\Bar as BarValidator;
    
    class Foo extends Element implements InputProviderInterface
    {
        protected $validator;
    
        public function getValidator()
        {
            if (null === $this->validator) {
                $this->validator = new BarValidator;
            }
            return $this->validator;
        }
    
        public function getInputSpecification()
        {
            return array(
                'name'       => $this->getName(),
                'required'   => true,
                'validators' => array(
                    $this->getValidator(),
                ),
            );
        }
    }
    

    自定义渲染

    目前,Zend Framework 如何处理自定义表单元素类型的呈现有点复杂。通常,它只返回普通的 &lt;input type="text"&gt; 元素。

    有一个选项,然后您必须覆盖 Zend\Form\View\Helper\FormElement 助手。它注册为formelement,您必须在自定义模块中覆盖此视图助手:

    namespace MyModule;
    
    class Module
    {
        public function getViewHelperConfig()
        {
            return array(
                'invokables' => array(
                    'formelement' => 'MyModule\Form\View\Helper\FormElement',
                    'formfoo'     => 'MyModule\Form\View\Helper\FormFoo',
                ),
            );
        }
    }
    

    此外,Zend Framework 2 中的每个表单元素都由视图助手呈现。因此,您为自己的元素创建了一个视图助手,它将呈现元素的内容。

    然后你必须创建自己的表单元素助手(MyModule\Form\View\Helper\FormElement):

    namespace MyModule\Form\View\Helper;
    
    use MyModule\Form\Element;
    use Zend\Form\View\Helper\FormElement as BaseFormElement;
    use Zend\Form\ElementInterface;
    
    class FormElement extends BaseFormElement
    {
        public function render(ElementInterface $element)
        {
            $renderer = $this->getView();
            if (!method_exists($renderer, 'plugin')) {
                // Bail early if renderer is not pluggable
                return '';
            }
    
            if ($element instanceof Element\Foo) {
                $helper = $renderer->plugin('form_foo');
                return $helper($element);
            }
    
            return parent::render($element);
        }
    }
    

    作为最后一步,创建您的视图助手来呈现这个特定的表单元素:

    namespace MyModule\Form\View\Helper;
    
    use Zend\Form\ElementInterface;
    use Zend\Form\View\Helper\AbstractHelper;
    
    class Foo extends AbstractHelper
    {
        public function __invoke(ElementInterface $element)
        {
            // Render your element here
        }
    }
    

    如果您想为此表单元素呈现一个 .phtml 文件,请将其加载到此帮助程序中:

    namespace MyModule\Form\View\Helper;
    
    use Zend\Form\ElementInterface;
    use Zend\Form\View\Helper\AbstractHelper;
    
    class Foo extends AbstractHelper
    {
        protected $script = 'my-module/form-element/foo';
    
        public function render(ElementInterface $element)
        {
            return $this->getView()->render($this->script, array(
                'element' => $element
            ));
        }
    }
    

    它将呈现一个my-module/form-element/foo.phtml,并且在此脚本中,您将拥有一个变量$element,其中包含您的特定表单元素。

    【讨论】:

    • 我得到 Catchable 致命错误:参数 1 传递给 MyModule\Form\View\Helper\FormElement::render() 必须是 MyModule\Form\View\Helper\ElementInterface 的实例,Zend 的实例\Form\Element 给定
    • 当我添加表单元素时,它仍然是 Zend\Form\Element 而不是 Element\Foo 的实例,我正在添加如下内容:$this-&gt;add(array( 'name' =&gt; 'category', 'attributes' =&gt; array( 'type' =&gt; 'MyModule\Form\Elemen\Foo', ));
    • @Maciej 你是对的,我犯了两个错误:在FormElement 视图助手中,您还必须导入ElementInterface,否则您会收到上述警告。在呈现自定义表单元素的视图助手中犯了第二个错误。检查差异以查看差异,我认为这应该可以解决所有问题:stackoverflow.com/posts/13776839/revisions
    • 是的,它更好,但我仍然无法渲染元素,可能我在表单类中做错了:class MyForm extends Form { public function __construct($name = null) { // we want to ignore the name passed parent::__construct('album'); $this-&gt;setAttribute('method', 'post'); $this-&gt;add(array( 'name' =&gt; 'category', 'attributes' =&gt; array( 'type' =&gt; 'Element\Foo', ), 'options' =&gt; array( 'label' =&gt; 'Category', ), )); } }
    • 它曾经使用render()方法。现在所有表单视图助手显然都进行了大修,所以它不再起作用了。我编辑了答案,因为 render() 应该重命名为 __invoke()
    猜你喜欢
    • 2013-02-15
    • 2023-03-20
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多