symfony 3: how to get the updated data in addEventSubscriber of form type?

172 Views Asked by At

Symfony version: 3.4

i have a root form is layout form that is including a collection type is named blocks. The content form is belonged to blocks form. I want to use ajax to making user change the value of selector 1 and then the form type 2 is been changed other form type.

The updated selected value can be picked in $request->request in controller.

but I can not get the new data of selector 1 that always is the old data.

LayoutType.php

class LayoutType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'attr' => array(
                'class' => 'form-control'
            ),
            'label' => 'name'
        ));

        $builder->add('blocks', CollectionType::class, array(
            'entry_type' => BlockType::class,
            'entry_options' => array('label' => false),
            'allow_add' => true,
            'allow_delete' => true,
            'required' => false,
            'label' => false
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => '****\Bundle\****Bundle\Entity\Layout'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'layout_form';
    }
}

BlockType.php

class BlockType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'attr' => array(
                'class' => 'form-control layout-block-name'
            ),
            'label' => '名称'
        ));
        $builder->add('contents', CollectionType::class, array(
            'entry_type' => BlockContentType::class,
            'entry_options' => array('label' => false),
            'allow_add' => true,
            'allow_delete' => true,
            'required' => false,
            'label' => false
        ));
    }/**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => '****\Bundle\****Bundle\Entity\LayoutBlock'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'layout_block_form';
    }
}

BlockContentType.php

class BlockContentType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $factory = $builder->getFormFactory();
        $builder->addEventSubscriber(new BlockContentValueFieldSubscriber($factory));
        $builder->add('unit', TextType::class, array(
            'attr' => array(
                'class' => 'form-control block-content-unit',
                'placeholder' => '默认单位'
            ),
            'required' => false,
            'label' => '默认单位'
        ));
        $builder->add('option', EntityType::class, array(
            'class' => '*******Bundle:FormFieldOption',
            'choice_label' => 'name',
            'attr' => array(
                'class' => 'form-control'
            ),
            'label' => '表单选项'
        ));
        $builder->add('type', ChoiceType::class, array(
            'attr' => array(
                'class' => 'form-control select-block-content-form-type'
            ),
            'choices' => array(
                '文本'   => 'textarea',
                '下拉菜单'   => 'select',
                '图片'      => 'image'
            ),
            'preferred_choices' => array('textarea'),
            'label' => 'Form TYpe'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => '****\Bundle\****Bundle\Entity\LayoutBlockContent'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'block_content_form';
    }
}

BlockContentValueFieldSubscriber.php

class BlockContentValueFieldSubscriber implements EventSubscriberInterface
{
    protected $factory;
    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_SET_DATA => 'preSetData',
        );
    }

    public function preSetData(FormEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();
        if (!($data instanceof LayoutBlockContent) || !$data->getBlock()) {
            $form->add('value', TextareaType::class, array(
                'attr' => array(
                    'class' => 'form-control block-content-input-value form-textarea-type'
                )
            ));
        } else {
            $type = $data->getType();
            // $type always is old data not the ajax data
            switch ($type)
            {
                case 'image':
                    $form->add('value', FileType::class, array(
                        'data_class' => null,
                        'attr' => array(
                            'class' => 'form-control block-content-input-value form-image-type'
                        )
                    ));
                    break;
                default:
                    $form->add('value', TextareaType::class, array(
                        'attr' => array(
                            'class' => 'form-control block-content-input-value form-textarea-type'
                        )
                    ));
                    break;
            }
        }
    }
}

enter image description here

enter image description here

0

There are 0 best solutions below