2012-09-13 90 views
16

我想用POST請求(無Ajax)上傳多個文件。我可以使用的Symfony 2的形式收集場類型的文件是這樣的:Symfony 2與類型文件的表單集合字段

代碼在實體:

public $pictures; 

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

代碼在Form類:

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

代碼在枝杈:

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

我試過了,但它似乎沒有工作。它沒有顯示任何錯誤,但它也沒有顯示輸入文件。有任何想法嗎?

回答

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

還需要添加對這個集合顯示cuz它將在初始化時像在實體的構造函數中一樣是空的。

+0

謝謝你的回答。我嘗試了上百次,但沒有奏效。 – Sukhrob

+0

這不會創建一個可以一次選擇多個文件的文件選擇框。 – Rvanlaak

+0

我認爲你需要使用一些捆綁來處理多次上傳。因爲默認情況下它會創建多個單個文件上傳。 –

6

要實際呈現輸入類型,您需要將集合中的allow_add選項設置爲true,並使用集合的表單原型,javascript和一個按鈕來添加文件字段。

基於文檔中的一個例子(Collection- adding and removing

形式:

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

這只是一個想法,但仍然有很多依賴於做根據您的需求。 如果這不是您正在尋找的內容,也許您可​​以將添加按鈕單擊作爲解決方法。

5

如果你想顯示多個輸入字段,不,這是行不通的。集合類型要求您在呈現字段之前提供一些數據。我已經嘗試過了,創建了一個單獨的實體(例如File),並將關係添加到了我的目標實體中。

例如:

class File 
{ 
    // properties 

    public $file; // this holds an UploadedFile object 

    // getters, setters 
} 

文件類型:

.... 

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('file', 'file', [ 
      'required' => false 
     ]) 
    ; 
} 

產品:

class Product 
{ 
    // properties 

    private $images; // ManyToMany relationship 

    // setters, getters 
} 

產品型號:

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

產品位指示:

public function someAction() 
{ 
    ... 

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

} 

我知道這個解決方案可以矯枉過正,並創建額外的表,但它的作品。