Создать один и тот же тип формы на одной странице несколько раз Symfony2

Я пытаюсь сгенерировать тип формы, в частности «ProductLanguageType».

Я хочу сгенерировать ProductLanguageType столько раз, сколько текущих чисел существующих языков в таблице Language.

Например, если у меня есть (английский, французский, русский, китайский) в таблице «Язык», на той же странице будет сгенерирована форма 4 ProductLanguageType.

Я хотел бы знать, как запросить таблицу языков и создать несколько форм одного типа на одной и той же странице, способен ли это сделать конструктор форм или есть другой обходной путь? В течение некоторого времени у нас были некоторые проблемы с этим, и мы были бы рады найти хорошее решение для этого.

ProductLanguageType:

class ProductLanguageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options){

$builder->add('id_language', 'entity', array(
'class' => 'AdminBundle:Language',
'data_class' => 'Main\AdminBundle\Entity\Language',
'property' => 'language'
)
)
->add('name', 'text')
->add('description', 'ckeditor', array(
'config_name' => 'admin',
'config' => array(
'filebrowser_image_browse_url' => array(
'route'            => 'elfinder',
'route_parameters' => array('instance' => 'default'),
),
)
))
->add('short_description', 'text');

}

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

ProductType (здесь указывается ProductLanguageType):

class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options){

$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
$builder->add('productLanguage', new ProductLanguageType())
->add('id_seller','text')
->add('price','text')
->add('cost_price','text')
->add('retail_price','text')
->add('hot', 'checkbox')
->add('featured', 'checkbox')
->add('new', 'checkbox')
->add('free_shipping', 'checkbox')
->add('status','text') //active or inactive, to be decided if hidden or visible
->add('Add', 'submit');

}
}

5

Решение

Надеюсь, это кому-нибудь поможет.

Надлежащим способом будет использование службы form.factory Symfony для создания именованного компоновщика и, в свою очередь, создания формы из этого. Я рекомендую создать функцию для процесса создания формы, так как (как я понимаю, исправьте меня, если я ошибаюсь) каждый экземпляр FormBuilder должен отличаться для создания другой формы.

Так же, как объяснение цели кода:
Мне нужно было показать список открытых заявок в справочной системе с возможностью назначения человека (авторизованного без входа в систему) на основе его токена для входа в заявку. Для этого необходимо отобразить N форм на одной странице, которые будут уникальными, но сгенерированы из одного «шаблона» или Type, если хотите.

Этот код достиг этого без каких-либо взломов. Просто не существует сокращенного метода createForm с определенным идентификатором (именем) из контроллера AFAIK.

ех.

public function generateFormForTicketAssignment(Ticket $ticket) {

$ticketAssignType = new TicketAssignInvokeType();
$ticketAssignType->setNameSuffix($ticket->getId());

/**
* @var Symfony\Component\Form\FormBuilderInterface
*/
$builder = $this->get('form.factory')->createNamedBuilder($ticketAssignType->getName(), $ticketAssignType );
$builder->setAutoinitialize(true);
$formTicket = $builder->getForm();

$formTicket->get('ticket')->setData($ticket);return $formTicket;
}

И (это важная часть) ticketAssignInvokeType выглядит следующим образом:

class TicketAssignInvokeType extends AbstractType {

private $nameSuffix = null;
private $name = 'ticket_assign_invoke';

public function __constructor(string $suffix = null)   {
//parent::__construct();

$this->nameSuffix = $this->generateNameSuffix();
}

private function generateNameSuffix() {
if ($this->nameSuffix == null ||  $this->nameSuffix == '') {
$generator = new SecureRandom();
//change data to alphanumeric string
return bin2hex($generator->nextBytes(10));
}

return $this->nameSuffix;
}

/**
*
* @param string $suffix When set suffix added to form will use selected
* string (note it should be unique for all forms on a page).
*/
public function setNameSuffix($suffix){
$this->nameSuffix = $suffix;
}

public function buildForm(FormBuilderInterface $builder, array $options)   {
$builder
->add('loginToken',new AuthenticateTokenType())
->add('ticket',new TicketIDType())
->add('save', 'submit', array('label' => 'form.button.assign'))
;

}

public function getName()    {
if ($this->nameSuffix == null || $this->nameSuffix == "" ) {
$this->nameSuffix = $this->generateNameSuffix();
}
return $this->name .'_'. $this->nameSuffix;
}

public function configureOptions(OptionsResolver $resolver)    {
// ...
}
}

Это несколько чрезмерно сложная логика и проверка суффикса имени, но в какой-то момент я не мог понять, почему все, что мне нужно — это имя формы без суффикса, отсюда и сложность.

PS. Я создал формы как сервисы и позже проверим, можно ли использовать сервис, а это было моим первым намерением.

PS2. Я не уверен насчет setAutoinitialize метода пока нет, но проверим и его.

5

Другие решения

Теперь в Symfony 3.0 они изменили createNamedBuilder, так что это можно решить, только вызвав:

use AppBundle\Form\ShippingTrackCodeReturnType;

$uniqueForm = $this->get('form.factory')->createNamedBuilder('ship_form_'.$orderRecord->getId(), ShippingTrackCodeReturnType::class, $orderRecord)->getForm();

Итак, вам просто нужно выполнить цикл для отображения и сохранения их:

foreach ($invoice->getOrderRecords() as $key => $orderRecord)
{
// creates the forms with different names
$returnShipTrackCodeForm = $this->get('form.factory')->createNamedBuilder('ship_form_'.$orderRecord->getId(), ShippingTrackCodeReturnType::class, $orderRecord)->getForm();

$returnShipTrackCodeForm->handleRequest($request);
if ($returnShipTrackCodeForm->isSubmitted() && $returnShipTrackCodeForm->isValid())
{
// flush object
}

$returnForms[$orderRecord->getId()] = $returnShipTrackCodeForm;
}
5

По вопросам рекламы [email protected]