Search code examples
phpsymfonysymfony4custom-field-type

How to create custom form type in symfony 4?


I was trying to create a custom form type with it's own template view via Symfony 4 Documentation but I got a lot of errors by searching and trying to create one.

Here is my custom form type file ImageChoiceType.php:

<?php

namespace App\Form\Type;

use App\Entity\Media;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ImageChoiceType extends AbstractType
{

    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }


    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
//            'data_class' => Media::class,
            'class' => Media::class,
            'choices' => $this->entityManager->getRepository(Media::class)
                            ->findAll(),
        ));
    }

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

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'image_choice';
    }

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

Here is my field template:

{% block image_choice_widget %}
    <div class="image_widget">
        <div class="radio">
            <label for="post_image_placeholder" class="">
                <input type="radio" id="post_image_placeholder" name="post[image]" value=""
                        {{ form.vars.value == "" ? "checked='checked'" : ""}}> None
            </label>
        </div>
        <div class="image-container">
            {% for key,choice in form.vars.choices %}
                <div class="radio col-xs-2">
                    <label for="post_image_{{ key }}" class="">
                        <input class="image-radio-buttons" type="radio" id="post_image_{{ key }}" name="post[image]"
                               value="{{ key }}" {{ form.vars.value == key ? "checked='checked'" : ""}}>
                        <img src="{{ asset(constant('App\\Constants::UPLOAD_MEDIA')~choice.label) }}" class="image-thumbs img-responsive"/>
                    </label>
                </div>
            {% endfor %}
            <div class="clearfix"></div>
        </div>
    </div>
{% endblock %}

The interesting part is if I override one of the built-in types of Symfony via this template by changing the first line to {% block entity_widget %} and use EntityType in my form builder, it works well. But as I started to populate this with my own custom type, It got angry and showed a lot of unrelated errors!

Any help or instruction?


Solution

  • OK, I found out how to create it!
    That was so easy. The documentation showed that it's so complex, but actually it's not.

    This is the custom form type file ImageChoiceType.php:

    <?php
    
    namespace App\Form\Type;
    
    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class ImageChoiceType extends AbstractType
    {
        public function configureOptions(OptionsResolver $resolver)
        {
        }
    
        public function getParent()
        {
            return EntityType::class;
        }
    
        /**
         * {@inheritdoc}
         */
        public function getName()
        {
            return 'image_choice';
        }
    
        /**
         * {@inheritdoc}
         */
        public function getBlockPrefix()
        {
            return 'image_choice';
        }
    }
    

    This is how I use this field in my form builder:

    ...
      ->add('image',ImageChoiceType::class , [
           'label' => 'Choose an Image',
           'class' => Media::class
      ])
    ...
    

    and the template that I've provided in the question is exactly what generates the pictures!