Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 Entity type form with name and image

Tags:

symfony

I have an entity with both a name (string) and a file (also a string representing the filename). This is the "Icon" entity. I have another entity called "Category" which has a name (string) and a relation to an Icon (OneToMany). I want the form to allow a user to select an Icon for a Category.

So I could display it in the form as:

$builder->add('icon', 'entity', array(
    'class' => 'CroltsMainBundle:Icon',
    'expanded' => true,
    'multiple' => false
));

But what I really want is to display something like this in twig for each radio button:

<div>
<label for="something"><img src="/icons/{{icon.file }}" />{{icon.name}}</label>
<input type="radio" name="something" value="{{ icon.id }}" />
</div>

Is there a good way to make that type of radio form with Symfony forms? Like would a custom Type be what I want? I really haven't done too much with custom types to know how much of this is possible.

like image 649
Matt Avatar asked Dec 21 '22 19:12

Matt


1 Answers

Not sure it is the best way but here is how I manage this kind of situation :

  1. create a new formtype that behalf as entityType, IconCheckType for instance: (http://symfony.com/doc/master/cookbook/form/create_custom_field_type.html)

    namespace .....\Form\Type;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilder;
    use Symfony\Component\Form\FormView;
    use Symfony\Component\Form\FormInterface;
    
    
    class IconCheckType extends AbstractType
    {
       /**
         * {@inheritdoc}
         */
      public function buildForm(FormBuilder $builder, array $options) {
    
        $builder -> setAttribute('dataType', $options['dataType']);
      }
    
       /**
         * {@inheritdoc}
         */
      public function buildView(FormView $view, FormInterface $form) {
        $view -> set('dataType', $form -> getAttribute('dataType'));
      }
    
       /**
         * {@inheritdoc}
         */
      public function getDefaultOptions(array $options) {
        return array('required' => false,'dataType'=>'entity');
      }
    
    
      /**
         * Returns the allowed option values for each option (if any).
         *
         * @param array $options
         *
         * @return array The allowed option values
         */
        public function getAllowedOptionValues(array $options)
        {
            return array('required' => array(false));
        }
    
       /**
         * {@inheritdoc}
         */
      public function getParent(array $options) {
        return 'entity';
      }
    
       /**
         * {@inheritdoc}
         */
      public function getName() {
        return 'iconcheck';
      }
    
    }
    
  2. in your Form

    ...
    ->add('icon', 'iconcheck', array(
            'class' => 'CroltsMainBundle:Icon',
            'property'=>'formField',
            'multiple'=>false,
            'expanded'=>true
          ))
    ...
    

    Note the property=>'formField', that means that instead of return the __toString as label it will return whatever you want from the function getFormField from your entity class

  3. So, in your entity class:

    class Icon {
    
    ....
        public function getFormField() {  
           return $this;   /* or an array with only the needed attributes */ 
        }
    
    ....
    }
    
  4. then you can render your custom field

    {% block iconcheck_widget %}
       {% for child in form %}
          {% set obj=child.vars.label %}
            <div>
                <label for="something"><img src="/icons/{{obj.file }}" />{{obj.name}}</label>
                {{ form_widget(child) }} {# the radio/checkbox #}
              </div>
          {{ form_widget(child) }}#}
        {% endfor %}
    
    
    {% endblock %}
    
like image 167
Eric Grivilers Avatar answered Dec 26 '22 15:12

Eric Grivilers