Я создал пользовательский тип поля класса BootstrapToggleType extends AbstractType
, который является дочерним по отношению к CheckboxType
Я также добавил его на всякий случай следующим образом
public function getBlockPrefix(): string
{
return 'bootstrap_toggle';
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$config = $form->getParent()->get($form->getName())->getConfig();
$options = $config->getOptions();
$defaultDataOptions = $this->_bootstrapToggleDataDefaults;
$form->getParent()->add($form->getName(), CheckboxType::class, array_replace_recursive($options, [
'attr' => $defaultDataOptions,
]))
;
});
}
Я добавил пользовательскую тему формы в twig.yaml form_themes: ['Form/custom_types.html.twig', 'bootstrap_4_layout.html.twig']
и создал упомянутый файл со следующим кодом
{% block bootstrap_toggle_row %}
{% for child in form.children if not child.rendered %}
<div class="my-custom-wrapper">
<div class="form-group">
{{ form_label(child) }}
{{ form_widget(child) }}
{{ form_help(child) }}
{{ form_errors(child) }}
</div>
</div>
{% endfor %}
{% endblock %}
Однако поле отображается с использованием стандартной темы игнорирования bootstrap_toggle_row
Что я делаю не так?
Проблема в основном с этой частью кода $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
. Однако мне нужно использовать такую конструкцию для создания поля, используя имя, предоставленное FormType
object $builder->add('is_published', BootstrapToggleType::class)
, если я изменю эту часть кода на что-то подобное
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addChild('testName', CheckboxType::class);
}
мой пользовательский шаблон отображается правильно.
добавлено
Поскольку я повторно добавил другого дочернего элемента, я должен предоставить его правильный префикс блока.
$form->getParent()->add($form->getName(), CheckboxType::class, array_replace_recursive($options, [
'attr' => $defaultDataOptions,
'block_prefix' => 'bootstrap_toggle'
]));
Затем в моем собственном шаблоне мне нужно ссылаться непосредственно на переменную form
как на один дочерний элемент, а не на массив. Поэтому вместо циклического перебора детей
{% for child in form.children if not child.rendered %}
просто прямой вызов
{{ form_label(form) }}
{{ form_widget(form) }}
{{ form_help(form) }}
{{ form_errors(form) }}
Теперь все работает.