Как установить требуемое состояние формы по умолчанию (и переопределить в компоновщике) в Symfony 3?

Я пытаюсь построить форму и состояние по умолчанию ‘required’ установлено в false,
а затем измените конфигурацию сборки формы, установив для некоторых значение true.

Если я не добавляю никакие параметры конфигурации, для полей по умолчанию устанавливается значение «обязательное» как «истина», и я могу переопределить их для определенных конфигураций.

Однако, если я добавлю:

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('required', false);
}

Я не могу переопределить это в конкретной конфигурации (это не делает обязательным true):

->add('name',TextType::class, array(
'required' => true,
'constraints' => array(new Length(array('min' => 3)))
))

Есть ли способ сделать это, или я должен всегда устанавливать не по умолчанию и указывать каждую конфигурацию?

2

Решение

Это возможно с PRE_SET_DATA Symfony форма события. По сути, вам нужно заново добавить все поля формы в это событие формы. Когда вы добавляете их в событие формы, они перезаписывают существующие поля формы с тем же именем. Вы хотите снова добавить поле со всей информацией, заменив массив параметров формы и вручную установив требуется возможность ложный. Посмотри:

class MyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(/* ... */)
->add(/* ... */)
;

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();

// loop through each form field
foreach ($form->all() as $field) {
$config  = $field->getConfig();
$options = $config->getOptions();

// re-add the form field and overwrite the 'required' option
// this overwrites the existing field
$form->add(
$field->getName(),
get_class($config->getType()->getInnerType()),
array_replace($options, ['required' => false])
);
}
});
}
}

Обратите внимание, что следующая строка:

get_class($config->getType()->getInnerType()),

вместо этого должно быть

$config->getType()->getName()

если вы используете версию Symfony ранее, чем Symfony 3.

В качестве фона, по замыслу FormConfigInterface Интерфейс не позволяет модификацию после того, как конфиг уже был установлен. Если вы загляните внутрь, он имеет только get а также has функции — так что ничего нельзя установить вручную. Это должно быть сделано при добавлении поля формы / формы.

Если вы хотите, чтобы это глобально для вашего проекта, вы могли бы сделать базовый тип формы, который включает эту функциональность в buildForm() событие, и тогда все ваши дочерние формы могут вызвать родителя после того, как они установили сами. Вы также можете сделать это для отдельных полей — вместо циклического

foreach ($form->all() as $field) {

Вы можете просто изменить определенное поле с

$config = $form->get('field_name');
$options = $config->getOptions();

$form->add(
'field_name',
get_class($config->getType()->getInnerType()),
array_replace($options, ['required' => false])
);
0

Другие решения

Это расширение формы (см. http://symfony.com/doc/master/form/create_form_type_extension.html) пусть по умолчанию все ваши поля все формы с required=false

// src/AppBundle/Form/Extension/RequiredDefaultsToFalseExtension.php
<?php

namespace AppBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RequiredDefaultsToFalseExtension extends AbstractTypeExtension
{

/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return FormType::class;
}

/**
*
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{

$resolver->setDefault('required', false);
}

}

Вы должны зарегистрировать свое расширение

# app/config/services.yml
services:
app.required_defaults_to_false_extension:
class: AppBundle\Form\Extension\RequiredDefaultsToFalseExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

и вы сделали, вам больше ничего не нужно делать.

Имея в виду, что required опция действует только в виде формы (http://symfony.com/doc/current/reference/forms/types/form.html#required) но имеет некоторое отражение с empty_data вариант (http://symfony.com/doc/current/reference/forms/types/form.html#empty-data) вы также можете использовать это расширение вместо предыдущий (возможно, вам придется настроить его под свои нужды)

// src/AppBundle/Form/Extension/RootFormRequiredDefaultsToFalseExtension.php
<?php

namespace AppBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RootFormRequiredDefaultsToFalseExtension extends AbstractTypeExtension
{

/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return FormType::class;
}

/**
*
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{

$resolver->setDefault('root_form_required_defaults_to_false', false);
}

public function buildView(FormView $view, FormInterface $form, array $options)
{
if ($form->getParent()) {
if ($form->getParent()->getConfig()->getOption('root_form_required_defaults_to_false')) {
$view->vars['required']=false;
}
}
}
}

Вы должны зарегистрировать свое расширение

# app/config/services.yml
services:
app.root_form_required_defaults_to_false_extension:
class: AppBundle\Form\Extension\RootFormRequiredDefaultsToFalseExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

и в типе формы, где вы хотите использовать это, вы должны включить его с

// src/AppBundle/Form/MyFormType.php
// ..
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
// ..
'root_form_required_defaults_to_false'=>true
));
}

В конце помните, что вы можете отключить проверку html5 для каждой формы с помощью этого атрибута, заданного в параметрах вашей корневой формы или в виде ветки. (http://symfony.com/doc/master/forms.html#form-validation)

// src/AppBundle/Form/MyFormType.php
// ..
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
// ..
'attr' => ['novalidate'=>'novalidate'],
));
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector