3. Form Types

The bundle comes with some handy form types.

3.1. DoctrineORMSerializationType

This form type reads JMSSerializer serialization class metadata and uses Doctrine ORM entity metadata to generate form fields and correct types.

All you have to do is to define a form type service for each entity for which you want to use a form type, like this:

<!-- config/services.xml -->

<service id="my.custom.form.type.comment" class="Sonata\Form\Type\DoctrineORMSerializationType">
    <argument type="service" id="jms_serializer.metadata_factory"/>
    <argument type="service" id="doctrine"/>
    <argument>my_custom_form_type_comment</argument>
    <argument>App\Entity\Comment</argument>
    <argument>a_serialization_group</argument>
    <tag name="form.type" alias="my_custom_form_type_comment"/>
</service>

The service definition should contain the following arguments:

  • The JMSSerializer metadata factory,

  • The Doctrine ORM entity manager,

  • The form type name,

  • The entity class name for which you want to build form,

  • The serialization group you want serialization fields have.

Warning

DoctrineORMSerializationType cannot be used directly with Symfony3.0, you need to extend the class BaseDoctrineORMSerializationType with an empty class to have a unique FQCN.

3.2. ImmutableArrayType

The Immutable Array allows you to edit an array property by defining a type per key.

The type has a keys parameter which contains the definition for each key. A definition is either a FormBuilder instance or an array with 3 options:

  • key name,

  • type: a type name or a FormType instance,

  • related type parameters: please refer to the related form documentation.

Let’s say a Page has options property with some fixed key-value pairs. Each value has a different type: integer, url, or string for instance:

// src/Entity/Page.php

class Page
{
    protected $options = [
        'ttl' => 1,
        'redirect' => '',
    [;

    public function setOptions(array $options)
    {
        $this->options = $options;
    }

    public function getOptions()
    {
        return $this->options;
    }
}

Now, the property can be edited by setting a type for each type:

// src/Admin/PageAdmin.php

use Sonata\Form\Type\ImmutableArrayType;

final class PageAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('options', ImmutableArrayType::class, [
                'keys' => [
                    ['ttl', 'text', ['required' => false]],
                    ['redirect', 'url', ['required' => true]],
                ]
            ]);
    }
}

3.3. BooleanType

The boolean type is a specialized ChoiceType, where the list of choices is locked to yes and no.

Note that for backward compatibility reasons, it will set your value to 1 for yes and to 2 for no. If you want to map to a boolean value, just set the option transform to true. For instance, you need to do so when mapping to a doctrine boolean.

3.4. TranslatableChoiceType

The translatable type is a specialized ChoiceType where the choices values are translated with the Symfony Translator component. The type has one extra parameter catalogue (the catalogue name to translate the value):

// src/Admin/DeliveryAdmin.php

use Sonata\Form\Type\TranslatableChoiceType;

final class DeliveryAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('deliveryStatus', TranslatableChoiceType::class, [
                'choices' => Delivery::getStatusList(),
                'catalogue' => 'SonataOrderBundle'
            ]);
    }
}
// src/Entity/Delivery.php

class Delivery
{
    public static function getStatusList()
    {
        return [
            self::STATUS_OPEN      => 'status_open',
            self::STATUS_PENDING   => 'status_pending',
            self::STATUS_VALIDATED => 'status_validated',
            self::STATUS_CANCELLED => 'status_cancelled',
            self::STATUS_ERROR     => 'status_error',
            self::STATUS_STOPPED   => 'status_stopped',
        ];
    }
}

Note

For more information, you can check the official ChoiceType documentation .

3.5. CollectionType

The Collection Type is meant to handle creation and editing of model collections. Rows can be added and deleted, and your model abstraction layer may allow you to edit fields inline. You can use type_options to pass values to the underlying forms:

// src/Entity/ProductAdmin.php

use Sonata\Form\Type\CollectionType;

final class ProductAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('sales', CollectionType::class, [

                // Prevents the "Delete" option from being displayed
                'type_options' => ['delete' => false]
            ], [
                'edit' => 'inline',
                'inline' => 'table',
                'sortable' => 'position',
            ]);
    }
}

The available options (which can be passed as a third parameter to FormMapper::add()) are:

btn_add and btn_catalogue:

The label on the add button can be customized with this parameters. Setting it to false will hide the corresponding button. You can also specify a custom translation catalogue for this label, which defaults to SonataAdminBundle.

type_options:

This array is passed to the underlying forms.

pre_bind_data_callback:

