Symfony 4 / Sonata : forms types

Voici une liste de forms types comums utilisés dans les interfaces d’admin.

Date time picker

Ajouter le template dans le fichier config/packages/twig.yaml

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

Et dans le 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

Il faut installer le bundle formatter :
https://sonata-project.org/bundles/formatter/3-x/doc/reference/installation.html

Ajouter une configuration dans le composer.json

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

Creer le fichier de configuration /config/sonata_formatter.yml avec le contenu suivant :

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]

               

Dans config/sonata_admin.yaml ajoutez les css et 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

Dans config/twig.yaml

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

Lancez les commandes :

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

Et dans votre 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)

Il faudra configurer le champs en boolean dans l’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;
    }

Et utiliser la configuration suivante pour le formulaire

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

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

Et pour afficher un bouton on/off dans la liste

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

Il est a noter que les listes comprennent un champs de recherche automatique au delà de 25 éléments.
Il n’est pas possible de le supprimer, sauf à surcharger la fonction d’initialisation.
Pour cela nous allons ajouter un fichier js à notre admin dans sonata_admin.yml

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

Nous allons ajouter une fonction à l’identique que l’original de l’initialisation de la librairie select2 dans Sonata mais avec un paramétrage différent.
Au lieux de minimumResultsForSearch: 25 on va le mettre à 100000, comme cela, la recherche se déclenchera pas pour nos listes de moins de 100k (en gros, toutes nos listes).
Et dans notre initialisation de liste, nous allons ajouter une classe css pour pointer dessus.

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)
            ;
        }
    });

});

Et notre champs avec la classe « 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']
                     ])