Forked from Raphhh/ContextualOptionsFormListener.php
Created
December 7, 2018 19:30
-
-
Save cybernet/3d8aa28f633702841b759eac78ad8185 to your computer and use it in GitHub Desktop.
Symfony form: set options according to the data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Form\EventListener; | |
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
use Symfony\Component\Form\FormEvent; | |
use Symfony\Component\Form\FormEvents; | |
class ContextualOptionsFormListener implements EventSubscriberInterface | |
{ | |
/** | |
* @var callable | |
*/ | |
private $callback; | |
/** | |
* The callback will be called for each child of the listened form. | |
* The callback will receive the following params: | |
* - FormEvent $event | |
* - $name name of the child | |
* - array $options the initial options of the child | |
* The callback must return an array with the final options of the child. | |
* | |
* @param callable $callback | |
*/ | |
public function __construct(callable $callback) | |
{ | |
$this->callback = $callback; | |
} | |
/** | |
* @return array The event names to listen to | |
*/ | |
public static function getSubscribedEvents() | |
{ | |
return [ | |
FormEvents::PRE_SET_DATA => 'preSetData', | |
]; | |
} | |
/** | |
* @param FormEvent $event | |
*/ | |
public function preSetData(FormEvent $event) | |
{ | |
$form = $event->getForm(); | |
$data = $event->getData(); | |
if (null === $data) { | |
return; | |
} | |
$children = $form->all(); | |
foreach ($form as $name => $child) { | |
$form->remove($name); | |
} | |
foreach ($children as $name => $child) { | |
$form->add( | |
$name, | |
$child->getConfig()->getType()->getInnerType(), | |
call_user_func($this->callback, $event, $name, $child->getConfig()->getOptions()) | |
); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Model; | |
class Example | |
{ | |
public $value; | |
public function isDisabled() | |
{ | |
return $this->value === 'disabled'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Controller; | |
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
use AppBundle\Model\Example; | |
use AppBundle\Model\Form\Type\ExampleType; | |
class ExampleController extends Controller | |
{ | |
/** | |
* @Route("/") | |
* @return \Symfony\Component\HttpFoundation\RedirectResponse | |
*/ | |
public function indexAction() | |
{ | |
$example = new Example(); | |
$example->value = 'disabled'; | |
$form = $this->createForm(ExampleType::class, $example); | |
... | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Form\Type; | |
use Symfony\Component\Form\AbstractType; | |
use AppBundle\Form\EventListener\ContextualOptionsFormListener; | |
use Symfony\Component\Form\FormBuilderInterface; | |
use Symfony\Component\Form\FormEvent; | |
class ExampleType extends AbstractType | |
{ | |
/** | |
* @param FormBuilderInterface $builder | |
* @param array $options | |
*/ | |
public function buildForm(FormBuilderInterface $builder, array $options) | |
{ | |
$builder->add('value'); | |
$builder->addEventSubscriber(new ContextualOptionsFormListener( | |
function (FormEvent $event, $name, array $options) { | |
if ($name === 'value') { | |
//the "value" field will be conditionnaly disabled according to Example instance. | |
$options['disabled'] = $event->getData()->isDisabled(); | |
} | |
return $options; | |
} | |
)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment