2012-07-23 17 views
17

La mia domanda è fondamentalmente, è possibile modificare un'opzione di un campo di un incorporato per il modulo padre?Symfony2 cambia le opzioni di campo di un modulo incorporato

Per illustrare il problema, considerare questo; Ho una classe genitore tipo di modulo come questo:

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

e un tipo di classe form figlio che si trova in un fascio separato e io preferirei non modificare, in questo modo:

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

e voglio per cambiare l'etichetta di qty in qualcos'altro, ma voglio farlo solo nello FruitForm, non ovunque sia utilizzato lo AppleForm. Avevo sperato di essere in grado di fare qualcosa di simile:

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'); 
    } 

ma nessuno di questi (e una serie di altri tentativi) hanno tutti mi fallito. Non esiste un metodo setOption che riesco a vedere.

Qualcuno sa di un modo per farlo?

Grazie

risposta

35

Volevo anche modificare le opzioni, il caso ovvio "modificare l'etichetta" per un campo esistente da il FOSUserBundle. So che potrei farlo in Twig o con le traduzioni.

@redbirdo mi ha indirizzato nella giusta direzione con "sembra che l'aggiunta di un campo con lo stesso nome lo sostituirà". Ecco la soluzione:

$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

$ opzione s = $ field-> getOptions(); non ha funzionato per me, tuttavia, $ field-> getConfig() -> getOptions() ha fatto il trucco! Grazie ancora ! – Steven

+0

Non funziona per me –

+0

Ha funzionato bene per me. @Steven devi usare '$ form-> get (" field ") -> getOptions()', o il campo con quel nome non esiste ancora. – Adambean

8

provare qualcosa di simile:

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'; 
     ); 
    } 
} 

e:

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

Grazie per la risposta, so che questa è un'opzione, ma poiché 'AppleFormType' è in un bundle di fornitori dovrei eseguire l'override o la sostituzione per farlo funzionare. Speravo in una soluzione che potesse essere fatta interamente nella classe 'FruitFormType'. – lopsided

+1

Scusa, ho visto che preferiresti non modificarlo, ma supponevo che avresti dovuto ignorarlo. Qualcosa come $ builder-> get ('apple') -> add ('qty', 'integer', array ('label' => 'better label') può essere un'opzione? Dalla lettura della documentazione (2.0) di FormBuilder sembra che l'aggiunta di un campo con lo stesso nome lo sostituirà ma ovviamente dovresti ridefinire tutte le opzioni, non solo l'etichetta ... – redbirdo

+0

MODIFICATO - Ho trovato l'API per FormBuilderInterface. Ha get/setAttribute(). Hai provato a usare $ builder-> get ('apple') -> get ('qty') -> setAttribute ('label', 'better label') ;? – redbirdo

3

Sono in un caso in cui non posso accedere al codice del modulo costruttore, ma devono ignorare alcune opzioni di campo per aggiungere un 'required' => true.

Espandendo @ peter-wooster e @thedamnedrhino rispondiamo a un problema di symfony su github (https://github.com/symfony/symfony/issues/11188), finisco con questo pezzo di codice.

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

Questo funziona bene con symfony/symfony: 2.3.21, la dottrina/doctrine-bundle: 1.2.0 e la dottrina/orm: 2.3.6

0

Modifica la vista è spesso molto più facile per questo tipo di cambiamento.

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

Tipicamente la visualizzazione sarà un form padre, quindi potrebbe assomigliare a questo - cambiamento da 'Data'> 'Data di pubblicazione':

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

Se il modulo è incapsulato nel suo proprio tipo è possibile utilizzare la funzione di finishView:

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

Poiché la maggior parte di ciò che è finalmente passato al motore di template per il rendering è in forma di matrice dritto, si può pasticciare con un bel po 'di cose a questo punto.

+0

Nota questa modifica si applica solo nella vista "corrente". Questo non cambia la forma da cui è stata costruita la vista. Ma mi aspetto che questa soluzione soddisfi molti casi d'uso. – Henry

8

Grazie mille a @Peter Wooster. In Symfony 3.0, ho dovuto usare qualcosa di un po 'diverso:

Ho un tipo di modulo personalizzato aggiunta di campi in questo modo:

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

E in un altro tipo di modulo personalizzato che ho bisogno di estendere il tipo di cui sopra e modificare alcune opzioni:

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); 
} 

Grazie alle risposte di cui sopra, spero che la mia aiuta!

Problemi correlati