2012-04-30 10 views
6

Estoy usando clases de formulario para compilar varias formas en mi proyecto.Symfony2 - ¿Cómo establecer y obtener opciones cuando se usa una clase de formulario?

En el archivo del tipo de entidad, para la función buildForm, hay un parámetro secundario de "array $ options" (esto se muestra en el funcionario Symfony 2 de documentación, pero nunca se ha mencionado, nunca!)

tengo alimenté una matriz en la función createForm en mi controlador pero ahora estoy totalmente perplejo sobre cómo recuperar los valores almacenados?

$form = $this->createForm(new ProductType(array(), array('id' => '2')), $product); 

La única cosa que he encontrado acerca de cómo obtener las opciones está utilizando la función getOption(), pero que no existe en Symfony 2 (el post que encontré fue a partir de 2010).

He intentado utilizar:

$id = $options['id']; 

Pero cuando trato de usar en cualquier lugar $ id, me sale el error:

Notice: Undefined index: id

Lo que da?

¿Cómo recupero mis valores de la matriz $ options? ¿Estoy incluso configurándolos correctamente en primer lugar?

EDITAR - Más código:

Clase Forma

<?php 

namespace DEMO\DemoBundle\Form\Product; 

use Doctrine\ORM\EntityRepository; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 

class ProductType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('name') 
      ->add('slug') 
      ->add('reference') 
      ->add('description') 
      ->add('active_from') 
      ->add('active_till') 
      ->add('is_active') 
      ->add('category', 'entity', array(
       'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 
       'query_builder' => function(EntityRepository $er) { 
        return $er->createQueryBuilder('u') 
         ->where('u.section = :id') 
         ->setParameter('id', ***ID VARIABLE NEEDS TO GO HERE***) 
         ->orderBy('u.root', 'ASC') 
         ->addOrderBy('u.lft', 'ASC'); 
       }, 
       'empty_value' => 'Choose an option', 
       'property' => 'indentedName', 
      )); 
    } 

    public function getDefaultOptions() 
    { 
     return array(
      'data_class' => 'DEMO\DemoBundle\Entity\Product\Product' 
     ); 
    } 

    public function getName() 
    { 
     return 'demo_demobundle_product_type'; 
    } 
} 

Respuesta

1

Bueno, a su vez s out, la respuesta de Gregoires estuvo muy cerca, pero me dio un error de "variable indefinida" al tratar de realmente pero la variable en la función createQueryBuilder.

Pasé un tiempo tratando de descubrir por qué y encontré el problema. Usted tiene que agregar un parámetro adicional para la función en la opción "query_builder", como por ejemplo:

'query_builder' => function(EntityRepository $er) use ($options) { 
        return $er->createQueryBuilder('u') 
         ->where('u.section = :id') 
         ->setParameter('id', $options['id']) 
         ->orderBy('u.root', 'ASC') 
         ->addOrderBy('u.lft', 'ASC'); 
       }, 

El ajuste magic "uso ($ options)". Esto le permite usar $ options ['id'] con éxito en Query Builder.

+0

esa fue mi respuesta no greg0ires ... – Flukey

+0

Lo siento, en realidad está implementado con la respuesta greg0ires, he copiado el código incorrectamente. Editado para borrarlo –

+0

ok :) gracias por aclararlo – Flukey

16

creo que no se está configurando de manera adecuada en el primer lugar. Se supone que tienes que darles como tercer argumento para createForm()

EDIT: Aquí es cómo su clase de formulario podía mirar:

<?php 
namespace DEMO\DemoBundle\Form\Product; 

use Doctrine\ORM\EntityRepository; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 

class ProductType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('name') 
      ->add('slug') 
      ->add('reference') 
      ->add('description') 
      ->add('active_from') 
      ->add('active_till') 
      ->add('is_active') 
      ->add('category', 'entity', array(
       'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 
       'query_builder' => function(EntityRepository $er) use($options) { 
        return $er->createQueryBuilder('u') 
         ->where('u.section = :id') 
         ->setParameter('id', $options['id']) 
         ->orderBy('u.root', 'ASC') 
         ->addOrderBy('u.lft', 'ASC'); 
       }, 
       'empty_value' => 'Choose an option', 
       'property' => 'indentedName', 
      )); 
    } 

    public function getDefaultOptions() 
    { 
     return array(
      'data_class' => 'DEMO\DemoBundle\Entity\Product\Product', 
      'id'   => null 
     ); 
    } 

    public function getName() 
    { 
     return 'demo_demobundle_product_type'; 
    } 
} 
+1

I cree que la tercera opción para createForm() es establecer opciones como las siguientes: "attr", "by_reference", "cascade_validation", "csrf_field_name", "csrf_protection", "csrf_provider", "data", "data_class", "disabled", "empty_data", "error_bubbling", "error_delay", "error_mapping", "error_type", "field_error_type", "help_block" "," help_inline ", etc, etc. (básicamente, lo intenté, y dice" La opción "id" no existe. ") –

