Задать вопрос
@ozornick

Как в Symfony 4 создавать кастомные формы с вложенными полями?

Вопрос вытекает из этого поста Нужно ли использовать Symfony forms? Похожая ситуация возникает. До создания объекта (то есть не редактирование сохраненной сущности) не найду как обработать форму. Есть объект User, у него зависимости вложенные.
$user = $this->getUser();
// Какое то значение
$client = $user->getClient()->getClientSomeData();
// Допустим теги, описания, которое являются ArrayCollection вообще тьма
$clientTags = $user->getClient()->getTags()->getTag()->getName();

С учетом отношений ManyToMany, OneToOne форму не знаю как реализовать. При сохранении ведь не генерируется связь.
Да же как у автора, нужно получить сначала User, у него взять client_id ключ связи, потом сам $user->getClient() и так далее. Знаю и использую property_path, но он не всегда срабатывает как надо, потому что где-то упускаю какую нибудь мелочь.
Также интересно как расширяете форму добавляя кастомное поле? Я сделал свой тип VehicleType, в нем автокомплит сущности. Я бы хотел дополнять везде этим типом выбор Vehicle, показывая текстовое поле. Но на выходе у меня появляется новая форма обрамленная fieldset > legend. Таким образом это не внутренне поле, а отдельный блок.
5df76c797a0fc512527215.png
  • Вопрос задан
  • 222 просмотра
Подписаться 1 Простой 11 комментариев
Решения вопроса 1
@ozornick Автор вопроса
Решение как часто бывает простое. Не создавать внутренние поля для своего типа
namespace App\Form\Type;

use ...

class UserSelectType extends AbstractType
{

    private $userRepository;

    public function __construct(UserRepository $repository)
    {
        $this->userRepository = $repository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Это фрагмент удаляем и вставляется обычное поле, а не форма
        $builder->add(
            'user',
            AutocompleteType::class,
            [
                'label' => false,
                'class' => User::class,
                'attr' => [
                    'placeholder' => 'Клиент',
                    'class' => 'user-autocomplete-property',
                ],
            ]
        );
       //dd($builder);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(
            [
                'label' => false,
                'class' => User::class,
                'attr' => [
                    'placeholder' => 'Клиент',
                    'class' => 'user-autocomplete-property',
                ],
            ]
        );
    }

    public function getParent()
    {
        return AutocompleteType::class;
    }
}


namespace App\Form;

use ...

class VehicleFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        /**
         * @var Vehicle $vehicle
         */
        $vehicle = $options['data'] ?? null;
        $isEdit = $vehicle && $vehicle->getId();

        $builder
            ->add(
                'user',
                UserSelectType::class,
                [
                    'empty_data' => new ClientData(),
                    'property_path' => 'clientData',
                ]
            )
            ->add(
                'brand',
                TextType::class,
                [
                    'attr' => [
                        'placeholder' => 'Бренд',
                    ],
                    'label' => false,
                ]
            )
            ->add(
                'button',
                SubmitType::class,
                [
                    'attr' => [
                        'class' => 'btn btn-primary',
                    ],
                    'label' => $isEdit ? 'Изменить' : 'Сохранить',
                ]
            )
            ->add(
                'resetButton',
                ResetType::class,
                [
                    'attr' => [
                        'class' => 'btn btn-secondary',
                    ],
                    'label' => 'Сбросить',
                ]
            );
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(
            [
                'data_class' => Vehicle::class,
            ]
        );
    }
}

Во первых добавил empty_data, теперь все резолвится и отношения подхватываются
Во вторых нашел почему новая с форма вставляется а не поле в текущую форму. Надо удалить фрагмент в билдере.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы