#php #symfony #symfony-forms
Вопрос:
В форме Symfony для типа коллекции с add
опцией есть ли способ дважды отобразить прототип? Или чистый (см. Ниже) способ задать полный путь к полям в представлении формы, чтобы я мог дважды отобразить строку прототипа с соответствующими ключами и __name__
заполнителем.
Пример использования:
У меня есть коллекция предметов нескольких типов (т. е. видео слайд, текстовый слайд и т.д.), разделяющие один и тот же тип, но сильно различающиеся в представлении HTML-формы. Поэтому у меня есть отдельные кнопки «Добавить xxxx» для добавления новых полей определенных типов (добавить текстовый слайд, добавить видео слайд и т. Д.), Связывающие отдельные строки прототипа. Проблема в том, что когда я пытаюсь использовать общий прототип в качестве источника визуализации, я не могу отобразить одно и то же поле дважды, поэтому на второй кнопке строка прототипа содержит только поля, не отображенные для первого.
Опробованные решения:
Я попытался вручную установить full_name для полей, но я не знаю чистого, не взломанного способа сделать это (я знаю, что могу установить blockPrefix, но этого недостаточно).
Самый простой способ сделать это-создать новое представление формы и поменять местами ключи вот так. Это работает, но смешно:
// EDIT: For nested fields (eg. radio buttons) you need to make
// the swap recursive, hence copyFields method was added.
// ALSO: I know it's not generalized in any way but it's a hack
// and I hope to get rid of it. ;-)
private function getTimelinePrototypes(FormView $sourceFormView, int $num) {
/** @var FormView */
$timelinesFormView = $sourceFormView->children['timelines'];
/** @var FormView */
$tlProto = $timelinesFormView->vars['prototype'];
$protoForms = [];
// GET FORM VIEWS FOR MULTI PROTOYPES:
for ($i = 0; $i < $num; $i ) {
$targetForm = $this->createForm(TimelineType::class, null, [])->createView();
$this->copyFields($tlProto, $targetForm);
$protoForms[] = $targetForm;
}
return $protoForms;
}
private function copyFields (FormView $sourceForm, FormView $targetForm) {
foreach($targetForm->children as $fieldKey => $targetField) {
$sourceField = $sourceForm->children[$fieldKey];
foreach(['full_name', 'id', 'name', 'cache_key', 'unique_block_prefix', 'block_prefixes', ] as $key) {
$targetField->vars[$key] = $sourceField->vars[$key];
}
if (count($sourceField->children) > 0) {
$this->copyFields($sourceField, $targetField);
}
}
}