Fields map entity properties to the four CRUD contexts - list, view, create, and edit.
Similar to Doctrine mappings or Symfony form types, their behaviour changes depending on the underlying data.
Usually fields will show the underlying data in the list and view contexts, and present form fields for the create and edit contexts. For example, a password
type might show asterisks for the list and view contexts, and show a password input for the create and edit contexts.
Fields can also include css and javascript for complex UI interactions, and also include fields themselves!
For example, the collection
type can arbitrarily nest child crud classes and manage their ordering using a javascript helper.
For every crud class, the fields are defined in the configureFields()
method.
Many field types are supplied by the PerformBaseBundle, but other bundles provide them too.
Run the perform:debug:field-types
command to list the available field types:
$ ./bin/console perform:debug:field-types
+------------+---------------------------------------------+
| Type | Class |
+------------+---------------------------------------------+
| string | Perform\BaseBundle\FieldType\StringType |
| text | Perform\BaseBundle\FieldType\TextType |
| password | Perform\BaseBundle\FieldType\PasswordType |
| date | Perform\BaseBundle\FieldType\DateType |
...
Field types are registered with the perform_base.field_type_registry
service (an instance of Perform\BaseBundle\FieldType\FieldTypeRegistry
) when the container is compiled.
You normally won’t need to interact with this service directly.
CrudInterface#configureFields()
takes an instance of Perform\BaseBundle\Config\FieldConfig
, which is used as a builder to add fields for a given entity.
Add a new type with FieldConfig#add()
, which requires the name of the field and an array of configuration.
The field name can be anything accessible by Symfony’s property access component. Configuration should be an array with the following properties:
type
- string, required. The field type name.contexts
- array. A list of contexts using this field. Each item should be one of CrudRequest::CONTEXT_LIST
, CrudRequest::CONTEXT_VIEW
, CrudRequest::CONTEXT_CREATE
, CrudRequest::CONTEXT_EDIT
, or CrudRequest::CONTEXT_EXPORT
. Defaults to all contexts.sort
- boolean or Closure. Whether to allow sorting by this field. Pass a closure for custom sorting by this field. Defaults to true.options
- array. Options to pass to the field type. Different field types require different options. See Field Type Reference for more information.listOptions
, viewOptions
, createOptions
, editOptions
- array. Field type options specific to a certain context.template
- string. Override the twig template used to render this type. Will only apply to this field.Use the contexts
option to restrict a type to certain contexts:
public function configureFields(FieldConfig $config)
{
$config->add('readOnly', [
'type' => 'string',
'contexts' => [
CrudRequest::CONTEXT_LIST,
CrudRequest::CONTEXT_VIEW,
],
]);
$config->add('noEdit', [
'type' => 'string',
'contexts' => [
CrudRequest::CONTEXT_LIST,
CrudRequest::CONTEXT_VIEW,
CrudRequest::CONTEXT_CREATE,
],
]);
}
Setting the sort
option to true will allow sorting by this field.
The header of that column in the table will be clickable, which will sort the list of entities by that field.
sort
can also be a closure, which will be passed a Doctrine\ORM\QueryBuilder
instance and the sort direction as a string.
For example, consider displaying a virtual fullname
property in a list context:
class SomeEntity
{
//...
public function getFullname()
{
return $this->forename . ' ' . $this->surname;
}
}
It’s not possible to sort by this method in the database, so a custom sort function is required:
public function configureFields(FieldConfig $config)
{
$config->add('fullname', [
'type' => 'string',
'contexts' => [
CrudRequest::CONTEXT_LIST,
],
'sort' => function($qb, $direction) {
return $qb->orderBy('e.forename', $direction)
->addOrderBy('e.surname', $direction);
},
]);
}
On first load, the list context is completely unsorted.
Use FieldConfig#setDefaultSort()
to sort by a certain field by default.
You may also pass in a field that has not been added to the field config, which will be treated as if it had been added with the sort
option set to true
.
public function configureFields(FieldConfig $config)
{
//...
$config->setDefaultSort('createdAt', 'DESC');
}
Use the listOptions
, viewOptions
, createOptions
, and editOptions
to change how fields are configured for a certain context.
For example, here we tell the datetime
field type to show a human friendly date diff (e.g. 2 hours ago) in the list context, but the full date in the view context:
public function configureFields(FieldConfig $config)
{
$config->add('createdAt', [
'type' => 'datetime',
'viewOptions' => [
'human' => false,
],
'listOptions' => [
'human' => true,
],
]);
}
Adding a field without the contexts
option will enable it for all contexts by default.
You can change this default by calling setDefaultContexts()
:
public function configureFields(FieldConfig $config)
{
// fields are read-only by default
$config->setDefaultContexts([
CrudRequest::CONTEXT_LIST,
CrudRequest::CONTEXT_VIEW,
]);
$config->add('title', [
'type' => 'string',
]);
}
Note
The new defaults will only apply to add()
invocations after this method has been called, so you should probably place it at the top of the configureFields()
method.
You may call this method multiple times.
Each call to add()
will use the latest given defaults.
Create a service that implements Perform\Base\FieldType\FieldTypeInterface
, either through autowiring or manually.
If the service is autoconfigured, the type will be added to the registry automatically.
If the service is not autoconfigured, give the service the perform_base.field_type
tag.
The name of the field type will be guessed from the class name, or you can set it manually with the alias
tag option.
# configured automatically
MyApp\FieldType\AutoType
autoconfigure: true
# configured manually
MyApp\FieldType\ManualType
tags:
- {name: perform_base.field_type}
# configured manually, setting the type name explicitly
MyApp\FieldType\AnotherType
tags:
- {name: perform_base.field_type, alias: app_another}
Then run the perform:debug:field-types
command to view your new field types:
$ ./bin/console perform:debug:field-types
+-------------+-----------------------------+
| Name | Class |
+-------------+-----------------------------+
| auto | MyApp\FieldType\AutoType |
| manual | MyApp\FieldType\ManualType |
| app_another | MyApp\FieldType\AnotherType |
...