2012-09-13 2 views
16

Desidero caricare più file con richiesta POST (senza Ajax). Posso usare campo di raccolta sotto forma di Symfony 2 con tipo di file in questo modo:Symfony 2 Campo raccolta moduli con file tipo

Codice in Entity:

public $pictures; 

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

codice nel modulo di classe:

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

Codice in Twig:

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

Ho provato, ma non sembra funzionare. Non mostra errori, ma non mostra nemmeno il file di input. Qualche idea?

risposta

3

è necessario specificare il tipo di widget nella collezione

sguardo al: 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, 
), 
)); 

Per ulteriori approfondimenti vi consiglio di

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

Inoltre è necessario aggiungere sth a questa raccolta per visualizzare cuz sarà vuoto quando si inizializza come nel costruttore dell'entità.

+0

Grazie per la risposta. L'ho provato centinaia di volte, ma non ha funzionato. – Sukhrob

+0

Questo non crea una casella di selezione file in cui è possibile selezionare più file contemporaneamente. – Rvanlaak

+0

Penso che sia necessario utilizzare qualche pacchetto per gestire il caricamento multiplo. Perché per impostazione predefinita creerà più caricamenti di file singoli. –

6

Per il rendering effettivo dei tipi di input è necessario impostare l'opzione allow_add nella raccolta su true e utilizzare il prototipo di modulo dell'insieme, javascript e un pulsante per aggiungere campi di file.

un esempio basato nella documentazione (Collection- adding and removing)

La forma:

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

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

Questa è solo un'idea, c'è ancora molto da fare in funzione sulle tue esigenze. Se non fosse quello che stavi cercando, forse potresti chiamare il pulsante Aggiungi come soluzione alternativa.

5

Se si desidera visualizzare più campi di input, no, non funzionerà. Un tipo di raccolta richiede di fornire alcuni dati prima di rendere i campi. L'ho già provato e ho creato un'entità separata (ad esempio File) e aggiungendo una relazione alla mia entità di destinazione.

esempio:

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

prodotto:

class Product 
{ 
    // properties 

    private $images; // ManyToMany relationship 

    // setters, getters 
} 

acquisto:

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

contoller prodotto:

public function someAction() 
{ 
    ... 

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

} 

so che questa soluzione può essere eccessivo e crea tavoli extra, ma funziona.