Multi File Smart Upload en AJAX avec Dropzone et jQuery

Dropzone est une librairie javascript permettant de faire du téléchargement multiple asynchrone de fichiers. Il offre une fonctionnalité particulièrement intéressante de téléchargement asynchrone de fichiers. De l'autre, il permet de gérer des téléchargements multiple de manière beaucoup plus intelligente qu'en utilisant l'input de base de l'HTML. Il permet notamment de charger des fichiers qui proviennent de plusieurs répertoires. Ce qui n'est pas le cas de la fonction de base disponible en HTML... Allez savoir pourquoi !

Objectif

L'objectif est relativement simple. On cherche a proposer un formulaire dans une modale (boîte de dialogue) chargée en AJAX avec du téléchargement multiple de fichiers. Ce que nous souhaitons, c'est de permettre l'ajout de ces fichiers lors de la soumission du formulaire afin que le comportement obtenu soit exactement le même que lorsque l'on utilise le champs de type file avec l'option multiple.

Solution

La solution n'est pas immediate, Dropzone n'est pas directement fait pour déléguer la gestion du formulaire à un tiers. Dans notre cas, nous avons un système qui s'occupe déjà de gérer la soumission du formulaire en ajax. De plus, il permet de gérer certains traitements faits après la soumission qui du coup sont incompatibles avec le système natif de Dropzone.

Modification de la soumission ajax originale

La première chose à faire est de tirer partie dy système de gestion évennementiel de javascript. Il permet de faire pas mal de choses surtout si vous voulez proposer un système générique permettant de brancher d'autres fonctions dans vos formulaires. (Un tinymce par exemple !).

L'idée est on ne peut plus simple, on récupère le formulaire que l'on souhaite soumettre, on le serialize en utilisant l'objet FormData et on dispatche l'évennement en lui passant les données sérialisées:

    var $form = $('#my-form');
    var data = new FormData($form[0])

    var postSubmitEvent = $.Event('post-submit.ucs.ajax-modal')
    postSubmitEvent.form = $form
    postSubmitEvent.formData = data
    $form.trigger(postSubmitEvent)

    // Puis soumission ajax du formulaire
    $.ajax({
        url: '/my-form-with-files-and-dropzone',
        method: 'post',
        data: data,
        processData: false,
        contentType: false,
        success: function(data) {
            // Votre code de succès ici
        },
        error: function(jqXHR) {
            // Votre code d'erreur ici
        }
    }).always(function() {
        // Le code toujours exécuté ici
    })

Gestion de la dropzone

La dernière étape est de modifier la finction init de la dropzone pour catcher l'évennement généré par notre soumission AJAX, récupérer les fichiers en attente dans notre instance de dropzone et les ajouter aux données à soumettre avec les bons paramètres:

    $("#my-dropzone").dropzone({
        // The configuration we've talked about above
        autoProcessQueue: false,
        uploadMultiple: true,
        parallelUploads: 100,
        maxFiles: 100,
        paramName: "file",
        previewsContainer: '.dropzone-previews',

        // The setting up of the dropzone
        init: function() {
            var myDropzone = this;

            $(document).on('post-submit.ucs.ajax-modal', function(e) {
                // Make sure that the form isn't actually being sent.
                var files = myDropzone.getQueuedFiles();

                for (_m = 0, _len4 = files.length; _m < _len4; _m++) {
                    var file = files[_m];
                    e.formData.append("" + "file[]", file, file.name);
                }
            });
        }
    })

Conclusion

Voilà ! vous savez maintenant comment tirer partie de dropzone dans un formulaire en ajax pour l'utiliser comme un input de fichier multiple !

A bientôt !

Comments

comments powered by Disqus