Symfony 4 / Sonata: form types

Here is a list of common form types used in admin interfaces.

Date Time Picker

Add the template in the config/packages/twig.yaml file

twig:
    form_themes:
        - '@SonataCore/Form/datepicker.html.twig'

And in the controller:

            $formMapper->with('Date d\'activation', ['class' => 'col-md-4 abcdaire'])
                ->add('activation_debut', DatePickerType::class, ['required' => false,  'label'=>'Activation début','attr' => ['placeholder' => '']])
                ->add('activation_fin', DatePickerType::class, ['required' => false,  'label'=>'Activation fin','attr' => ['placeholder' => '']])
            ->end();
Sélection_071

HTML Area

You need to install the formatter bundle:
https://sonata-project.org/bundles/formatter/3-x/doc/reference/installation.html

Add a configuration in the composer.json

    "replace": {
        "egeloen/ckeditor-bundle": "*"
    },

Create the configuration file /config/sonata_formatter.yml with the following content:

sonata_formatter:
    default_formatter: richhtml
    formatters:
        markdown:
            service: sonata.formatter.text.markdown
            extensions:
                - sonata.formatter.twig.control_flow
                - sonata.formatter.twig.gist
        #        - sonata.media.formatter.twig #keep this commented unless you are using media bundle.


        text:
            service: sonata.formatter.text.text
            extensions:
                - sonata.formatter.twig.control_flow
                - sonata.formatter.twig.gist
        #        - sonata.media.formatter.twig


        rawhtml:
            service: sonata.formatter.text.raw
            extensions:
                - sonata.formatter.twig.control_flow
                - sonata.formatter.twig.gist
        #        - sonata.media.formatter.twig


        richhtml:
            service: sonata.formatter.text.raw
            extensions:
                - sonata.formatter.twig.control_flow
                - sonata.formatter.twig.gist
        #        - sonata.media.formatter.twig


        twig:
            service: sonata.formatter.text.twigengine
            extensions: [] # Twig formatter cannot have extensions
            
    ckeditor:
        templates:
            browser: 'CaueEdpBundle:Ckeditor:browser.html.twig'
            upload: 'CaueEdpBundle:Ckeditor:upload.html.twig'
            
            
fos_ck_editor:
    default_config: default
    configs:
        default:
            # default toolbar plus Format button
            toolbar:
            - [Bold, Italic, Underline, -, 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ,-, Cut, Copy, Paste, PasteText, PasteFromWord, -, Undo, Redo, -, NumberedList, BulletedList, -, Outdent, Indent, -,Blockquote, -, Image, Link, Unlink, Table]
            - [Format, Maximize, Source, Iframe]

               

In config/sonata_admin.yaml add the css and js

sonata_admin:
       [...]                      
    assets:
        extra_stylesheets:
            - bundles/sonataformatter/markitup/skins/sonata/style.css
            - bundles/sonataformatter/markitup/sets/markdown/style.css
            - bundles/sonataformatter/markitup/sets/html/style.css
            - bundles/sonataformatter/markitup/sets/textile/style.css
        extra_javascripts:
            - bundles/fosckeditor/ckeditor.js
            - bundles/sonataformatter/vendor/markitup-markitup/markitup/jquery.markitup.js
            - bundles/sonataformatter/markitup/sets/markdown/set.js
            - bundles/sonataformatter/markitup/sets/html/set.js
            - bundles/sonataformatter/markitup/sets/textile/set.js

In config/twig.yaml

twig:
[..]
    form_themes:
        - '@SonataFormatter/Form/formatter.html.twig'

Run the commands:

composer require sonata-project/formatter-bundle
composer dump-autoload
php bin/console assets:install public
php bin/console ckeditor:install

And in your controller:

use Sonata\FormatterBundle\Form\Type\SimpleFormatterType;

                $formMapper->add('introduction', SimpleFormatterType::class, [
                    'format' => 'richhtml',
                    'ckeditor_context' => 'default',
                    'required' => false,  'label'=>'Introduction','attr' => ['placeholder' => '']]);

Sélection_072

Checkbox (Boolean)

The field needs to be configured as boolean in the entity

    /**
     * @var int
     *
     * @ORM\Column(name="actif", type="boolean", nullable=false)
     */
    private $actif = '0';

    public function getActif(): ?bool
    {
        return $this->actif;
    }

    public function setActif(bool $actif): self
    {
        $this->actif = $actif;

        return $this;
    }

And use the following configuration for the form

use Symfony\Component\Form\Extension\Core\Type\CheckboxType;

$formMapper->with('Status', ['class' => 'col-md-4 abcdaire'])
     ->add('actif', CheckboxType::class, ['required' => false])
>end();

And to display an on/off button in the list

protected function configureListFields(ListMapper $listMapper)
{
		$listMapper->add('actif', null, ['editable' => true])
}
Sélection_075
Sélection_077
Et pour finir les filtres
$datagridMapper->add('actif', null, ['label'=>'PRIX'])

Listbox

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

->add('etape', ChoiceType::class, [
                        'choices' => array(
                            'coordonnees' => 'coordonnees',
                            'declaration' => 'declaration',
                        ),
                        'placeholder' => 'Selection du champs',
                        'required' => false,
                        'label' => 'Destination du champs'
                    ])
Sélection_079

It should be noted that lists include an automatic search field beyond 25 items.
It is not possible to remove it, except by overriding the initialization function.
To do this, we will add a js file to our admin in sonata_admin.yml

sonata_admin:
    assets:
        extra_javascripts:
            - js/admin.js

We will add a function identical to the original initialization of the select2 library in Sonata but with different settings.
Instead of minimumResultsForSearch: 25 we will set it to 100000, so that the search will not trigger for our lists of less than 100k (basically, all our lists).
And in our list initialization, we will add a css class to target it.

jQuery(document).ready(function() {
jQuery('select.select2-search-hidden, .select2-search-hidden select').each(function() {
        var select            = jQuery(this);
        var allowClearEnabled = false;
        var popover           = select.data('popover');

        select.removeClass('form-control');

        if (select.find('option[value=""]').length || select.attr('data-sonata-select2-allow-clear')==='true') {
            allowClearEnabled = true;
        } else if (select.attr('data-sonata-select2-allow-clear')==='false') {
            allowClearEnabled = false;
        }

        select.select2({
            width: function(){
                // Select2 v3 and v4 BC. If window.Select2 is defined, then the v3 is installed.
                // NEXT_MAJOR: Remove Select2 v3 support.
                return Admin.get_select2_width(window.Select2 ? this.element : select);
            },
            dropdownAutoWidth: true,
            minimumResultsForSearch: 100000,
            allowClear: allowClearEnabled
        });

        if (undefined !== popover) {
            select
                .select2('container')
                .popover(popover.options)
            ;
        }
    });

});

And our field with the class "select2-search-hidden":

->add('numberStudent', ChoiceType::class, [
                         'label' => 'Nombre maximum d\'élèves par classe',
                         'choices' => array_combine(range(5,50), range(5,50)),
                         'placeholder' => '',
                         'attr' => ['class' => 'select2-search-hidden']
                     ])