简体   繁体   中英

Symfony Forms - How to Change a CollectionTypes Items labels

This is my first question on stackoverflow; until now I just looked for answers for my issues and found them. But now it seems that I have one that nobody or at least no one here stumbled across.

About my problem:

In my Class FieldType extends AbstractType I want to change the labels of CollectionType items.

This works for all contained items, but I want to set the labels individually:

$translations = $builder->create("translations", CollectionType::class, array(
            "label" => "Translations",
            "type" => TranslationType::class,
            "entry_options" => array(
                'label' => "THIS IS A TEST"
            )
        ));

Here I add new types to the CollectionType and try to set each item's label:

foreach ($this->field->getTranslations() as $translation) {
            /** @var Language $language */
            $iso2 = strtolower($translation->getLanguage()->getIso2());
            $translation = $builder->create("translation_{$iso2}", TranslationType::class, array(
                'label' => $iso2,
                )
            );
            $translations->add($translation);
        }
$builder->add($translations);

But they are not displayed in the template; I suppose that here the indices of the Collection are shown (0,1,...) . (see Rendered Translations FormView )

This is my TranslationType :

class TranslationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add("label");
        $builder->add("placeholder");
    }

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

I got here by searching for exactly the same question.

The 0,1,... probably are the keys of ArrayCollection of your entity. But that doesn't help.

The methods below are not pretty, but they should work. I'll be watching this thread for better suggestions...

Method 1

In your FormType class, add:

use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;

...


/** 
 * this gets called in the final stage before rendering the form
 */   
public function finishView(FormView $view, FormInterface $form, array $options)
{
    foreach ($view['translations']->children as $childView)
    {
        // here you have access to all child form vars, assigned entities, etc
        $childView->vars['label'] = ''; // set label here
    }
}

Method 2:

Just customize the template, as per http://symfony.com/doc/current/cookbook/form/form_customization.html

Instead of {{ form_label() }} , use something else :)

As I said, it is not pretty, but hope it helps.

Thanks for the answer @Karolis. Just in case this might be interesting for someone else. I was also facing this issue trying to customize the label of individual collection items, and I was trying for a while to do it through twig like so:

{% for key, child in successStoryForm.content.children %}
                <div id="successStory_content">
                    <div class="form-group">
                        <div id="{{ child.vars.id }}">
                            <div class="form-group">
                                <label class="control-label required" for="{{ child.vars.id }}_text">{{ contentHeaders[key] }}</label>
                                <textarea id="{{ child.vars.id }}_text" name="{{ child.vars.full_name }}[text]" required="required" class="form-control" placeholder="<p>Dein Text</p>"><p>Dein Text_2</textarea>

                                <span class="help-block">
                                    <ul class="list-unstyled">
                                        <li>
                                            <span class="glyphicon glyphicon-exclamation-sign"></span>
                                            {{ dump(child.vars.errors) }}
                                        </li>
                                    </ul>
                                </span>

                            </div>
                        </div>
                    </div>
                </div>
            {% endfor %}

This actually rendered the label correctly, however, I was not able to render the errors properly. They were always empty.

In my main formtype I add this collection using:

->add('content', CollectionType::class, [
            'entry_type'    => SuccessStoryContentType::class,
            'required'      => true,
            'entry_options' => [
                'label'     => false,
            ],
        ])

The SuccessStoryContentType is a simple form type with some validation (left out here)

$builder
        ->add('text', TextareaType::class);

To get this to work I had to dig a little deeper into the form views children like so:

 foreach ($view['content']->children as $key => $childView)
    {
        $childView->vars['form']->children['text']->vars['label'] = $label;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM