218 votes

Intégration de Dropzone.js dans un formulaire HTML existant avec d'autres champs

J'ai actuellement un formulaire HTML dans lequel les utilisateurs remplissent les détails d'une annonce qu'ils souhaitent publier. Je souhaite maintenant pouvoir ajouter un zone de saut pour télécharger des images de l'objet à vendre.

J'ai trouvé Dropzone.js qui semble faire la plupart des choses dont j'ai besoin. Cependant, en consultant la documentation, il apparaît que vous devez spécifier la classe de l'ensemble du formulaire comme suit dropzone (par opposition au simple entrée élément). Cela signifie donc que l'ensemble de mon formulaire devient l'élément zone de saut .

Est-il possible d'utiliser la dropzone dans une partie seulement de mon formulaire, c'est-à-dire en ne faisant que en spécifiant l'élément comme classe "dropzone" plutôt que l'ensemble du formulaire ?

Je pourrais utiliser des formulaires séparés, mais je veux que l'utilisateur puisse tout soumettre avec un seul bouton.

Sinon, existe-t-il une autre bibliothèque qui peut faire cela ?

Merci beaucoup.

77voto

Satinder singh Points 3089

Voici une autre façon de procéder : ajouter un div dans votre formulaire avec un classname dropzone, et implémenter dropzone programmatiquement.

HTML :

<div id="dZUpload" class="dropzone">
      <div class="dz-default dz-message"></div>
</div>

JQuery :

$(document).ready(function () {
    Dropzone.autoDiscover = false;
    $("#dZUpload").dropzone({
        url: "hn_SimpeFileUploader.ashx",
        addRemoveLinks: true,
        success: function (file, response) {
            var imgName = response;
            file.previewElement.classList.add("dz-success");
            console.log("Successfully uploaded :" + imgName);
        },
        error: function (file, response) {
            file.previewElement.classList.add("dz-error");
        }
    });
});

Note : Désactiver autoDiscover, sinon le Dropzone essaiera de se connecter deux fois.

60voto

mrtnmgs Points 575

J'ai eu exactement le même problème et j'ai constaté que la réponse de Varan Sinayee était la seule qui résolvait réellement la question initiale. Cette réponse peut cependant être simplifiée, voici donc une version plus simple.

Les étapes sont les suivantes :

  1. Créez un formulaire normal (n'oubliez pas les args method et enctype puisque ce n'est plus géré par dropzone).

  2. Mettez un div à l'intérieur avec le class="dropzone" (c'est ainsi que Dropzone s'y attache) et id="yourDropzoneName" (utilisé pour changer les options).

  3. Définissez les options de Dropzone, pour définir l'URL où le formulaire et les fichiers seront affichés, désactivez autoProcessQueue (de sorte qu'il ne se produit que lorsque l'utilisateur appuie sur 'submit') et autorisez les téléchargements multiples (si vous en avez besoin).

  4. Configurer la fonction init pour utiliser Dropzone au lieu du comportement par défaut lorsque le bouton submit est cliqué.

  5. Toujours dans la fonction init, utilisez le gestionnaire d'événement "sendingmultiple" pour envoyer les données du formulaire avec les fichiers.

Voilà ! Vous pouvez maintenant récupérer les données comme vous le feriez avec un formulaire normal, dans $_POST et $_FILES (dans l'exemple, cela se passe dans upload.php).

HTML

<form action="upload.php" enctype="multipart/form-data" method="POST">
    <input type="text" id ="firstname" name ="firstname" />
    <input type="text" id ="lastname" name ="lastname" />
    <div class="dropzone" id="myDropzone"></div>
    <button type="submit" id="submit-all"> upload </button>
</form>

JS

Dropzone.options.myDropzone= {
    url: 'upload.php',
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 5,
    maxFiles: 5,
    maxFilesize: 1,
    acceptedFiles: 'image/*',
    addRemoveLinks: true,
    init: function() {
        dzClosure = this; // Makes sure that 'this' is understood inside the functions below.

        // for Dropzone to process the queue (instead of default form behavior):
        document.getElementById("submit-all").addEventListener("click", function(e) {
            // Make sure that the form isn't actually being sent.
            e.preventDefault();
            e.stopPropagation();
            dzClosure.processQueue();
        });

        //send all the form data along with the files:
        this.on("sendingmultiple", function(data, xhr, formData) {
            formData.append("firstname", jQuery("#firstname").val());
            formData.append("lastname", jQuery("#lastname").val());
        });
    }
}

24voto

Varan Sinayee Points 320

Le fichier "dropzone.js" est la bibliothèque la plus courante pour le téléchargement d'images. Si vous souhaitez que "dropzone.js" fasse partie intégrante de votre formulaire, vous devez suivre les étapes suivantes :

1) pour le côté client :

