2012-07-23 13 views
17

Mi pregunta básicamente es, ¿es posible cambiar una opción de un campo de un incrustado desde el formulario principal?Opciones de campo de cambio de Symfony2 de un formulario incrustado

Para ilustrar el problema, considere esto; Tengo una clase formulario primario tipo así:

class FruitFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', 'text') 
      ->add('apple', new AppleFormType()) 
     ; 
    } 

y una clase de tipo de formulario secundario que está en un paquete separado y yo preferiría no editar, así:

class AppleFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', 'text') 
      ->add('qty', 'integer', array('label' => 'rubbish label') 
     ; 
    } 

y quiero para cambiar la etiqueta de qty a otra cosa, pero quiero hacerlo solo en el FruitForm, no en todas partes donde se usa AppleForm. Tenía la esperanza de ser capaz de hacer algo como:

class FruitFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', 'text') 
      ->add('apple', new AppleFormType(), array('qty' => array('label' => 'better label'))) 
     ; 
    } 

o:

class FruitFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', 'text') 
      ->add('apple', new AppleFormType()) 
     ; 

     $builder->get('apple')->get('qty')->setOption('label', 'better label'); 
    } 

pero ninguno de estos (y un número de otros intentos) todos me han fallado. No existe un método setOption que pueda ver.

¿Alguien sabe de una manera de hacer esto?

Gracias

Respuesta

35

También quería cambiar las opciones, lo obvio "cambiar la etiqueta de" caso de un campo existente de el FOSUserBundle. Sé que podría hacer esto en Twig o con traducciones.

@redbirdo me apuntó en la dirección correcta con "parece que agregar un campo con el mismo nombre lo reemplazará". Aquí está la solución:

$field = $builder->get('username');   // get the field 
$options = $field->getOptions();   // get the options 
$type = $field->getType()->getName();  // get the name of the type 
$options['label'] = "Login Name";   // change the label 
$builder->add('username', $type, $options); // replace the field 
+7

$ option s = $ campo-> getOptions(); no funcionó para mí, sin embargo, $ field-> getConfig() -> getOptions() hizo el truco! Gracias de nuevo ! – Steven

+0

No funciona para mí –

+0

Funcionó bien para mí. @Steven necesita usar '$ form-> get (" campo ") -> getOptions()', o el campo con ese nombre aún no existe. – Adambean

8

intentar algo como esto:

class AppleFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', 'text') 
      ->add('qty', 'integer', array('label' => $options['qtyLabel']) 
     ; 
    } 

    public function getDefaultOptions() 
    { 
     return array(
      'qtyLabel' = 'rubbish label'; 
     ); 
    } 
} 

y:

class FruitFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', 'text') 
      ->add('apple', new AppleFormType(), array('qtyLabel' => 'better label')) 
     ; 
    } 
} 
+0

Gracias por la respuesta, sé que esta es una opción, pero como el 'AppleFormType' está en un paquete de proveedor, tendría que anularlo o reemplazarlo para que funcione. Esperaba una solución que podría hacerse completamente en la clase 'FruitFormType'. – lopsided

+1

Lo siento, vi que preferiría no editarlo, pero asumió que estaría bien con anularlo. ¿Algo así como $ builder-> get ('apple') -> add ('qty', 'integer', array ('label' => 'better label') será una opción? Por leer la documentación (2.0) de FormBuilder parece que agregar un campo con el mismo nombre lo reemplazará, pero obviamente tendrías que redefinir todas las opciones, no solo la etiqueta ... – redbirdo

+0

EDITADO - Encontré la API para FormBuilderInterface. Tiene get/setAttribute(). ¿Has probado usando $ builder-> get ('apple') -> get ('qty') -> setAttribute ('etiqueta', 'mejor etiqueta') ;? – redbirdo

3

estoy en un caso en el que no puedo acceder al código constructor de la forma, pero tienen que reemplazar a las opciones de campo para añadir un 'required' => true.

Expandiendo @ peter-wooster y @thedamnedrhino responden a un problema de symfony en github (https://github.com/symfony/symfony/issues/11188), termino con este fragmento de código.

$field = $form->get('combinaisons'); 
$options = $field->getConfig()->getOptions(); 
$type = $field->getConfig()->getType()->getName(); 
$options['required'] = true; 
unset($options['em']); 
$form->add('combinaisons', $type, $options); 

Esto funciona bien con symfony/symfony: 2.3.21, la doctrina/doctrina de haz: 1.2.0 y la doctrina/ORM: 2.3.6

0

Modificación de la vista es a menudo mucho más fácil para este tipo de cambio

$view->vars['label'] = 'New label'; 

Normalmente la vista habrá un formulario principal, por lo que podría tener este aspecto - el cambio de 'Fecha'> 'Fecha de publicación':

$view = $form->createView(...); 
$view->children['date']->vars['label'] = 'Publication date'; 

Si su formulario se encapsula en su propio tipo puede utilizar la función finishView:

public function finishView(FormView $view, FormInterface $form, array $options) 
{ 
    $view->children['date']->vars['label'] = 'Publication date'; 
} 

Dado que la mayoría de lo que se aprobó finalmente en el motor de plantillas para la representación es en forma array lineal, que puede meterse con un buen montón de cosas en este punto.

+0

Tenga en cuenta que este cambio solo se aplicará en la vista 'actual'. Esto no cambia la forma desde la que se construyó la vista. Pero espero que esta solución se adapte a muchos casos de uso. – Henry

8

Muchas gracias a @Peter Wooster. En Symfony 3.0, tuve que usar algo un poco diferente:

tengo un tipo de formulario personalizado añadiendo campos de este modo:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('my_field', ChoiceType::class, [ 
     // Some options here... 
     'multiple' => false, 
    ]); 
} 

Y en otro tipo de formulario a medida que necesito extienden el Tipo arriba y cambie algunas opciones:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    parent::buildForm($builder, $options); 

    $myField = $builder->get('my_field'); 
    $fieldOptions = $myField->getOptions(); 
    // Retrieve the FormType. That is the part that is different. 
    $fieldType = get_class($myField->getType()->getInnerType()); 
    $fieldOptions['multiple'] = true; 
    // I can obviously put the name 'my_field' directly here 
    $builder->add($myField->getName(), $fieldType, $fieldOptions); 
} 

Gracias a las respuestas anteriores, ¡espero que la mía ayude!

Cuestiones relacionadas