This closure will be executed during the preBind method (FormEvent::PRE_BIND | FormEvent::PRE_SUBMIT) to build the data given to the form based on the value retrieved. Use this if you need to generate your forms based on the submitted data.

Tip

A jQuery event is fired after a row has been added (sonata-admin-append-form-element). You can listen to this event to trigger custom javascript (eg: add a calendar widget to a newly added date field)

3.6. StatusType

The StatusType is not available as a service. However, you can use it to declare your own type to render a choice of status.

Let’s say, you have a Delivery::getStatusList method which returns a list of status. Now, you want to create a form type to expose those values:

// src/Entity/Delivery.php

class Delivery
{
    public static function getStatusList()
    {
        return [
            self::STATUS_OPEN      => 'status_open',
            self::STATUS_PENDING   => 'status_pending',
            self::STATUS_VALIDATED => 'status_validated',
            self::STATUS_CANCELLED => 'status_cancelled',
            self::STATUS_ERROR     => 'status_error',
            self::STATUS_STOPPED   => 'status_stopped',
        ];
    }
}

This can be done by declaring a new service:

<service id="sonata.order.form.status_type" class="Sonata\Form\Type\StatusType">
    <tag name="form.type"/>

    <argument>%sonata.order.order.class%</argument>
    <argument>getStatusList</argument>
    <argument>sonata_order_status</argument>
</service>

And the type can now be used:

// src/Admin/DeliveryAdmin.php

use App\Type\OrderStatusType;

final class DeliveryAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('deliveryStatus', OrderStatusType::class)
            // ...
        ;
    }
}

Warning

StatusType cannot be used directly with Symfony3.0, you need to extend the class BaseStatusType with an empty class to have a unique FQCN.

3.7. DatePickerType / DateTimePickerType

Those types integrate Eonasdan’s Bootstrap datetimepicker into a Symfony form. They both are available as services and inherit from date and datetime default form types.

Note

These form types require you to have bootstrap and jquery assets available in your project.

They will allow you to have a JS date picker onto your form fields as follows:

../../_images/datepicker.png

In your form, you may use the form type as follows:

// src/Admin/PageAdmin.php

use Sonata\Form\Type\DatePickerType;
use Sonata\Form\Type\DateTimePickerType;

final class PageAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('publicationDateStart', DateTimePickerType::class)

            // or DatePickerType if you don't need the time
            ->add('publicationDateStart', DatePickerType::class);
    }
}

Many of the standard date picker options are available by adding options with a dp_ prefix:

// src/Admin/PageAdmin.php

use Sonata\Form\Type\DatePickerType;
use Sonata\Form\Type\DateTimePickerType;

final class PageAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('publicationDateStart', DateTimePickerType::class, [
                'dp_side_by_side'       => true,
                'dp_use_current'        => false,
                'dp_use_seconds'        => false,
                'dp_collapse'           => true,
                'dp_calendar_weeks'     => false,
                'dp_view_mode'          => 'days',
                'dp_min_view_mode'      => 'days',
            ])

            // or DatePickerType if you don't need the time
            ->add('publicationDateStart', DatePickerType::class, [
                'dp_use_current' => false,
            ]);
    }
}

If you look in the classes DateTimePickerType.php and BasePickerType.php you can see all the currently available options.

In addition to these standard options, there is also the option datepicker_use_button which, when used, will change the widget so that the datepicker icon is not shown and the pop-up datepicker is invoked simply by clicking on the date input.

3.8. DateRangePickerType and DateTimeRangePickerType

Those types extend the basic range form field types (Sonata\Form\Type\DateRangeType and Sonata\Form\Type\DateTimeRangeType).

You can use them if you need datetime picker in datetime range filters.

Example with Sonata\DoctrineORMAdminBundle\Filter\DateRangeFilter filter:

// src/Admin/PostAdmin.php

use Sonata\Form\Type\DateRangeType;
use Sonata\DoctrineORMAdminBundle\Filter\DateRangeFilter;

final class PostAdmin extends AbstractAdmin
{
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('createdAt', DateRangeFilter::class, [
                'field_type' => DateRangeType::class,
            ]);
    }
}

3.9. ColorType

This is HTML5 input type color.

../../_images/color.png

In order to use it, you’ll need to perform a bit of setup:

# config/packages/twig.yaml

twig:
    form_themes:
        - '@SonataForm/Form/color.html.twig'

Finally, in your form, you may use the form type as follows:

// src/Admin/PageAdmin.php

use Sonata\Form\Type\ColorType;

final class PageAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('color', ColorType::class);
    }
}