HTML :

    <form action="/" enctype="multipart/form-data" method="POST">
        <input type="text" id ="Username" name ="Username" />
        <div class="dropzone" id="my-dropzone" name="mainFileUploader">
            <div class="fallback">
                <input name="file" type="file" multiple />
            </div>
        </div>
    </form>
    <div>
        <button type="submit" id="submit-all"> upload </button>
    </div>

JQuery :

    <script>
        Dropzone.options.myDropzone = {
            url: "/Account/Create",
            autoProcessQueue: false,
            uploadMultiple: true,
            parallelUploads: 100,
            maxFiles: 100,
            acceptedFiles: "image/*",

            init: function () {

                var submitButton = document.querySelector("#submit-all");
                var wrapperThis = this;

                submitButton.addEventListener("click", function () {
                    wrapperThis.processQueue();
                });

                this.on("addedfile", function (file) {

                    // Create the remove button
                    var removeButton = Dropzone.createElement("<button class='btn btn-lg dark'>Remove File</button>");

                    // Listen to the click event
                    removeButton.addEventListener("click", function (e) {
                        // Make sure the button click doesn't submit the form:
                        e.preventDefault();
                        e.stopPropagation();

                        // Remove the file preview.
                        wrapperThis.removeFile(file);
                        // If you want to the delete the file on the server as well,
                        // you can do the AJAX request here.
                    });

                    // Add the button to the file preview element.
                    file.previewElement.appendChild(removeButton);
                });

                this.on('sendingmultiple', function (data, xhr, formData) {
                    formData.append("Username", $("#Username").val());
                });
            }
        };
    </script>

2) pour le côté serveur :

ASP.Net MVC

    [HttpPost]
    public ActionResult Create()
    {
        var postedUsername = Request.Form["Username"].ToString();
        foreach (var imageFile in Request.Files)
        {

        }

        return Json(new { status = true, Message = "Account created." });
    }

18voto

enyo Points 5083

J'ai récemment écrit un tutoriel pour ce cas d'utilisation : https://github.com/enyo/dropzone/wiki/Combine-normal-form-with-Dropzone

17voto

Umair Ahmed Points 1567

J'ai une solution plus automatisée pour cela.

HTML :

<form role="form" enctype="multipart/form-data" action="{{ $url }}" method="{{ $method }}">
    {{ csrf_field() }}

    <!-- You can add extra form fields here -->

    <input hidden id="file" name="file"/>

    <!-- You can add extra form fields here -->

    <div class="dropzone dropzone-file-area" id="fileUpload">
        <div class="dz-default dz-message">
            <h3 class="sbold">Drop files here to upload</h3>
            <span>You can also click to open file browser</span>
        </div>
    </div>

    <!-- You can add extra form fields here -->

    <button type="submit">Submit</button>
</form>

JavaScript :

Dropzone.options.fileUpload = {
    url: 'blackHole.php',
    addRemoveLinks: true,
    accept: function(file) {
        let fileReader = new FileReader();

        fileReader.readAsDataURL(file);
        fileReader.onloadend = function() {

            let content = fileReader.result;
            $('#file').val(content);
            file.previewElement.classList.add("dz-success");
        }
        file.previewElement.classList.add("dz-complete");
    }
}

Laravel :

// Get file content
$file = base64_decode(request('file'));

Il n'est pas nécessaire de désactiver DropZone Discovery et l'envoi normal du formulaire sera en mesure d'envoyer le fichier avec tous les autres champs du formulaire par le biais de la sérialisation standard du formulaire.

Ce mécanisme stocke le contenu du fichier sous forme de chaîne base64 dans le champ de saisie caché lors de son traitement. Vous pouvez le décoder en chaîne binaire en PHP à l'aide de la fonction standard base64_decode() método.

Je ne sais pas si cette méthode sera compromise avec les gros fichiers mais elle fonctionne avec des fichiers de ~40MB.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X