简体   繁体   English

Symfony 2表单集合字段,带有类型文件

[英]Symfony 2 Form collection field with type file

I want to upload multiple files with POST request (without Ajax). 我想用POST请求上传多个文件(没有Ajax)。 Can I use Symfony 2's form collection field with type file like this: 我可以将Symfony 2的表单集合字段与类型文件一起使用,如下所示:

Code in Entity: 实体代码:

public $pictures;

public function __construct()
{
    $this->pictures = new \Doctrine\Common\Collections\ArrayCollection();
}

Code in Form Class: 表格类代码:

$builder->add('pictures', 'collection', array(
        'type' => 'file',
        'required' => false,
        'attr' => array(
            'multiple' => 'multiple'
        )
));

Code in Twig: Twig中的代码:

{% for picture in form.pictures %}
    <td>
        {{ form_widget(picture) }}
    </td>
{% endfor %}

I tried, but it doesn't seem to work. 我试过了,但似乎没有用。 It is not showing any errors, but it is not showing the input file either. 它没有显示任何错误,但它也没有显示输入文件。 Any ideas? 有任何想法吗?

To actually render input types you will need to set the allow_add option in the collection to true and use the form prototype of the collection, javascript and a button to add file fields. 要实际呈现输入类型,您需要将集合中的allow_add选项设置为true,并使用集合的表单原型,javascript和按钮来添加文件字段。

An example based in the documentation ( Collection- adding and removing ) 基于文档的示例( 集合 - 添加和删除

The form: 表格:

<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>

The 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>

This is just an idea, there is still plenty to do depending on your needs. 这只是一个想法,根据您的需要还有很多工作要做。 If this wasn't what you were looking for, maybe you could call the add button click as a workaround. 如果这不是您想要的,也许您可​​以调用添加按钮单击作为解决方法。

If you want to show multiple input fields, no, it won't work. 如果要显示多个输入字段,则不起作用。 A collection type requires you to supply some data before rendering the fields. 集合类型要求您在渲染字段之前提供一些数据。 I've already tried it, and came up creating a separate entity (eg File) and and adding relationship to my target entity. 我已经尝试过,然后创建了一个单独的实体(例如File)并添加了与我的目标实体的关系。

example: 例:

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
        ])
    ;
}

Product: 产品:

class Product
{
    // properties

    private $images; // ManyToMany relationship

    // setters, getters
}

ProductType: 产品类别:

->add('images', 'collection', [
    'type' => 'YOUR_FILE_TYPE_NAME',
    'by_reference' => false,
    'required' => false
])

Product contoller: 产品控制器:

public function someAction()
{
    ...

    $image = new File();
    $product->addImage($image);

}

I know this solution can be overkill and creates extra tables, but it works. 我知道这个解决方案可能会过度使用并创建额外的表,但它可以工作。

You need to specify the type of the widget in collection 您需要在集合中指定窗口小部件的类型

Look at the: http://symfony.com/doc/2.0/reference/forms/types/collection.html 请查看: 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,
  ),
));

For further reading I suggest 为了进一步阅读,我建议

http://symfony.com/doc/2.0/reference/forms/types/file.html http://symfony.com/doc/2.0/reference/forms/types/file.html

Also you need to add sth to this collection to display cuz it will be empty when initialize like in your constructor of entity. 此外,你需要添加sth到这个集合来显示cuz它在初始化时将是空的,就像你的实体的构造函数。

The code in the form class is correct, but you also should modify the name of the formfield. 表单类中的代码是正确的,但您还应该修改表单域的名称。 The full_name should be form[pictures][] in your case. 在您的情况下, full_name应该是form[pictures][]的形式。

It actually seems that modifying a form field name is not possible anymore in sf2.3, but it will be possible in sf2.4 again. 实际上似乎在sf2.3中不再可以修改表单字段名称,但是在sf2.4中它将是可能的。

https://github.com/bamarni/symfony/commit/35639824e864ed8d4a4cc0d8360f2c73ae08b507#commitcomment-3627879 https://github.com/bamarni/symfony/commit/35639824e864ed8d4a4cc0d8360f2c73ae08b507#commitcomment-3627879

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM