Я знаю, что это общий вопрос, но я не могу понять, как этого добиться.
У меня есть сущность Course и сущность CourseDocument.
Course(id, documents, ...)
CourseDocument(id, file, course)
В моей форме курса:
class CourseType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, [
'label' => 'course.title',
])
->add('documents', CollectionType::class, array(
'entry_type' => MediaType::class,
'label' => 'course.documents_list',
'entry_options' => array(
'label' => false,
'data_class' => CourseDocument::class,
),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
}
В форме я хочу иметь возможность добавлять столько документов, сколько захочу. Я все настроил, включая javascript. Моя единственная проблема - это прототип данных, который мне не нужен.
{% import "macros/prototype.html.twig" as prototype %}
{{ form_start(form) }}
<div class = "row">
<div class = "col-md-6">
<fieldset class = "form-group">
{{ form_label(form.documents) }}
<div id = "course_documents" class = "collection_holder" data-prototype = "{{ prototype.tagCollectionItem(form.documents.vars.prototype)|e }}">
{% for widget in form.documents %}
{{ prototype.tagCollectionItem(widget) }}
{% endfor %}
</div>
<button type = "button" id = "add-document-btn" data-target-collection = "#{{ form.documents.vars.id }}" class = "btn btn-sm btn-info"><i class = "la la-plus"></i> {{ 'course.buttons.add_document' | trans({}, 'labels') }}</button>
</fieldset>
</div>
</div>
{{ form_end(form) }}
Я создаю свой прототип с помощью макроса:
{% macro tagCollectionItem(item) %}
<fieldset class = "form-group">
<div id = "{{ item.vars.id }}">
<div class = "custom-file">
{{ form_widget(item.uploadedFile) }}
{{ form_label(item.uploadedFile, item.uploadedFile.vars.label, {'label_attr': {'class': 'custom-file-label'}}) }}
</div>
</div>
</fieldset>
{% endmacro %}
Он работает довольно хорошо, за исключением редактирования. Мне не нужен ввод, если я уже выбрал файл. Но мне нужно имя файла.
^^ это. Я также хотел бы добавить, что вам следует иметь в виду эту ссылку, когда вы пытаетесь сформировать прототипы коллекции тем и сталкиваетесь с проблемами, определяющими имя поля формы, которое вы должны использовать: github.com/symfony/symfony-docs/issues/6056




Наконец-то я использовал макрос.
{% macro tagCollectionItem(item) %}
<fieldset class = "form-group">
<div id = "{{ item.vars.id }}">
{% if item.uploadedFile.vars.file_url or item.uploadedFile.vars.image_url %}
{{ form_errors(item.uploadedFile) }}
{{ form_widget(item.uploadedFile, {'attr': {'hidden': true}}) }}
{% else %}
<div class = "custom-file">
{{ form_widget(item.uploadedFile) }}
{{ form_label(item.uploadedFile, item.uploadedFile.vars.label, {'label_attr': {'class': 'custom-file-label'}}) }}
</div>
{% endif %}
</div>
</fieldset>
{% endmacro %}
Файл ветки для формы
<fieldset class = "form-group">
{{ form_label(form.documents) }}
<div id = "course_documents" class = "collection_holder" data-prototype = "{{ prototype.tagCollectionItem(form.documents.vars.prototype)|e }}">
{% for widget in form.documents.children %}
{{ prototype.tagCollectionItem(widget) }}
{% endfor %}
</div>
<button type = "button" id = "add-document-btn" data-target-collection = "#{{ form.documents.vars.id }}" class = "btn btn-sm btn-info"><i class = "la la-plus"></i> {{ 'course.buttons.add_document' | trans({}, 'labels') }}</button>
</fieldset>
Вы делаете это, переопределяя шаблон для этого конкретного поля коллекции. Как указано здесь: symfony.com/doc/current/form/…. Вы должны создать свой собственный файл макета формы, вы можете сделать это в том же файле ветки или в отдельном файле (если вы хотите использовать его повторно). И поверх вашего существующего файла ветки вы должны указать form_theme на этот файл или добавить его в свои темы форм в конфигурации фреймворка.