【问题标题】:Zend Framework 3 Form FieldsetZend Framework 3 表单字段集
【发布时间】:2018-04-19 08:53:10
【问题描述】:

嘿, 我对 Zend-Framework 3 真的很陌生,而且我正在练习 OOP,我找不到关于制作带有字段集和图例的 Zend 表单的简单解释/教程。基本上我正在尝试在 HTML 中创建它:

<form name="my_name">
    <fieldset>
        <legend>My legend value</legend>
        <input type="checkbox" name="name_1" value="value_1">Value 1</input>
        <input type="checkbox" name="name_2" value="value_2">Value_2</input>
        <input type="checkbox" name="name_3" value="value_3">Value_3</input>
    </fieldset>
    <input type="button" value="Get values" id="btn"/>
</form>

我查看了有关 Zend Forms and Collections and Fieldsets 的官方文档,但这真的让我很困惑。任何帮助将不胜感激。

【问题讨论】:

    标签: zend-framework3


    【解决方案1】:

    实际上,您正在寻找的示例是 zend 形式的“集合”部分。它不是确切的,但有点像。

    这是一个小例子。我忽略了命名空间,希望没有错字:)

    class myFieldset extends Fieldset {
        public function init(){
          $this
             ->add([
               'name' => 'name_1,
               'type' => 'text',
          ])
             ->add([
               'name' => 'name_2,
               'type' => 'text',
          ])
             ->add([
               'name' => 'name_3,
               'type' => 'text',
          ]);
        }
    }
    
    
    class MyForm extends Form {
         public function init(){
             $this->add([
                 'type' => myFieldset,
                  'name' => 'fieldset'
             ])->add([
                 'type' => 'button',
                  'name' => 'action'
             ]);
         }
    }
    

    在视图文件中;

    <?=$this-form($form);?>
    

    【讨论】:

    • 抱歉。您正在寻找复选框。这意味着您将自己呈现表单。
    【解决方案2】:

    首先,我很抱歉,因为它会有点长。但这将描述行动中的形式。所以请耐心等待!

    假设你知道 ZF3 默认Application 模块。在Application 模块中创建了一些文件夹,用于分隔每个元素。您需要按如下方式创建它们。

    让我们首先创建您的字段集。 Zend\Form\Fieldset 组件表示一组可重用的元素,并且依赖于 Zend\From\Form 组件。这意味着您需要将此附加到Zend\Form\Form

    module/Application/src/Form/Fieldset/YourFieldset.php

    <?php
    namespace Application\Form\Fieldset;
    
    use Zend\Form\Element;
    use Zend\Form\Fieldset;
    
    class YourFieldset extends Fieldset
    {
    
        public function __construct($name = null)
        {
            parent::__construct('your-fieldset');
    
            $this->add([
                'name' => 'name_1',
                'type' => Element\Checkbox::class,
                'options' => [
                    'label' => 'Value 1',
                    'use_hidden_element' => true,
                    'checked_value' => 'yes',
                    'unchecked_value' => 'no',
                ],
                'attributes' => [
                     'value' => 'no',
                ],
            ]);
            // Creates others as your needs
        }
    }
    

    现在我们将使用Zend\From\Form 附加从Zend\From\Fieldset 创建的字段集来创建表单。

    module/Application/src/Form/YourForm.php

    <?php 
    namespace Application\Form;
    
    use Application\Form\Fieldset\YourFieldset;
    use Zend\Form\Form;
    
    class YourForm extends Form
    {
    
        public function __construct($name = null)
        {
            parent::__construct('your-form');
    
            $this->add([
                // This name will be used to fetch each checkbox from 
                // the CheckboxFieldset::class in the view template.
                'name' => 'fieldsets',
                'type' => YourFieldset::class
            ]);
    
            $this->add([
                'name' => 'submit',
                'attributes' => [
                    'type'  => 'submit',
                    'value' => 'Get Values',
                    'class' => 'btn btn-primary'
                ],
            ]);
        }
    }
    

    我们的 from 几乎准备好了。如果我们希望它在控制器的任何操作中使用,我们需要使其可服务。所以让我们这样做吧。

    更新您的模块配置文件。如果service_manager键不存在则添加如下sn-p代码,否则只更新factoriesaliases键如下。

    修复模块配置文件中的命名空间

    模块/Application/config/module.config.php

    'service_manager' => [
        'factories' => [
            // Form service
            Form\YourForm::class => Zend\ServiceManager\Factory\InvokableFactory::class,
    
            // Other services
        ],
        'aliases' => [
            // Make an alias for the form service
            'YourForm' => Form\YourForm::class,          
        ],
    ],
    

    现在表格可以使用了。这需要注入到我们的控制器中。当我在处理Application 模块时,我会将表单注入IndexController::class 的构造函数中。然后我们将在 IndexController::fieldsetAction() 方法中使用该表单。

    module/Application/src/Controller/IndexController.php

    <?php
    namespace Application\Controller;
    
    use Zend\Form\FormInterface;
    use Zend\Mvc\Controller\AbstractActionController;
    use Zend\View\Model\ViewModel;
    
    class IndexController extends AbstractActionController
    {
        protected $YourForm;
    
        public function __construct(FormInterface $YourForm) 
        {
            $this->YourForm = $YourForm;
        }
    
        public function fieldsetAction()
        {
            $request   = $this->getRequest();
            $viewModel = new ViewModel(['form' => $this->YourForm]);
    
            if (! $request->isPost()) {
                return $viewModel;
            }
    
            $this->YourForm->setData($request->getPost());
    
            if (! $this->YourForm->isValid()) {
                return $viewModel;
            }
    
            $data = $this->YourForm->getData()['fieldsets'];
    
            echo '<pre>';
            print_r($data);
            echo '</pre>';
    
            return $viewModel;
        }    
    }
    

    由于这个控制器在其构造函数中接受参数,我们需要为这个控制器创建一个工厂(工厂创建其他对象)。

    模块/Application/src/Factory/Controller/IndexControllerFactory.php

    <?php
    namespace Application\Factory\Controller;
    
    use Application\Controller\IndexController;
    use Interop\Container\ContainerInterface;
    use Zend\ServiceManager\Factory\FactoryInterface;
    
    class IndexControllerFactory implements FactoryInterface
    {
        public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
        {   
            // We get form service via service manager here
            // and then inject controller's constructor 
            $YourForm = $container->get('YourForm');
            return new IndexController($YourForm);
        }    
    }
    

    再一次,我们需要更新模块配置文件。这次我们将在controllers键下添加工厂如下

    'controllers' => [
        'factories' => [
            Controller\IndexController::class => Factory\Controller\IndexControllerFactory::class,
        ],
    ],
    

    最后,在视图模板中回显表单如下:

    module/Application/view/application/index/fieldset.phtml

    <h1>Checkbox Form</h1>
    
    <?php
    $form = $this->form;
    $form->setAttribute('action', $this->url());
    
    // Here is the catch, remember this name from the CheckboxForm::class
    $fieldset = $form->get('fieldsets');
    
    $name_1 = $fieldset->get('name_1');
    
    $name_2 = $fieldset->get('name_2');
    
    $name_3 = $fieldset->get('name_3');
    
    $submit = $form->get('submit');
    $submit->setAttribute('class', 'btn btn-primary');
    
    $form->prepare();
    
    echo $this->form()->openTag($form);
    ?>
    
    <fieldset>
        <legend>My legend value</legend>
        <?= $this->formElement($name_1) ?>
        <?= $this->formLabel($name_1) ?>
    
        <?= $this->formElement($name_2) ?>
        <?= $this->formLabel($name_2) ?>
    
        <?= $this->formElement($name_3) ?>
        <?= $this->formLabel($name_3) ?>
    
        <?= $this->formSubmit($submit) ?>
    </fieldset>
    
    <?php
    echo $this->form()->closeTag();
    

    希望对您有所帮助!

    【讨论】:

    • 非常感谢您的详细回复。这正是我一直在寻找的。奇迹般有效。 :)
    • 这是一个很酷的迷你教程。但是有一个问题:如果您习惯让普通的 ServiceManager 处理您的表单,那么当您开始做一些更花哨的事情时,您可能会被咬伤,例如。自定义元素。作为最佳实践,您应该让 FormElementManager 处理它们。请参阅docs.zendframework.com/zend-form/advanced/… 并在之后搜索“第二个捕获”和“处理依赖项”部分。
    猜你喜欢
    • 2017-01-08
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多