-->

Customize form field rendering

2020-02-25 23:15发布

问题:

I would like to customize the rendering of a form field in the edit page from sonata admin bundle to include an applet that uses the text content of a field.

I know that I have to edit the configureFormFields function in the admin class, but I need to know 3 things:

  • What is the syntax to provide a field form template
  • Where to put the template file ( which directory )
  • What the template have to looks like.

回答1:

Found a solution

What i have done is:

  1. Created a field type, lets call it myfieldType in myCompany\myBundle\Form\Type\myfieldType.php

    namespace myCompany\myBundle\Form\Type;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilder;
    
    class myfieldType extends AbstractType
    {
    
        public function getParent()
        {
            return 'text';
        }
    
        public function getName()
        {
            return 'myfield';
        }
    }
    
  2. Registered the Type in app/config/services.yml

    myCompany.myBundle.form.type.myfield:
        class: myCompany\myBundle\Form\Type\myfieldType
        tags:
            - { name: form.type, alias: myfield }
    
  3. In my myentityAdmin class,

     protected function configureFormFields(FormMapper $formMapper)
     {
         $formMapper
         ->add('myfieldname', 'myfield')
         ...
     }
    

    and

    public function getFormTheme() {
        return array('myCompanymyBundle:Admin:myfield_edit.html.twig');
    }
    

    and the template :

    {# src/mycompany/myBundle/Resources/views/Form/myfield_edit.html.twig #}
    {% block myfield_widget %}
        {% spaceless %}
            {{ block('textarea_widget') }}
        {% endspaceless %}
    {% endblock %}
    

And now i can access the form field value by the twig variable "value" !

So easy... when you got it.



回答2:

user1254498's solution won't work unless the block name prefix matches the name of the form type. At least with the last version of sonata admin bundle (2.2.12). In this case:

{# src/mycompany/myBundle/Resources/views/Form/myfield_edit.html.twig #}
{% block myfield_widget %}
    {% spaceless %}
        {{ block('textarea_widget') }}
    {% endspaceless %}
{% endblock %}

And, regarding getFormTheme(), you shoud return also the parent theme, otherwise you may break the whole style...

public function getFormTheme()
{
    return array_merge(
            parent::getFormTheme(), array(
          'mycompanyBundle:Form:myfield_edit.html.twig')
    );        
}

Also, you can access the admin service in the twig template with the variable sonata_admin.admim.



回答3:

In your services.yml file you define the template for your edit Action:

app.admin.product:
    class: AppBundle\Admin\ProductAdmin
    arguments: [~, AppBundle\Entity\Product, AppBundle:Admin\Product]
    tags:
        - {name: sonata.admin, manager_type: orm, group: Products, label: Products}
    calls:
        - [ setTemplate, [edit, AppBundle:Product:edit.html.twig]]

In that template you can then override templates for fields in your form:

{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}

{% form_theme form.selectall 'AppBundle:Form:selectall.html.twig' %}
{% form_theme form.Country 'AppBundle:Form:country.html.twig' %}

Then my template looks like that:

{% block form_row %}
<div class="form-group">
{{ form_label(form) }}
{% set c = 0 %}
{% for i in form %}
    {% set c = c+1 %}
    {% if (c == 1) %}
        <div style="float: left; width: 20%;">
    {% endif%}
    {{ form_row(i) }}
    {% if ((c == 60) or (form|length == loop.index)) %}
        </div>
        {% set c = 0 %}
    {% endif%}
{% endfor %}
</div>
{% endblock form_row %}

In this case, my countries check boxes appear in column of 60 elements, not in one column with the whole list of elements.

Hope this is helpful to someone else.