Hola señor@s. Un saludo.
Tengo una duda. ¿Puedo pasarle a una clase form
variables opcionales desde el controlador? La información que me suministran es la de pasar esta información al __constructor
del formulario cuando se está instanciando. De la siguiente manera.
// controller $form = $this->createForm(new MiLindoFormType($opcional), new MiLindaClase()); // ClassForm class MiLindoForm extends AbstractType { private $opcional; public function __construct($opcional = null) { $this->opcional = $opcional; } public function buildForm(FormBuilderInterface $builder, array $options) { $opcional = $this->opcional; $builder ->add('ordenes', 'entity', array( 'class' => 'AppBundle:Operaciones\OrdenesCompra', 'property' => 'id_u_orden', 'query_builder' => function(EntityRepository $er) use($opcional){ return $er->createQueryBuilder('co') ->where('co.operaciones = :operacion') ->setParameter('operacion', $opcional); }, 'empty_value' => 'Seleccione' )); } }
De la anterior manera funciona. Mi duda es ¿cómo se puede hacer cuando tu formulario es un servicio?
$form = $this->createForm('my_lindo_form', new MiLindaClase(), array('opcion' => $opcional));
Saludos cordiales!
Respuestas
Buenas, para lograr eso se utiliza el componente OptionsResolver de Symfony.
Donde los formularios poseen un método setDefaultOptions
(configureOptions
en Symfony 2.7), en ese método defines las opciones por defecto, las requeridas y los valores permitidos para esas opciones, por ejemplo:
<?php namespace AppBundle\Form; use AppBundle\Entity\Repository\CitaRepository; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class HoraCitaType extends AbstractType { const FORMATO_HORA = 'h:i A'; /** * @var CitaRepository */ private $citasRepository; public function __construct($citasRepository) { $this->citasRepository = $citasRepository; } public function buildForm(FormBuilderInterface $builder, array $options) { // Acá tengo las opciones disponibles en la variabe $options $builder->addEventSubscriber(new AddXXXListener( $this->citasRepository, $options['fecha'], $options['hora_inicial'], $options['hora_hasta'], $options['clientes_por_hora'], )); //.... } public function configureOptions(OptionsResolver $resolver) { // Aquí defino las opciones de configuración que mi formulario va a ofrecer $resolver->setRequired([ 'fecha', 'clientes_por_hora', ]); $resolver->setAllowedTypes([ 'fecha' => ['string', 'Datetime', 'null'], 'clientes_por_hora' => 'int', ]); $resolver->setNormalizer('fecha', function ($options, $fecha) { if (is_string($fecha)) { return \DateTime::createFromFormat('d/m/Y', $fecha); } return $fecha; }); $resolver->setDefaults([ 'horas_desde' => '8:00 am', 'horas_hasta' => '5:00 pm', 'intervalo' => '+30 mins', 'formato' => self::FORMATO_HORA, ]); } public function getName() { return 'hora_cita'; } }
Defino mi formulario como un servicio (Sea o no un servicio, las opciones de configuración se manejan igual):
services: app.horas_cita_type: class: AppBundle\Form\HoraCitaType arguments: [@app.citas_repository] tags: - { name: form.type, alias: hora_cita }
Luego en el controlador, le paso las opciones de configuración de la siguiente manera:
$form = $this->createForm('hora_cita', null, [ 'fecha' => new \Datetime(), 'clientes_por_hora' => 3, 'intervalo' => '+1 hours', ]);
Espero te sirva, saludos!
@manuel_j555
@manuel_j555 realmente me impresiona lo bien que manejas el componente de formularios. Yo soy incapaz de hacer nada avanzado con el :(
@javiereguiluz
En la empresa donde trabajo, la mayoría de formularios son bastante exigentes (eventos, campos opcionales dependientes, valores cargados en base a perfiles de usurio, etc), y nos ha tocado aprender a usar bien este componente :)
@manuel_j555
Muchas gracias. Sabía que se podía hacer. @Javier, y como decimos en mi tierra: la necesidad te lleva! :D
@cristian_angulo