Symfony 2 Поле сбора форм с типом файла
Я хочу загрузить несколько файлов с запросом POST (без Ajax). Могу ли я использовать поле коллекции форм Symfony 2 с типом файла следующим образом:
Код в сущности:
public $pictures;
public function __construct()
{
$this->pictures = new \Doctrine\Common\Collections\ArrayCollection();
}
Код в классе формы:
$builder->add('pictures', 'collection', array(
'type' => 'file',
'required' => false,
'attr' => array(
'multiple' => 'multiple'
)
));
Код в Twig:
{% for picture in form.pictures %}
<td>
{{ form_widget(picture) }}
</td>
{% endfor %}
Я пробовал, но он, похоже, не работает. Он не показывает никаких ошибок, но также не показывает входной файл. Любые идеи?
Ответы
Ответ 1
Чтобы реально создавать типы ввода, вам нужно установить значение allow_add в коллекции true и использовать прототип формы коллекции, javascript и кнопку для добавления полей файлов.
Пример, основанный на документации (Добавление и удаление коллекции)
Форма:
<form action="..." method="POST" {{ form_enctype(form) }}>
{# ... #}
{# store the prototype on the data-prototype attribute #}
<ul id="image-container" class="collection-container" data-prototype="{{ form_widget(form.images.vars.prototype) | e }}">
{% for imageField in form.images%}
<li>
{{ form_widget(imageField) }}
</li>
{% endfor %}
</ul>
<a href="#" class="collection-add" data-collection="image-container">Add image</a>
</form>
script:
<script type="text/javascript">
var imageCount;
jQuery(document).ready(function() {
$(document).on('click', '.collection-add', function () {
var $collectionContainer = $('#' + $(this).data('collection'));
if(!imageCount){imageCount = $collectionContainer.children().length;}
var prototype = $collectionContainer.attr('data-prototype');
var item = prototype.replace(/__name__/g, imageCount);
$collectionContainer.append(item);
imageCount++;
});
})
</script>
Это просто идея, в зависимости от ваших потребностей есть еще много дел.
Если это не то, что вы искали, возможно, вы могли бы вызвать кнопку "Добавить" в качестве обходного пути.
Ответ 2
Если вы хотите показать несколько полей ввода, нет, это не сработает. Тип коллекции требует, чтобы вы предоставили некоторые данные перед рендерингом полей. Я уже пробовал это и придумал создание отдельного объекта (например, File) и добавление отношения к моей целевой сущности.
Пример:
class File
{
// properties
public $file; // this holds an UploadedFile object
// getters, setters
}
FileType:
....
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', 'file', [
'required' => false
])
;
}
Продукт:
class Product
{
// properties
private $images; // ManyToMany relationship
// setters, getters
}
ProductType:
->add('images', 'collection', [
'type' => 'YOUR_FILE_TYPE_NAME',
'by_reference' => false,
'required' => false
])
Концеллер продукта:
public function someAction()
{
...
$image = new File();
$product->addImage($image);
}
Я знаю, что это решение может быть излишним и создает дополнительные таблицы, но оно работает.
Ответ 3
Вам нужно указать тип виджета в коллекции
Посмотрите на: http://symfony.com/doc/2.0/reference/forms/types/collection.html
$builder->add('pictures', 'collection', array(
// each item in the array will be an "email" field
'type' => 'file',
// these options are passed to each "email" type
'options' => array(
'required' => false,
),
));
Для дальнейшего чтения я предлагаю
http://symfony.com/doc/2.0/reference/forms/types/file.html
Также вам нужно добавить sth в эту коллекцию, чтобы отобразить, потому что она будет пустой при инициализации, как в вашем конструкторе объекта.
Ответ 4
Код в классе формы правильный, но вы также должны изменить имя поля формы. full_name
должен быть form[pictures][]
в вашем случае.
На самом деле кажется, что изменение имени поля формы больше невозможно в sf2.3, но это снова возможно в sf2.4.
https://github.com/bamarni/symfony/commit/35639824e864ed8d4a4cc0d8360f2c73ae08b507#commitcomment-3627879