Zend Framework 3 Form Fieldset

ぐ巨炮叔叔 提交于 2020-01-05 09:09:20

问题


Hy, I'm really new to Zend-Framework 3 and I'm practicing OOP, I can't find a simple explanation/tutorial on making a Zend Form with a fieldset and legend. Basically I'm trying to create this in 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>

I checked the official documentation about Zend Forms and Collections and Fieldsets, but it's really confusing me. Any help would be greatly appreciated.


回答1:


First, I am sorry as it is going to be a bit long one. But this would describe the form in action. So be patient please!

Assuming you are known to ZF3 default Application module. Some folders are created in the Application module for separation of each element. You need to create them as follows.

Let's get started by creating your fieldsets first. Zend\Form\Fieldset component represents a reusable set of elements and is dependent on Zend\From\Form component. This means you need to attach this to 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
    }
}

Now we would create the form using Zend\From\Form attaching the fieldset created from 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'
            ],
        ]);
    }
}

Our from is almost ready. We need to make it serviceable if we want it to be used in any action of a controller. So let's do that.

Update your module config file. If service_manager key does not exist then add the following snippet of code, otherwise, update only factories and aliases key as the following.

Fix namespaces in module config file.

module/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,          
    ],
],

Now the form is ready to be used. This needs to be injected into our controller. As I am working on Application module, I would inject the form into the IndexController::class's constructor. Then we would be using that form inside IndexController::fieldsetAction() method.

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

As this controller is taking argument in its constructor, we need to create a factory for this controller (a factory creates other objects).

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

Once again, we need to update the module config file. We would add this time the factory under controllers key as follows

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

At the end, echo the form in the view template as follows:

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

Hope this would help you!




回答2:


Actually the example you are looking for is in "collections" part of zend form. Its not the exact one but kinda like.

Here you are a little example. I ignored namespaces and hope so there's no typo :)

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

And in view file;

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


来源:https://stackoverflow.com/questions/47149722/zend-framework-3-form-fieldset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!