2012-05-12 49 views
11

Więc mam działania kontrolera podobną do tejWiele form tego samego typu - Symfony 2

$task1 = new Task(); 
$form1 = $this->createForm(new MyForm(), $task1); 

$task2 = new Task(); 
$form2 = $this->createForm(new MyForm(), $task2); 

I powiedzmy, moja MyForm ma dwa pola

//... 
$builder->add('name', 'text'); 
$builder->add('note', 'text'); 
//... 

Wydaje się, gdyż obie formy są tego samego typu MyForm, gdy są renderowane w widokach, ich pola mają tę samą nazwę i identyfikatory (pola "nazwa" dwóch formularzy mają tę samą nazwę i id; to samo dotyczy pól "Uwaga", z powodu których Symfony może nie poprawnie wiązać danych formularzy. Czy ktoś wie, jakie to rozwiązanie?

Odpowiedz

18
// your form type 
class myType extends AbstractType 
{ 
    private $name = 'default_name'; 
    ... 
    //builder and so on 
    ... 
    public function getName(){ 
     return $this->name; 
    } 

    public function setName($name){ 
     $this->name = $name; 
    } 

    // or alternativ you can set it via constructor (warning this is only a guess) 

    public function __constructor($formname) 
    { 
     $this->name = $formname; 
     parent::__construct(); 
    } 

}

// you controller 

$entity = new Entity(); 
$request = $this->getRequest(); 

$formType = new myType(); 
$formType->setName('foobar'); 
// or new myType('foobar'); if you set it in the constructor 

$form = $this->createForm($formtype, $entity); 

teraz powinno być możliwe, aby ustawić inny identyfikator dla każdej instancji formularz paka .. to powinno skutkować <input type="text" id="foobar_field_0" name="foobar[field]" required="required> i tak dalej.

+0

Dokładnie moja myśl. Świetna odpowiedź! –

7

użyłbym statycznego, aby utworzyć nazwę

// your form type 

    class myType extends AbstractType 
    { 
     private static $count = 0; 
     private $suffix; 
     public function __construct() { 
      $this->suffix = self::$count++; 
     } 
     ... 
     public function getName() { 
      return 'your_form_'.$this->suffix; 
     } 
    } 

Następnie można utworzyć tyle, ile chcesz, bez konieczności ustawić nazwę razem.

+1

To jest najlepsza odpowiedź. – Stan

+0

To dobra odpowiedź, thx. Ale zastanawiam się, czy można skalować poprawnie z dużą liczbą użytkowników? –

+0

@ThomasLeduc Jest bardzo mało prawdopodobne, że liczba użytkowników będzie miała problem z tego rodzaju wzorcem. Zmienna $ count zostanie zainicjalizowana tylko raz na żądanie i zwiększana tyle razy, ile masz formularza utworzonego w jednym żądaniu. Nawet gdybyś miał tysiące formularzy, zmienna nie powinna stanowić problemu (ale wtedy pojawiłyby się inne problemy). – Julien

0

utworzyć jeden dynamicznej nazwy:

const NAME = "your_name"; 

public function getName() 
{ 
    return self::NAME . '_' . uniqid(); 
} 

nazwa jest zawsze pojedynczy

3

EDIT: Nie rób tego! Zobacz to zamiast: http://stackoverflow.com/a/36557060/6268862

w Symfony 3.0:

class MyCustomFormType extends AbstractType 
{ 
    private $formCount; 

    public function __construct() 
    { 
     $this->formCount = 0; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     ++$this->formCount; 
     // Build your form... 
    } 

    public function getBlockPrefix() 
    { 
     return parent::getBlockPrefix().'_'.$this->formCount; 
    } 
} 

Teraz pierwsza instancja formularza na stronie będzie miał „my_custom_form_0” jak sama nazwa (sam nazw Fields' i identyfikatory), przy czym drugi "my_custom_form_1", ​​...

+0

Muszę zauważyć, że jest to prawdopodobnie najlepszy pomysł, ponieważ po przesłaniu formularza, liczba zostanie zainicjowana, a zatem formularz ** nie ** zostanie faktycznie przesłany (różnica między nazwą formularza a danymi w żądaniu). Zamiast tego należy użyć metody createNamedBuilder, jak wyjaśniono tutaj: http://stackoverflow.com/a/36557060/6268862 – peamak

+0

w Symfony3, konstruktor nie jest już dozwolony w formularzu – Zwen2012

+0

createNamedBuilder również dla mnie pracował – Sam

Powiązane problemy