Symfony 3 dynamically add attributes to form fields based on translation messages

1k Views Asked by At

I want to implement custom helper messages (html data attribute) for every form element. Helper messages are defined in YAML lang file (messages.en.yml) and not all form elements have helper messages.

Problem is that I am not sure can it be done using Symfony FormType or Symfony Form events.

I was thinking to create Form event as a service and inject translator service and from there manipulate data and add helper classes but I didn't find any solid example how can it be done.

Other option I was thinking is to use Trait and inject translator service in trait and from there to start developing my code but it doesn't feel so right.

Can someone share their experience and clue how to resolve this particular problem?

Here is my setup

messages.en.yml

intro:
        created: Intro created!
        edited:  Intro has been edited successfully!
        deleted: Intro has been has been deleted!
        index:
            title: List of all intros
        new:
            title: New intro
        show:
            title: Details of intro
        edit:
            title: Edit intro
        form:
             title: Title
             content: Content
             isEnabled: Is active
        tooltip:
             title: Please enter title

My form type:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title', TextType::class, array(
                'label_format' => 'admin.intro.form.%name%',
                'attr' => [
                    'data-helper' => 'Please enter title'
                ]

            )
        )
        ->add('content', TextareaType::class, array(
                'label_format' => 'admin.intro.form.%name%',
                'required' => false,
                'attr' => [
                    'class' => 'mceEditor'
                ]
            )
        )
        ->add('isEnabled', CheckboxType::class, array(
                'label_format' => 'admin.intro.form.%name%',
                'required' => false,
            )
1

There are 1 best solutions below

4
On BEST ANSWER

You can do so by registering the form as a service and injecting the YAML configuration into the form.

config.yml

message_config:
    intro:
            created: Intro created!
            edited:  Intro has been edited successfully!
            deleted: Intro has been has been deleted!
            index:
                title: List of all intros
            new:
                title: New intro
            show:
                title: Details of intro
            edit:
                title: Edit intro
            form:
                 title: Title
                 content: Content
                 isEnabled: Is active
            tooltip:
                 title: Please enter title

services.yml

services:
app.form.type.my_form:
    class: AppBundle\Form\Type\MyForm
    arguments:
        - '%message_config%'
    tags:
        - { name: form.type }

Now you can work with the array in your FormType.

<?php

namespace AppBundle\Form\Type;

class MyForm
{
    protected $messages;

    public function __construct(array $messages)
    {
        $this->messages = $messages;
    }
}

If the YAML configuration is being used by a Translator service, you would inject the translator service instead.

Update: Symfony does this with the Translator component and Twig form themes see the below comment.