Modifying form fields dynamically depending on edited object
It is a quite common situation when you need to modify your form's fields because of edited object's properties or structure. Let us assume you only want to display an admin form field for new objects and you do not want it to be shown for those objects that have already been saved to the database and now are being edited.
This is a way for you to accomplish this.
In your Admin
class' configureFormFields
method you are able to get the
current object by calling $this->getSubject()
. The value returned will be your
linked model. And another method isCurrentRoute
for check the current request's route.
Then, you should be able to dynamically add needed fields to the form:
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 35 36 37 38 39 40
// src/Admin/PostAdmin
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
final class PostAdmin extends AbstractAdmin
{
// ...
protected function configureFormFields(FormMapper $form): void
{
// Description field will always be added to the form:
$form
->add('description', TextareaType::class)
;
$subject = $this->getSubject();
// If you're using auto-generated identifiers
if ($subject->getId() === null) {
// The thumbnail field will only be added when the edited item is created
$form->add('thumbnail', FileType::class);
}
// Name field will be added only when create an item
if ($this->isCurrentRoute('create')) {
$form->add('name', TextType::class);
}
// The foo field will added when current action is related acme.demo.admin.code Admin's edit form
if ($this->isCurrentRoute('edit', 'acme.demo.admin.code')) {
$form->add('foo', 'text');
}
}
}
This work, including the code samples, is licensed under a
Creative Commons BY-SA 3.0
license.