How to create custom form element in Zend Framework 2?

后端 未结 1 533
你的背包
你的背包 2021-02-08 13:02

How can I in ZF2 create custom form element with custom validator? I want to create custom category picker that uses jQuery and content of this element should be rendered from p

相关标签:
1条回答
  • 2021-02-08 14:08

    A form element must implement a Zend\Form\ElementInterface. A default class is the Zend\Form\Element which you can use as a base form:

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

    CUSTOM VALIDATOR

    You can let the element directly assign a custom validator. Then you must implement the 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(),
                ),
            );
        }
    }
    

    CUSTOM RENDERING

    At this moment it is a bit complex how Zend Framework handles the rendering of custom form element types. Usually, it just returns plain <input type="text"> elements.

    There is one option, then you have to override the Zend\Form\View\Helper\FormElement helper. It is registered as formelement and you must override this view helper in your custom module:

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

    Furthermore, every form element in Zend Framework 2 is rendered by a view helper. So you create a view helper for your own element, which will render the element's content.

    Then you have to create your own form element helper (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);
        }
    }
    

    As a last step, create your view helper to render this specific form 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
        }
    }
    

    If you want to render a .phtml file for example for this form element, load it inside this helper:

    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
            ));
        }
    }
    

    It will render a my-module/form-element/foo.phtml and in this script you will have a variable $element which contains your specific form element.

    0 讨论(0)
提交回复
热议问题