php - isvalid - Symfony2: cambiar las opciones con ajax y validación
symfony forms (1)
Escenario: tengo un formulario con 2 selecciones. Cuando el usuario selecciona algo de la primera selección, la segunda selección se llena con nuevos valores. Esta parte funciona bien.
Pero el formulario no se valida, ya que contiene algunas opciones que no están permitidas en la forma inicial.
Formar:
<?php
class MyType extends AbstractType
{
private $category;
public function __construct($category = null)
{
$this->category = $category;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(''category'', ''choice'', array(
''choices'' => array(
''foo'' => ''foo'',
''bar'' => ''bar''
)
);
$builder->add(''template'', ''choice'', array(
''choices'' => $this->loadChoices()
);
}
private function loadChoices()
{
// load them from DB depending on the $this->category
}
}
Inicialmente, la categoría es foo
. Entonces las plantillas para foo se cargan y se configuran como opciones. Pero si el usuario selecciona la bar
, las plantillas de barras se cargan. Pero la forma todavía tiene las opciones foo y no valida.
¿Cuál es la mejor manera de resolver esto?
Una manera que encontré fue simplemente reiniciar la forma en el controlador:
<?php
$form = $this->createForm(new MyType());
if ($request->getMethod() === ''POST'') {
if ($request->request->has($form->getName())
&& isset($request->request->get($form->getName())[''category''])) {
$form = $this->createForm(new MyType($request->request->get($form->getName())[''category'']));
}
// ...
}
Esto funciona, pero no puedo probarlo porque arroja IllegalArgumentException
al establecer el valor y solo asume el valor predeterminado. ¿Hay alguna mejor solución para esto? ¡Gracias por adelantado!
Creo que tienes que usar Eventos para administrar esto, que es la manera más correcta
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(''category'', ''choice'', array(
''choices'' => array(
''foo'' => ''foo'',
''bar'' => ''bar''
)
));
$ff = $builder->getFormFactory();
// function to add ''template'' choice field dynamically
$func = function (FormEvent $e) use ($ff) {
$data = $e->getData();
$form = $e->getForm();
if ($form->has(''template'')) {
$form->remove(''template'');
}
$cat = isset($data[''category''])?$data[''category'']:null;
// here u can populate ur choices in a manner u do it in loadChoices
$choices = array(''1'' => ''1'', ''2'' => ''2'');
if ($cat == ''bar'') {
$choices = array(''3'' => ''3'', ''4'' => ''4'');
}
$form->add($ff->createNamed(''template'', ''choice'', null, compact(''choices'')));
};
// Register the function above as EventListener on PreSet and PreBind
$builder->addEventListener(FormEvents::PRE_SET_DATA, $func);
$builder->addEventListener(FormEvents::PRE_BIND, $func);
}