Sonata Admin Bundle : enable field dynamically - php

I use Sonata Admin Bundle in my Symfony2 project. In one form, I have a list of choice containing two items, 'article' and 'event', and a date field, which is relevant only if 'event' is selected in the list.
How can I disabla/enable according to which value in the list is selected?
Here is my relevant code :
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title', null, array(
'label' => 'Titre',
))
->add('type', 'choice', array('choices' => array('0' => 'Article', '1' => 'Evénement',)) )
->add('gameDate', null, array('required' => false));
}
Thank you for your help.

Maybe: https://sonata-project.org/bundles/admin/master/doc/reference/form_types.html#sonata-adminbundle-form-type-choicefieldmasktype if you just show additional field based on choice

just to save you some scrolling, here's the relevant section from the doc:
13.1.5. SONATA\ADMINBUNDLE\FORM\TYPE\CHOICEFIELDMASKTYPE
According the choice made only associated fields are displayed. The others fields are hidden.
<?php
// src/AppBundle/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;
class AppMenuAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->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')
;
}
}

Related

Symfony 4 - Multiple forms of same type with dynamic display fields

I would like to use my UserType form class to register a user and to edit the user profile. As I want to the admins to register a user while setting up their roles, I don't want the user to modify that options. So I would like to use 2 different forms but for the same type User.
Can I create 2 different buildForm() functions in one FormType class ?
Or do I need to create another type ?
Here is my UserType class (main purpose was to register a user) :
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\BirthdayType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', TextType::class)
->add('lastname', TextType::class)
->add('birthdate', BirthdayType::class, array(
'placeholder' => '-'))
->add('email', EmailType::class)
->add('username', TextType::class)
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array('label' => 'password'),
'second_options' => array('label' => 'repeat-password'),
))
->add('roles', ChoiceType::class, [
'multiple' => true,
'expanded' => true, // render check-boxes
'choices' => [
'Administrateur' => 'ROLE_ADMIN',
'Direction' => 'ROLE_MANAGER',
'Comptabilite' => 'ROLE_ACCOUNTING',
'Commercial' => 'ROLE_MARKETING',
'Docteur' => 'ROLE_DOCTOR',
'Client' => 'ROLE_CLIENT',
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class,
));
}
}
You can use a variable to dynamically add the roles to the formType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->is_admin = $options['is_admin'];
// [...]
if ($this->is_admin)
$builder
->add('roles', ChoiceType::class, [
'multiple' => true,
'expanded' => true,
'choices' => [
'Administrateur' => 'ROLE_ADMIN',
'Direction' => 'ROLE_MANAGER',
'Comptabilite' => 'ROLE_ACCOUNTING',
'Commercial' => 'ROLE_MARKETING',
'Docteur' => 'ROLE_DOCTOR',
'Client' => 'ROLE_CLIENT',
],
])
// [...]
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
// [...]
'is_admin' => false,
]);
}
Then pass the variable like
$form = $this->createForm(UserType::class, $user, array(
'is_admin' => $this->isGranted('ROLE_ADMIN'),
);
you can easily handle this using array $optionsin controller set choices of roles and add them to $optionand in userType do something like this:
->add('roles', ChoiceType::class, [
'multiple' => true,
'expanded' => true, // render check-boxes
'choices' => $options['choices'],
])

SonataAdminBundle "sonata_type_translatable_choice" field type

I'm struggling with the "sonata_type_translatable_choice" field type.
PageAdmin.php :
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->with('page.title', ['class' => 'col-md-12'])
->add('name', null, ['label' => 'page.field.name'])
->add('code', null, ['label' => 'page.field.code'])
->add('content', 'ckeditor', ['label' => 'page.field.content'])
->add('status', 'sonata_type_translatable_choice', [
'choices' => Page::$statuses,
'catalogue' => 'admin',
'label' => 'page.field.status'
])
->end()
;
}
Page.php :
public static $statuses = array(
self::STATUS_HIDDEN => 'page.status.hidden',
self::STATUS_OFFLINE => 'page.status.offline',
self::STATUS_DRAFT => 'page.status.draft',
self::STATUS_ONLINE => 'page.status.online'
);
admin.en.yml :
page:
status:
hidden: hidden
offline: offline
draft: draft
online: online
The form is displaying the select field with the values : "page.status.hidden" instead of "hidden" located in my .yml file.
Can someone help me with this ?

Sonata admin "sonata_type_collection" tries to remove entity

I have two entities and two Admin classes(StripePage and Stripe) for them. Form looks good, it has my fields and button to add new subforms. When "add new" button is clicked, new subform with form from Admin class is rendered, but if you click second time on this button or try to save entity error appears:
Catchable Fatal Error: Argument 1 passed to
Fred\CoreBundle\Entity\StripePage::removeStripe() must be an instance
of Fred\CoreBundle\Entity\Stripe, null given in
C:\Users\lubimov\OpenServer\domains\tappic.dev\src\Fred\CoreBundle\Entity\StripePage.php
So symfony tries to remove entity instead of adding it.
StripePageAdmin class:
class StripePageAdmin extends Admin
{
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id', null, array('label' => 'id'))
->add('name', null, array('label' => 'Page name'));
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name', 'text', array('label' => 'Page name'))
->add('stripes', 'sonata_type_collection',
array('label' => 'Stripes', 'required' => false, 'by_reference' => false),
array('edit' => 'inline', 'inline' => 'table', 'sortable' => 'pos')
)
->end();
}
}
StripeAdmin class:
class StripeAdmin extends Admin
{
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('picture', null, array('sortable' => true))
->add('text', null, array('sortable' => true))
->add('deep_link', null, array('sortable' => true));
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('file', 'file', array('label' => 'Picture'))
->add('text', null, array('label' => 'Text'))
->add('deep_link', 'choice', array(
'choices' => array('test1' => 'Test1', 'test' => 'Test2'),
'label' => 'Deep Link',
))
->end();
}
}
What is the problem? Stripe form in admin class must be configured by other way?
Well, solution that I use now is to set 'by_reference' => true in 'sonata_type_collection' settings.
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name', 'text', array('label' => 'Page name'))
->add('stripes', 'sonata_type_collection',
array('label' => 'Stripes', 'required' => false, 'by_reference' => true),
array('edit' => 'inline', 'inline' => 'table', 'sortable' => 'pos')
)
->end();
}
After this need to declare setStripes() method in entity.
public function setStripes(\Doctrine\Common\Collections\ArrayCollection $stripes) {
$this->stripes = $stripes;
}
If somebody finds how to solve this using addStripe() type of methods, please share it here.

SonataAdmin - Custom form template for each form

I'm having problems with Sonata Admin Bundle. What I would like to do is:
Add some text before some labels in my form. Like for example:
The resolution of your image must be ..x.. .
For example I have a form like this:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('locale', 'choice', array(
'choices' => array('nl' => 'NL', 'en' => 'EN'),
'required' => true,
))
->add('pageid.tag', 'text', array('label' => 'Tag'))
->add('description', 'text', array('label' => 'Beschrijving'))
->add('content', 'textarea', array('label' => 'Tekst', 'attr' => array('class' => 'ckeditor')))
->add('files', 'file', array('required' => false, 'multiple' => true))
;
}
Now I would like to add some text before my files input field.
What I've done now is:
Add this to my config.yml (overload the templates/form configuration option):
sonata_doctrine_orm_admin:
# default value is null, so doctrine uses the value defined in the configuration
entity_manager: ~
templates:
form:
- MurisBundle:PageAdmin:form_admin_fields.html.twig
But this will be used for every form, can't I set specific form templates for specific forms?
You can specify form template in your admin class overriding getFormTheme method.
Add this code to your admin class.
public function getFormTheme()
{
return array_merge(
parent::getFormTheme(),
array('MurisBundle:PageAdmin:form_admin_fields.html.twig')
);
}
getPictureUrlFull().'" alt="'.$campaign->getPicture().'" style="margin-top:10px;" />Use "help"
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('locale', 'choice', array(
'choices' => array('nl' => 'NL', 'en' => 'EN'),
'required' => true,
'help' => '<img src="'.$entity->getPictureUrlFull().'" alt="'.$entity->getPicture().'" />'
))
)

How is the best way to add select with choices to filters in Sonata Admin?

How is the best way to add select with choices to filters in Sonata Admin?
For form i can:
$builder->add('gender', 'choice', array(
'choices' => array('m' => 'Male', 'f' => 'Female'),
'required' => false,
));
but this not working in filters.
For your admin class you should use configureDatagridFilters function to add your filters,if you want to add custom options for your gender fields you can use doctrine_orm_string and provide your choices list in array form
$datagridMapper
->add('gender',
'doctrine_orm_string',
array(),
'choice',
array('choices' => array('m' => 'Male', 'f' => 'Female')
)
);
Try this:
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('gender',null, array(), ChoiceType::class, array(
'choices' => array('m' => 'Male', 'f' => 'Female')
))
;
}
On my version - symfony 3.4 and "sonata-project/doctrine-orm-admin-bundle": "^3.0"
worked this way:
->add('preferredLanguage', 'doctrine_orm_choice', [
'global_search' => true,
'field_type' => ChoiceType::class,
'field_options' => [
'choices' => [
'English' => PotentialCustomerInterface::PREFERRED_LANGUAGE_ENGLISH,
'Spanish' => PotentialCustomerInterface::PREFERRED_LANGUAGE_SPANISH
]
]
]
)
The choices are string values in database.
If you want choices from database filtered by some logic:
->add('csr', 'doctrine_orm_choice', [
'field_type' => EntityType::class,
'field_options' => [
'class' => User::class,
'query_builder' => function (UserRepository $userRepository) {
return $userRepository->qbFindAdmins();
},
]
]
)
In UserRepository just create method which returns query builder.
I'm using symfony 4.3 and sonata-admin-bundle 3.0 and this is how I ended up doing:
use Sonata\DoctrineORMAdminBundle\Filter\StringFilter;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
/**
* #param DatagridMapper $datagridMapper
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('gender', StringFilter::class, ['label' => 'Gender'], ChoiceType::class, [
'choices' => ['m' => 'Male', 'f' => 'Female']
])
;
}

Categories