2012-09-13 19 views
16

Chcę przesłać wiele plików z żądaniem POST (bez Ajax). Czy pole zbierania forma Symfony 2 jest używać z pliku typu tak:Symfony 2 Pole kolekcji formularza z plikiem typu

kod w podmiocie:

public $pictures; 

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

kod w formularzu Klasa:

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

kod w Gałązka:

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

Próbowałem, ale to nie działa. Nie pokazuje żadnych błędów, ale nie pokazuje również pliku wejściowego. Jakieś pomysły?

Odpowiedz

3

musisz określić typ widgetu w kolekcji

Spójrz na: 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, 
), 
)); 

Dla dalszego czytania Proponuję

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

Ponadto trzeba dodać do tej kolekcji, aby wyświetlić, ponieważ będzie ona pusta po zainicjowaniu jak w konstruktorze encji.

+0

Dziękuję za odpowiedź. Próbowałem go setki razy, ale nie działało. – Sukhrob

+0

To nie tworzy pola wyboru pliku, w którym można wybrać wiele plików jednocześnie. – Rvanlaak

+0

Myślę, że musisz użyć jakiegoś pakunku do obsługi wielokrotnego przesyłania. Ponieważ domyślnie utworzy wiele pojedynczych plików. –

6

Aby faktycznie renderować typy wejściowe, należy ustawić opcję allow_add w kolekcji na wartość true i użyć prototypu formularza kolekcji, javascript i przycisku, aby dodać pola plików.

Przykładem siedzibą w dokumentacji (Collection- adding and removing)

Postać:

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

Skrypt:

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

To tylko pomysł, jest jeszcze wiele do zrobienia w zależności na twoje potrzeby. Jeśli nie było to, czego szukałeś, może możesz zadzwonić do przycisku dodawania, aby go obejść.

5

Jeśli chcesz pokazać wiele pól wejściowych, nie, to nie będzie działać. Typ kolekcji wymaga podania pewnych danych przed renderowaniem pól. Wypróbowałem już to i stworzyłem oddzielną całość (np. Plik) i dodałem powiązanie z moją jednostką docelową.

przykład:

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

produktu

class Product 
{ 
    // properties 

    private $images; // ManyToMany relationship 

    // setters, getters 
} 

ProductType:

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

contoller produktu:

public function someAction() 
{ 
    ... 

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

} 

wiem, że to rozwiązanie może być przesadą i tworzy dodatkowe tabele, ale to działa.

Powiązane problemy