表单类型
Admin 相关表单类型
在管理类中定义字段时,您可以使用任何标准的 Symfony 字段类型,并像往常一样配置它们。此外,还有一些特殊的 Sonata 字段类型,允许您处理一个实体类和另一个实体类之间的关系。
Sonata\AdminBundle\Form\Type\ModelType
此类型允许您从链接的模型类中选择现有实体。实际上,它显示了一个选项列表,您可以从中选择一个值(或多个值)。
例如,我们有一个名为 Page
的实体类,它有一个名为 image1
的字段,该字段将关系映射到另一个名为 Image
的实体类。我们现在需要做的就是在我们的 PageAdmin
类中为此字段添加一个引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Admin/PageAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\Type\ModelType;
final class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$imageFieldOptions = []; // see available options below
$form
->add('image1', ModelType::class, $imageFieldOptions)
;
}
}
请注意,FormMapper::add()
的第三个参数是可选的,因此无需传入空数组,此处显示它只是为了演示当您想要使用选项时,选项的位置。
由于 image1
字段引用了一个相关实体,因此我们不需要指定任何选项。Sonata 将计算出链接的 admin 类类型为 Image
,并且默认情况下,使用 ImageAdmin
类来检索所有现有 Image 的列表,以在选择器中显示为选项。
提示
在这种情况下,您需要创建 ImageAdmin
类才能使用 sonata_type_model
类型。 您也可以使用 admin_code
参数。
可用选项有
property
- 默认为
null
。您可以将其设置为 Symfony PropertyPath 兼容字符串,以指定要用于选项值的字段。 query
- 默认为
null
。您可以将其设置为 ProxyQueryInterface 实例,以便为检索可用选项定义自定义查询。 template
- 默认为 'choice' (当前未使用?)
multiple
- 默认为
false
- 有关更多信息,请参阅 Symfony choice 字段类型文档 expanded
- 默认为
false
- 有关更多信息,请参阅 Symfony choice 字段类型文档 choices
- 默认为
null
- 有关更多信息,请参阅 Symfony choice 字段类型文档 preferred_choices
- 默认为 [] - 有关更多信息,请参阅 Symfony choice 字段类型文档
choice_loader
- 默认为从其他选项构建的
ModelChoiceLoader
model_manager
- 默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 class
- 由此字段管理的实体类。默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 btn_add
,btn_list
,btn_delete
和btn_translation_domain
add
、list
和delete
按钮上的标签可以使用这些参数进行自定义。将它们中的任何一个设置为false
将隐藏相应的按钮。您还可以为这些标签指定自定义翻译域,默认为SonataAdminBundle
。
注意
需要为链接的模型类定义一个 admin 类才能渲染此表单类型。
注意
如果您需要使用可排序的 Sonata
,请查看 Admin 中可排序的 Sonata 类型模型 页面。
注意
当将 Sonata
与 btn_add
一起使用时,当子表单添加到 DOM 时,将触发 jQuery 事件(默认情况下为 sonata-admin-setup-list-modal
,使用 edit:inline
时为 sonata-admin-append-form-element
)。
Sonata\AdminBundle\Form\Type\ModelListType
此类型允许您选择现有实体,添加新实体或编辑已选定的实体。
例如,我们有一个名为 Page
的实体类,它有一个名为 image1
的字段,该字段将关系映射到另一个名为 Image
的实体类。我们现在需要做的就是在我们的 PageAdmin
类中为此字段添加一个引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Admin/PageAdmin.php
use Sonata\AdminBundle\Form\Type\ModelListType;
use Sonata\AdminBundle\Form\FormMapper;
final class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$form
->add('image1', ModelListType::class)
;
}
}
可用选项有
model_manager
- 默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 class
- 由此字段管理的实体类。默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 btn_add
,btn_edit
,btn_list
,btn_delete
和btn_translation_domain
add
、edit
、list
和delete
按钮上的标签可以使用这些参数进行自定义。将它们中的任何一个设置为false
将隐藏相应的按钮。您还可以为这些标签指定自定义翻译域,默认为SonataAdminBundle
。
Sonata\AdminBundle\Form\Type\ModelHiddenType
隐藏字段的值是相关实体的标识符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Admin/PageAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\Type\ModelHiddenType;
final class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
// generates hidden form field with id of related Category entity
$form
->add('categoryId', ModelHiddenType::class)
;
}
}
可用选项有
model_manager
- 默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 class
- 由此字段管理的实体类。默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。
Sonata\AdminBundle\Form\Type\ModelAutocompleteType
此类型允许您从链接的模型类中选择现有实体。实际上,它显示了一个选项列表,您可以从中选择一个值。选项列表在键入 3 个字符(自动完成)后动态加载 ajax。它最适合项目众多的实体。
如果相关实体具有 admin 实例,并且在相关实体数据网格中存在 property
字段的字符串过滤器,则此字段类型默认情况下起作用。
例如,我们有一个名为 Article
(在 ArticleAdmin
中)的实体类,它有一个名为 category
的字段,该字段将关系映射到另一个名为 Category
的实体类。我们现在需要做的就是在我们的 ArticleAdmin
类中为此字段添加一个引用,并确保在 CategoryAdmin
中存在属性 title
的数据网格过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Admin/ArticleAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
final class ArticleAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
// the dropdown autocomplete list will show only Category
// entities that contain specified text in "title" attribute
$form
->add('category', ModelAutocompleteType::class, [
'property' => 'title'
])
;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Admin/CategoryAdmin.php
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
final class CategoryAdmin extends AbstractAdmin
{
protected function configureDatagridFilters(DatagridMapper $datagrid)
{
// this text filter will be used to retrieve autocomplete fields
$datagrid
->add('title')
;
}
}
可用选项有
property
- 默认为
null
。您必须设置此项以指定要用于选项值的字段(或字段列表)。此值可以是字符串或字符串数组。 class
- 由此字段管理的实体类。默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 model_manager
- 默认为
null
,但实际上是从链接的 admin 类计算出来的。您通常不需要手动设置此项。 callback
-
默认为
null
。可调用函数,可用于修改用于检索自动完成项的查询。回调应接收三个参数 - admin 实例、定义为可搜索的属性(或属性)以及用户输入的搜索值。从
$admin
参数可以获取Datagrid
和Request
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'callback' => static function (AdminInterface $admin, string $property, $value): void { $datagrid = $admin->getDatagrid(); $query = $datagrid->getQuery(); $query ->andWhere($query->getRootAlias() . '.foo=:barValue') ->setParameter('barValue', $admin->getRequest()->get('bar')) ; $datagrid->setValue($property, null, $value); }, ]) ;
如果您想动态更改要过滤的
property
,可以使用前缀系统,如下所示。当用户键入 id: 20 时,用于过滤的属性是“id”。当他们键入 username: awesome_user_name 时,它将是“username”1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'callback' => static function (AdminInterface $admin, string $property, string $value): void { $datagrid = $admin->getDatagrid(); $valueParts = explode(':', $value); if (count($valueParts) === 2 && in_array($valueParts[0], ['id', 'email', 'username'])) { [$property, $value] = $valueParts; } $datagrid->setValue($datagrid->getFilter($property)->getFormName(), null, $value); }, ]) ;
to_string_callback
-
默认为
null
。可调用函数,可用于更改实体的默认 toString 行为1 2 3 4 5 6 7 8
$form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'to_string_callback' => function($entity, $property) { return $entity->getTitle(); }, ]) ;
response_item_callback
-
默认为
null
。可调用函数,可用于自定义 JSON 中单独返回的每个项目1 2 3 4 5 6 7 8 9 10
$form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'response_item_callback' => function (AdminInterface $admin, object $entity, array $item): array { $item['type'] = $entity->getType(); return $item; }, ]) ;
multiple
- 默认为
false
。如果您的字段处于多对多关系中,请设置为true
。 placeholder
- 默认为 ""。当未选择任何项目时,将显示占位符。
minimum_input_length
- 默认为 3。应键入以加载 ajax 数据的最少字符数。
items_per_page
- 默认为 10。每个 ajax 请求的项目数。
quiet_millis
- 默认为 100。在发出 ajax 请求之前等待用户停止键入的毫秒数。
cache
- 默认为
false
。如果请求的页面应由浏览器缓存,请设置为true
。 url
- 默认为 ""。ajax 请求的目标外部远程 URL。您通常不需要手动设置此项。
route
- 用作 ajax 请求目标 URL 的路由
name
和parameters
。 width
- 默认为 ""。控制 Select2 容器 div 的宽度样式属性。
dropdown_auto_width
- 默认为
false
。设置为true
以启用dropdownAutoWidth
Select2 选项,该选项允许下拉列表比父输入更宽,并根据其内容调整大小。 container_css_class
- 默认为 ""。将添加到 select2 容器标签的 Css 类。
dropdown_css_class
- 默认为 ""。下拉列表的 CSS 类。
dropdown_item_css_class
- 默认为 ""。下拉列表项的 CSS 类。
safe_label
- 默认为
false
。设置为true
以启用将标签显示为原始 HTML,这可能会导致 XSS 漏洞。 req_param_name_search
- 默认为 "q"。Ajax 请求参数名称,其中包含搜索到的文本。
req_param_name_page_number
- 默认为 "_page"。Ajax 请求参数名称,其中包含页码。
req_param_name_items_per_page
- 默认为 "_per_page"。Ajax 请求参数名称,其中包含每页的项目数限制。
template
- 默认为
@SonataAdmin/Form/Type/sonata_type_model_autocomplete.html.twig
。如果您想覆盖此表单类型的默认模板,请使用此选项。 btn_add
和btn_translation_domain
-
add
按钮上的标签可以使用这些参数进行自定义。将它们中的任何一个设置为false
将隐藏相应的按钮。您还可以为这些标签指定自定义翻译域,默认为SonataAdminBundle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Admin/ArticleAdmin.php use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Form\Type\ModelAutocompleteType; final class ArticleAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $form): void { $form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'template' => '@App/Form/Type/sonata_type_model_autocomplete.html.twig', ]) ; } }
1 2 3 4 5 6 7 8 9 10 11 12
{# templates/Form/Type/sonata_type_model_autocomplete.html.twig #}
{% extends '@SonataAdmin/Form/Type/sonata_type_model_autocomplete.html.twig' %}
{# change the default selection format #}
{% block sonata_type_model_autocomplete_selection_format %}'<b>'+item.label+'</b>'{% endblock %}
{# customize select2 options #}
{% block sonata_type_model_autocomplete_select2_options_js %}
options.multiple = false;
options.dropdownAutoWidth = false;
{% endblock %}
target_admin_access_action
-
默认为
list
。默认情况下,用户需要LIST
角色(映射到list
访问操作)才能从目标 admin 的数据网格获取自动完成项。如果您无法为某些用户提供此角色,因为他们将有权访问目标 admin 的数据网格,则必须授予他们另一个角色。在下面的示例中,我们将
target_admin_access_action
从list
更改为autocomplete
,这在目标 admin 中映射到AUTOCOMPLETE
角色。请确保所有有效用户都拥有AUTOCOMPLETE
角色1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Admin/ArticleAdmin.php use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Form\Type\ModelAutocompleteType; final class ArticleAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $form): void { // the dropdown autocomplete list will show only Category // entities that contain specified text in "title" attribute $form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'target_admin_access_action' => 'autocomplete', ]) ; } }
您必须按以下方式修改目标实体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Admin/CategoryAdmin.php use Sonata\AdminBundle\Datagrid\DatagridMapper; use Sonata\AdminBundle\Admin\AbstractAdmin; final class CategoryAdmin extends AbstractAdmin { protected $accessMapping = [ 'autocomplete' => 'AUTOCOMPLETE', ]; protected function configureDatagridFilters(DatagridMapper $datagrid): void { // this text filter will be used to retrieve autocomplete fields // only the users with role AUTOCOMPLETE will be able to get the items $datagrid ->add('title') ; } }
attr
-
将呈现到 select 标签中的任意属性数组
1 2 3 4 5 6 7 8
$form ->add('category', ModelAutocompleteType::class, [ 'property' => 'title', 'attr' => [ 'data-my-custom-variable' => 'my-custom-value', ], ]) ;
Sonata\AdminBundle\Form\Type\ChoiceFieldMaskType
根据所做的选择,仅显示关联的字段。其他字段被隐藏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
// src/Admin/AppMenuAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\Type\ChoiceFieldMaskType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
final class AppMenuAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$form
->add('linkType', ChoiceFieldMaskType::class, [
'choices' => [
'uri' => 'uri',
'route' => 'route',
],
'map' => [
'route' => ['route', 'parameters'],
'uri' => ['uri'],
],
'placeholder' => 'Choose an option',
'required' => false
])
->add('route', TextType::class)
->add('uri', TextType::class)
->add('parameters')
;
}
}
map
- 关联数组。描述为每个选择显示的字段。
- .. figure:: ../images/choice_field_mask_type.gif
- :alt: 表单类型选择字段掩码类型
Sonata\AdminBundle\Form\Type\AdminType
设置 Sonata
字段类型将嵌入另一个 admin 类,并在编辑此字段时使用嵌入式 admin 的配置。Sonata
字段应仅在编辑表示两个模型类之间关系的字段时使用。
此类型允许您嵌入相关元素的完整表单,您可以对其进行配置以允许创建、编辑和(可选)删除相关对象。
例如,让我们使用与上面的 Sonata
类似的示例。这一次,当使用 PageAdmin
编辑 Page
时,我们希望启用新 Image 的内联创建(和编辑),而不是从列表中选择现有 Image。
首先,我们需要创建一个 ImageAdmin
类,并将其注册为用于管理 Image
对象的 admin 类。在我们的 services.yaml
中,我们有一个用于 ImageAdmin
的条目,如下所示
1 2 3 4 5 6 7 8 9
# config/services.yaml
services:
app.admin.image:
class: App\Admin\ImageAdmin
calls:
- [setTranslationDomain, ['App']]
tags:
- { name: sonata.admin, model_class: App\Entity\Image, controller: 'Sonata\AdminBundle\Controller\CRUDController', manager_type: orm, label: 'Image' }
要在 PageAdmin
中嵌入 ImageAdmin
,我们需要将 image1
字段的引用更改为 AdminType
在我们的 PageAdmin
类中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Admin/PageAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\Type\AdminType;
final class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$form
->add('image1', AdminType::class)
;
}
}
我们不需要定义任何选项,因为 Sonata 会计算出链接的类类型为 Image
,并且服务定义(在 services.yaml
中)定义 Image
对象由 ImageAdmin
类管理。
可用选项(可以作为第三个参数传递给 FormMapper::add()
)是
delete
- 默认为
true
,表示应显示“delete”复选框,允许用户删除链接的对象。 btn_add
,btn_list
,btn_delete
和btn_translation_domain
add
、list
和delete
按钮上的标签可以使用这些参数进行自定义。将它们中的任何一个设置为false
将隐藏相应的按钮。您还可以为这些标签指定自定义翻译域,默认为SonataAdminBundle
。
Sonata\Form\Type\CollectionType
Sonata\Form\Type\CollectionType
旨在处理模型集合的创建和编辑。可以添加和删除行,并且您的模型抽象层可能允许您内联编辑字段。您可以使用 type_options
将值传递给底层表单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
// src/Admin/ProductAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\Form\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
final class ProductAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$form
->add('sales', CollectionType::class, [
'type_options' => [
// Prevents the "Delete" option from being displayed
'delete' => false,
'delete_options' => [
// You may otherwise choose to put the field but hide it
'type' => HiddenType::class,
// In that case, you need to fill in the options as well
'type_options' => [
'mapped' => false,
'required' => false,
]
]
]
], [
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
])
;
}
}
可用选项(可以作为第三个参数传递给 FormMapper::add()
)是
btn_add
和btn_translation_domain
add
按钮上的标签可以使用此参数进行自定义。将其设置为false
将隐藏相应的按钮。您还可以为此标签指定自定义翻译域,默认为SonataAdminBundle
。
提示
在添加行后,会触发 jQuery 事件 (sonata-admin-append-form-element
)。您可以监听此事件以触发自定义 JavaScript(例如:向新添加的日期字段添加日历小部件)
提示
将 'required' 选项设置为 true
不会导致“至少一个”子实体的要求。将 'required' 选项设置为 false
会导致所有嵌套表单字段也变为非必需。
提示
您可以通过单击第一个复选框,然后按住 shift 键单击第二个复选框来选中/取消选中一系列复选框。
警告
如果您正在使用 sonata.admin.security.handler.role
,则必须至少为关系的 Admin 设置 CREATE 权限,才能向集合添加更多行。为了删除行,您必须设置 DELETE 权限。有关权限的更多信息,请查看 安全性 页面。
Sonata\AdminBundle\Form\Type\CollectionType
此 bundle 通过添加以下内容来处理原生 Symfony collection
表单类型
- 如果您将
allow_add
选项设置为true
,则添加add
按钮。 - 如果您将
allow_delete
选项设置为true
,则添加delete
按钮。
提示
在添加行后,会触发 jQuery 事件 (sonata-admin-append-form-element
)。您可以监听此事件以触发自定义 JavaScript(例如:向新添加的日期字段添加日历小部件)
提示
在添加行后,会触发 jQuery 事件 (sonata-collection-item-added
) 或在删除行之前 (sonata-collection-item-deleted
)。在成功删除行后,会触发 jQuery 事件 (sonata-collection-item-deleted-successful
)。您可以监听这些事件以触发自定义 JavaScript。
警告
如果您正在使用 sonata.admin.security.handler.role
,则必须至少为关系的 Admin 设置 CREATE 权限,才能向集合添加更多行。为了删除行,您必须设置 DELETE 权限。有关权限的更多信息,请查看 安全性 页面。
FieldDescription 选项
FormMapper::add()
的第四个参数允许您将 FieldDescription
选项作为数组传入。其中最有用的一个是 admin_code
,它允许您指定要用于管理此关系的 admin。它与 Sonata
表单类型结合使用内联编辑时最有用。
使用的值应该是 admin *service* 名称,而不是类名称。如果您未以这种方式指定 admin_code
,则将使用字段模型类型的默认 admin 类。
例如,要指定使用注册为 sonata.admin.imageSpecial
的 admin 类来管理我们 PageAdmin
示例中的 image1
字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Admin/PageAdmin.php
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\Type\AdminType;
final class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$form
->add('image1', AdminType::class, [], [
'admin_code' => 'sonata.admin.imageSpecial'
])
;
}
}
其他特定字段配置选项在相关的抽象层文档中详细说明。
Types 选项
通用
您可以使用任何 Symfony 表单选项 来自定义表单字段。例如
你可以设置
label
选项为false
,如果你不想显示它1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Admin/PageAdmin.php use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Admin\AbstractAdmin; final class PageAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $form): void { $form ->add('status', null, [ 'label' => false ]) ; } }
你可以使用
help
选项来添加与表单字段一起呈现的消息1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Admin/PostAdmin.php final class PostAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $form): void { $form ->with('General') ->add('title', null, [ 'help' => 'Set the title of a web page' ]) ->add('keywords', null, [ 'help' => 'Set the keywords of a web page' ]) ->end() ; } }

Symfony\Component\Form\Extension\Core\Type\ChoiceType
sortable
: 此选项可以为多项选择小部件添加,以激活 select2 sortable1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Admin/PageAdmin.php use Sonata\AdminBundle\Form\FormMapper; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Sonata\AdminBundle\Admin\AbstractAdmin; final class PageAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $form): void { $form ->add('multiChoices', ChoiceType::class, [ 'multiple' => true, 'sortable' => true, ]) ; } }