5. Form field definition
5.1. Example
namespace Sonata\NewsBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelType;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
final class PostAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('author', ModelType::class, [], ['edit' => 'list'])
->add('enabled')
// you can define help messages using Symfony help option
->add('title', null, ['help' => 'help_post_title'])
->add('abstract', null, ['required' => false])
->add('content');
}
public function validate(ErrorElement $errorElement, $object)
{
// conditional validation, see the related section for more information
if ($object->getEnabled()) {
// abstract cannot be empty when the post is enabled
$errorElement
->with('abstract')
->assertNotBlank()
->assertNotNull()
->end()
;
}
}
}
Note
By default, the form framework always sets required=true
for each
field. This can be an issue for HTML5 browsers as they provide client-side
validation.
5.2. Available Types
array
checkbox
choice
datetime
decimal
integer
text
date
time
datetime
If no type is set, the Admin class will use the one set in the doctrine mapping definition.
5.3. Short Object Placeholder
When using Many-to-One or One-to-One relations with Sonata Type fields, a short object description is used to represent the target object. If no object is selected, a “No selection” placeholder will be used. If you want to customize this placeholder, you can use the corresponding option in the form field definition:
namespace Sonata\NewsBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelListType;
final class PostAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('enabled', null, ['required' => false])
->add('author', ModelListType::class, [], [
'placeholder' => 'No author selected',
])
->end();
}
}
This placeholder is translated using the SonataAdminBundle catalogue.
5.4. Advanced Usage: File Management
If you want to use custom types from the Form framework you must use the
addType
method. (The add
method uses the information provided by the
model definition):
namespace Sonata\MediaBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
final class MediaAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name', null, ['required' => false])
->add('enabled', null, ['required' => false])
->add('authorName', null, ['required' => false])
->add('cdnIsFlushable', null, ['required' => false])
->add('description', null, ['required' => false])
->add('copyright', null, ['required' => false])
->add('binaryContent', 'file', ['required' => false]);
}
}
Note
By setting type=false
in the file definition, the Form framework will
provide an instance of UploadedFile
for the Media::setBinaryContent
method. Otherwise, the full path will be provided.
5.5. Advanced Usage: Many-to-One
If you have many Post``s linked to one ``User
, then the Post
form should
display a User
field.
SonataAdminBundle provides 3 edit options:
standard
: default value, theUser
list is set in a select widget
list
: theUser
list is set in a model where you can search and select a user
inline
: embed theUser
form into thePost
form, great for one-to-one, or if your want to allow the user to edit theUser
information.
With the standard
and list
options, you can create a new User
by clicking on the “+” icon:
namespace Sonata\NewsBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelListType;
use Sonata\AdminBundle\Form\Type\ModelType;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
final class PostAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('enabled', null, ['required' => false])
->add('author', ModelListType::class, [
// Specify a custom label
'btn_add' => 'Add author',
// which will be translated
'btn_list' => 'button.list',
// or hide the button
'btn_delete' => false,
// Custom translation domain for buttons
'btn_catalogue' => 'SonataNewsBundle',
], ['edit' => 'list'])
->add('title')
->add('abstract')
->add('content')
->end()
->with('Tags')
->add('tags', ModelType::class, ['expanded' => true])
->end()
->with('Options', ['collapsed' => true])
->add('commentsCloseAt')
->add('commentsEnabled', null, ['required' => false])
->add('commentsDefaultStatus', ChoiceType::class, [
'choices' => Comment::getStatusList(),
])
->end()
;
}
}
5.6. Advanced Usage: One-to-Many
Let’s say you have a Gallery
that links to some Media``s with a join table
``galleryHasMedias
you can reference them like:
namespace Sonata\MediaBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\Form\Type\CollectionType;
final class GalleryAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('code')
->add('enabled')
->add('name')
->add('defaultFormat')
->add('galleryHasMedias', CollectionType::class);
}
}
Add a new Media
(via galleryHasMedias
) row by defining one of these options:
edit
inline
orstandard
, the inline mode allows you to add new rowsinline
table
orstandard
, the fields are displayed into tablesortable
if the model has a position field, you can enable a drag and drop sortable effect by setting
sortable=field_name
After choosing your action, your admin would llok like this:
namespace Sonata\MediaBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\Form\Type\CollectionType;
final class GalleryAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('code')
->add('enabled')
->add('name')
->add('defaultFormat')
->add('galleryHasMedias', CollectionType::class, [], [
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
]);
}
}