+0

Puede adaptar el método getDefaultOptions() de su clase de formulario para informar su formulario sobre esta opción y evitar este mensaje. – greg0ire

+1

Tbh, realmente no quiero "piratear" ninguna de las estructuras principales. La función buildForm() claramente tiene un parámetro secundario para establecer una matriz de opciones. Quiero saber cómo se utiliza correctamente. –

1

pasar las opciones a través de las formas método de clase __construct, así:

use Doctrine\ORM\EntityRepository; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 

class ProductType extends AbstractType 
{ 

    private $options = array(); 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('name') 
      ->add('slug') 
      ->add('reference') 
      ->add('description') 
      ->add('active_from') 
      ->add('active_till') 
      ->add('is_active') 
      ->add('category', 'entity', array(
       'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 
       'query_builder' => function(EntityRepository $er) { 
        return $er->createQueryBuilder('u') 
         ->where('u.section = :id') 
         ->setParameter('id', $this->options['id']) 
         ->orderBy('u.root', 'ASC') 
         ->addOrderBy('u.lft', 'ASC'); 
       }, 
       'empty_value' => 'Choose an option', 
       'property' => 'indentedName', 
      )); 
    } 

    public function getDefaultOptions() 
    { 
     return array(
      'data_class' => 'DEMO\DemoBundle\Entity\Product\Product' 
     ); 
    } 

    public function getName() 
    { 
     return 'demo_demobundle_product_type'; 
    } 

    public function __construct(array $options) 
    { 
     $this->options = $options; 
    } 
} 

Y entonces usted puede hacer:

new ProductType(array('id'=>1)); 
+0

Intenté este método y terminé con un error de" variable no definida ". Lo copié exactamente, así que no puedo entender por qué me da ese error, ya que, en lo que a mí respecta, la variable IS se está configurando ... –

+1

agregando "use ($ this)" probablemente sea el truco – greg0ire

+0

Jaja, sí , ya lo descubrí hace unos días, mira mi respuesta :) ¡Gracias por la ayuda! –

5

Pues según esta Google Groups

"greg0ire" estaba bien, de hecho yo he probado y funciona perfecto !!!. Dijiste "No quiero" piratear "ninguna de las estructuras principales" pero terminas usando el mejor enfoque ... de hecho, desde mi punto de vista, terminas haciendo lo que no hiciste quiero hacer.

Así que al final usted debe hacer esto:

en el formType

public function buildForm(FormBuilder $builder, array $options) 
{ 
    $builder 
     ->add('name') 
     ->add('slug') 
     ->add('reference') 
     ->add('description') 
     ->add('active_from') 
     ->add('active_till') 
     ->add('is_active') 
     ->add('category', 'entity', array(
      'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 
      'query_builder' => function(EntityRepository $er) { 
       return $er->createQueryBuilder('u') 
        ->where('u.section = :id') 
        ->setParameter('id', $options['id']) 
        ->orderBy('u.root', 'ASC') 
        ->addOrderBy('u.lft', 'ASC'); 
      }, 
      'empty_value' => 'Choose an option', 
      'property' => 'indentedName', 
     )); 
} 

public function getDefaultOptions() 
{ 
    return array(
     'data_class' => 'DEMO\DemoBundle\Entity\Product\Product' 
     'id' => null 
    ); 
} 

Y en el controlador

$form = $this->createForm(new ProductType(), $product, array('id' => $id)); 
7

Déjame mostrarte lo que funcionó para mí

En el controlador:

$form = $this->createForm(new UsersType(), $entity, array(
    'attr' => array('locationId' => $currentLocationId))); 

En el FormType:

->add('location', 'entity', array(
     'class' => 'Ro\RoinventBundle\Entity\Locations', 
     'query_builder' => function (\Doctrine\ORM\EntityRepository $er) use ($options) 
     { 
      if (isset($options['attr']['locationId']) && ($options['attr']['locationId'] != NULL)) 
      { 
       return $er->createQueryBuilder('Locations') 
        ->where('Locations.id = :param') 
        ->setParameter('param', $options['attr']['locationId']); 
      } 
      //else do what you want 
}, 
)); 
7

Al parecer no es con getDefaultOptions() más, pero con setDefaultOptions().

De lo contrario, dice

The option "my_custom_option" does not exist. Known options are: "action", "attr", "auto_initialize", ...

tanto, para mí que tenía que actualizar setDefaultOptions como este:

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array('my_custom_option' => false)); 
    // Others if needed, like in the documentation for : 'data_class' => 'VENDOR\Bundle\Entity\MyEntity', 'csrf_protection' => true 
} 

Y luego se puede recuperar en el método buildForm

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $myCustomOption = $options['my_custom_option']; 
} 
Cuestiones relacionadas