2
votes

I would like to override a specific element of my Symfony form, while allowing my standard template to generate the rest of the fields. So far it has been a case of either/or.

First my template generates the form element

<form action="" method="post" {{ form_enctype(form) }} autocomplete="off">
    {% form_theme form 'SuperSecretProjectBundle:Default:collection.html.twig' %}
    {{ form_widget(form) }}

    <input type="submit" class="right submit button primary small" value="Save" />
</form>

Inside collection.html.twig I have the following blocks: form_row is the generic widget renderer, while image_sets_row is my specific row I want to override.

{% block form_row %}
    <div class="row">
        <div class="large-12 columns{% if not form.vars.valid %}error{% endif %}">
            {{ form_label(form) }}
            {{ form_widget(form) }}
            <small>{{ form_errors(form) }}</small>
        </div>
    </div>
{% endblock form_row %}

{% block image_sets_row %}
    <div id="image_sets">
        <div class="row">
            <div class="columns large-12">
                <a href="#" id="add-image-set" class="button medium secondary right">Add image set</a>
            </div>
        </div>
    </div>
{% endblock %}

This results in using form_row for all fields, without my modified block. How can I have Symfony output the elements that are not being specifically overridden and include my new blocks as well?

1

1 Answers

0
votes

What you need is a custom field type for the field you are trying to use your custom widget for.

As shown in the link, first you need to create a custom Field Type class like so

// src/AppBundle/Form/Type/ImageSetsType.php
namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; #should change to whatever parent type you need

class ImageSetsType extends AbstractType{
    public function configureOptions(OptionsResolver $resolver){
        $resolver->setDefaults( array() ); #set any option defaults you need here
    }

    public function getParent(){
        return ChoiceType::class; #again change this to whatever parent type you need
    }
}

Next we get your template for that block working properly

{# app/Resources/views/form/fields.html.twig #}

{% block imagesets_widget %}
    <div id="image_sets">
        <div class="row">
            <div class="columns large-12">
                {{ form_label(form) }}
                {{ form_widget(child) }}
                <a href="#" id="add-image-set" class="button medium secondary right">Add image set</a>
                <small>{{ form_errors(form) }}</small>
            </div>
        </div>
    </div>
{% endblock %}

Then you use your newly created type in your form as you would any other.

As I assume you want a little more in