Несколько форм одного типа - Symfony 2

Итак, у меня есть действие моего контроллера, подобное этому

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

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

И скажем, у моей MyForm есть два поля

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

Похоже, что поскольку две формы имеют один и тот же тип MyForm, при отображении в представлениях их поля имеют одинаковое имя и идентификаторы (поля 'name' двух форм имеют одно и то же имя и идентификатор; то же самое касается ' note 'fields), из-за чего Symfony может некорректно связывать данные форм. Кто-нибудь знает какое-либо решение этого?


person 0x56794E    schedule 12.05.2012    source источник


Ответы (4)


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

теперь вы должны иметь возможность устанавливать разные идентификаторы для каждого экземпляра формы, которую вы собираете ... это должно привести к <input type="text" id="foobar_field_0" name="foobar[field]" required="required> и так далее.

person Flask    schedule 12.05.2012
comment
Собственно моя мысль. Отличный ответ! - person Jovan Perovic; 13.05.2012
comment
Обновление для Symfony 4: getName устарело и удалено, теперь следует использовать getBlockPrefix (github.com/symfony/symfony/blob/3.3/UPGRADE-3.0.md#form) - person Full; 22.10.2020

Я бы использовал статику для создания имени

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

Затем вы можете создать столько, сколько захотите, без необходимости каждый раз устанавливать имя.

person Stéphan Champagne    schedule 11.09.2013
comment
Это лучший ответ. - person Stan; 21.01.2015
comment
Хороший ответ, спасибо. Но мне интересно, может ли он правильно масштабироваться с большим количеством пользователей? - person Thomas Leduc; 08.02.2015
comment
@ThomasLeduc Очень маловероятно, что количество пользователей будет проблемой с таким шаблоном. Переменная $ count будет инициализирована только один раз за запрос и увеличиваться столько раз, сколько вы создали форму за один запрос. Даже если бы у вас были тысячи форм, переменная не должна быть проблемой (но тогда, я думаю, у вас были бы другие проблемы) - person Julien; 26.04.2016

РЕДАКТИРОВАТЬ: не делайте этого! См. Вместо этого: http://stackoverflow.com/a/36557060/6268862

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

Теперь первый экземпляр формы на странице будет иметь имя my_custom_form_0 (то же самое для имен и идентификаторов полей), второй - my_custom_form_1, ...

person peamak    schedule 09.05.2016
comment
Я должен отметить, что это, вероятно, лучшая идея, потому что, когда вы отправите свою форму, счетчик будет инициализирован, и, следовательно, форма не будет фактически отправлена ​​(разница между именем формы и данными в запрос). Вместо этого следует использовать метод createNamedBuilder, как описано здесь: stackoverflow.com/a/36557060/6268862 - person peamak; 11.05.2016
comment
в Symfony3 конструктор больше не разрешен в formtype - person Zwen2012; 24.11.2016

создать единое динамическое имя:

const NAME = "your_name";

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

твое имя всегда холост

person Snoozer    schedule 13.10.2015