wemxo / dynamic-form-bundle

一个有用的symfony插件,允许根据给定的配置创建动态表单类型。

安装: 60

依赖者: 0

建议者: 0

安全性: 0

星星: 10

关注者: 2

分支: 0

开放问题: 0

类型:symfony-bundle

v1.0.2 2024-04-02 04:07 UTC

This package is auto-updated.

Last update: 2024-10-02 05:30:16 UTC


README

GitHub build img GitHub all releases

动态表单插件允许您根据给定的配置动态创建表单。

需求/依赖

  • PHP 7.4 或更高版本
  • symfony/framework-bundle 5.0 或更高版本
  • symfony/form 5.0 或更高版本
  • symfony/finder 5.0 或更高版本

使用方法

安装

安装最新版本

composer require wemxo/dynamic-form-bundle

激活

config/bundle.php 中启用插件

<?php

return [
    /* ... */
    Wemxo\DynamicFormBundle\DynamicFormBundle::class => ['all' => true],
    /* ... */
];

配置

添加插件配置

# config/packages/dynamic_form.yaml

dynamic_form:
    recursive: true # Browse config folders recursively
    config_paths: # Files configuration paths
        - '%kernel.project_dir%/config/dynamic_form'
when@prod:
    framework:
        cache:
            pools:
                dynamic_form_pool_cache:
                    adapter: cache.adapter.redis
    dynamic_form:
        cache_pool: dynamic_form_pool_cache # Use cache 'dynamic_form_pool_cache' to store parsed configuration (recommended in production)

表单配置示例

YAML 格式

# config/dynamic_form/address.yaml
france:
    form:
        subscribers: ~
        fields:
            address: &address
                type: &textType Symfony\Component\Form\Extension\Core\Type\TextType
                options:
                    label: Address
                    required: true
                    attr:
                        placeholder: Enter your address
                constraints:
                    - class: &notBlank Symfony\Component\Validator\Constraints\NotBlank
                      options:
                          message: You must enter your address
            addressComplement: &addressComplement
                type: *textType
                options:
                    label: Address complement
                    required: false
                    attr:
                        placeholder: Enter your address complement
                constraints: ~
            postalCode: &postalCode
                type: *textType
                options:
                    label: Postal code
                    required: true
                    attr:
                        placeholder: Enter your postal code
                constraints:
                    - class: *notBlank
                      options:
                          message: You must enter your postal code
italy:
    form:
        subscribers: ~
        fields:
            address: *address
            addressComplement: *addressComplement
            postalCode: *postalCode
            department: &department
                type: *textType
                options:
                    label: Department
                    required: true
                    attr:
                        placeholder: Enter your department
                constraints:
                    - class: *notBlank
                      options:
                          message: You must enter your department
morocco:
    form:
        subscribers: ~
        fields:
            address: *address
            postalCode: *postalCode
            city:
                type: *textType
                options:
                    label: City
                    required: true
                    attr:
                        placeholder: Enter your city
                constraints:
                    - class: *notBlank
                      options:
                          message: You must enter your city

PHP 格式

<?php

return [
    'france' => [
        'form' => [
            'subscribers' => NULL,
            'fields' => [
                'address' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Address',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your address',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your address',
                            ],
                        ],
                    ],
                ],
                'addressComplement' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Address complement',
                        'required' => false,
                        'attr' => [
                            'placeholder' => 'Enter your address complement',
                        ],
                    ],
                    'constraints' => NULL,
                ],
                'postalCode' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Postal code',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your postal code',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your postal code',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
    'italy' => [
        'form' => [
            'subscribers' => NULL,
            'fields' => [
                'address' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Address',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your address',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your address',
                            ],
                        ],
                    ],
                ],
                'addressComplement' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Address complement',
                        'required' => false,
                        'attr' => [
                            'placeholder' => 'Enter your address complement',
                        ],
                    ],
                    'constraints' => NULL,
                ],
                'postalCode' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Postal code',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your postal code',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your postal code',
                            ],
                        ],
                    ],
                ],
                'department' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Department',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your department',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your department',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
    'morocco' => [
        'form' => [
            'subscribers' => NULL,
            'fields' => [
                'address' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Address',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your address',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your address',
                            ],
                        ],
                    ],
                ],
                'postalCode' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'Postal code',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your postal code',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your postal code',
                            ],
                        ],
                    ],
                ],
                'city' => [
                    'type' => 'Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType',
                    'options' => [
                        'label' => 'City',
                        'required' => true,
                        'attr' => [
                            'placeholder' => 'Enter your city',
                        ],
                    ],
                    'constraints' => [
                        0 => [
                            'class' => 'Symfony\\Component\\Validator\\Constraints\\NotBlank',
                            'options' => [
                                'message' => 'You must enter your city',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
];

创建表单

<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Wemxo\DynamicFormBundle\Form\DynamicType;
use Wemxo\DynamicFormBundle\Utils\Helper\DynamicFormHelper;

class AppController extends AbstractController
{
    #[Route(name: 'app_home')]
    public function home(FormFactoryInterface $formFactory): Response
    {
        $user = $this->getUser();
        $countryLabel = $user->getCountry()->getLabel();
        $form = $formFactory->create(DynamicType::class, null, [
            'dynamic_key' => DynamicFormHelper::configKey('address', $countryLabel),
        ]);

        return $this->render('app/home.html.twig', [
            'form' => $form->createView()
        ]);
    }
}

带有块前缀的表单创建

<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Wemxo\DynamicFormBundle\Form\DynamicType;
use Wemxo\DynamicFormBundle\Utils\Helper\DynamicFormHelper;

class AppController extends AbstractController
{
    #[Route(name: 'app_home')]
    public function home(FormFactoryInterface $formFactory): Response
    {
        $user = $this->getUser();
        $countryLabel = $user->getCountry()->getLabel();
        $form = $formFactory->createNamed('my_custom_prefix', DynamicType::class, null, [
            'dynamic_key' => DynamicFormHelper::configKey('address', $countryLabel),
        ]);

        return $this->render('app/home.html.twig', [
            'form' => $form->createView()
        ]);
    }
}

使用表单事件订阅者

1 - 通过实现接口 Wemxo\DynamicFormBundle\EventSubscriber\DynamicFormEventSubscriber 创建一个类。

1.1 - 实现 getName 函数。

1.2 - 实现 getSubscribedEvents 函数。

<?php

declare(strict_types=1);

namespace App\Form;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Wemxo\DynamicFormBundle\EventSubscriber\DynamicFormEventSubscriber;

class AddressFormEventSubscriber implements DynamicFormEventSubscriber
{

    public function getName(): string
    {
        return 'address_event_subscriber';
    }

    public static function getSubscribedEvents(): array
    {
        return [
            FormEvents::PRE_SET_DATA => 'onPreSetData',
        ];
    }
    
    public function onPreSetData(FormEvent $event): void
    {
        // do something.
    }
}

1.3 - 更新表单配置

france:
    form:
        subscribers:
            - address_event_subscriber # The value returned from the getName function.
        fields: []