it-roy-ru.com

Интеграция Dropzone.js в существующую HTML-форму с другими полями

В настоящее время у меня есть HTML-форма, которую пользователи заполняют детали объявления, которое они хотят опубликовать. Теперь я хочу, чтобы можно было добавить Dropzone для загрузки изображений предмета для продажи. Я нашел dropzone.js, который, кажется, делает большую часть того, что мне нужно. Однако при просмотре документации кажется, что вам нужно указать класс всей формы как «dropzone» (в отличие от только элемента ввода). Это означает, что вся моя форма становится зоной падения. Можно ли использовать dropzone только в части моей формы, т. Е. Указав только элемент в качестве класса dropzone, а не всю форму?

Я мог бы использовать отдельные формы, но я хочу, чтобы пользователь мог отправить все это с помощью одной кнопки.

Или есть другая библиотека, которая может это сделать?

Большое спасибо

146
Ben Thompson

Вот еще один способ сделать это: добавить в форму div с помощью dropzone зоны с именем класса и программно реализовать ее.

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

Примечание: отключение автообнаружения, иначе Dropzone попытается подключиться дважды

Статья в блоге: Dropzone js + Asp.net: простой способ загрузки групповых изображений

53
Satinder singh

У меня была точно такая же проблема, и я обнаружил, что ответ Варан Синаи был единственным, который действительно решил исходный вопрос. Этот ответ может быть упрощен, так что вот более простая версия.

Шаги:

  1. Создайте нормальную форму (не забудьте метод и аргументы enctype, так как это больше не обрабатывается dropzone).

  2. Поместите div внутри с помощью class="dropzone" (именно так к нему прикрепляется Dropzone) и id="yourDropzoneName" (используется для изменения параметров).

  3. Задайте параметры Dropzone, чтобы задать URL-адрес, где будут размещаться форма и файлы, деактивировать autoProcessQueue (так происходит только при нажатии пользователем кнопки «Отправить») и разрешить несколько загрузок (если вам это нужно).

  4. Установите функцию init для использования Dropzone вместо поведения по умолчанию при нажатии кнопки отправки.

  5. Все еще в функции init используйте обработчик события «sendmultiple» для отправки данных формы вместе с файлами.

Вуаля! Теперь вы можете извлекать данные, как и в обычной форме, в $ _POST и $ _FILES (в примере это происходит в 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());
        });
    }
}
28
mrtnmgs

«Dropzone.js» является самой распространенной библиотекой для загрузки изображений Если вы хотите, чтобы «dropzone.js» был только частью вашей формы, вы должны выполнить следующие шаги:

1) для клиентской части:

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) для серверной части:

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." });
    }
17
Varan Sinayee

Учебник Enyo отлично.

Я обнаружил, что пример сценария в учебном пособии хорошо работает для кнопки, встроенной в dropzone (то есть элемент формы). Если вы хотите, чтобы кнопка находилась вне элемента формы, я смог выполнить ее с помощью события click:

Во-первых, HTML:

<form id="my-awesome-dropzone" action="/upload" class="dropzone">  
    <div class="dropzone-previews"></div>
    <div class="fallback"> <!-- this is the fallback if JS isn't working -->
        <input name="file" type="file" multiple />
    </div>

</form>
<button type="submit" id="submit-all" class="btn btn-primary btn-xs">Upload the file</button>

Затем тег сценария ....

Dropzone.options.myAwesomeDropzone = { // The camelized version of the ID of the form element

    // The configuration we've talked about above
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 25,
    maxFiles: 25,

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

        // Here's the change from enyo's tutorial...

        $("#submit-all").click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            myDropzone.processQueue();
        }); 
    }
}
11
kablamus

В дополнение к тому, что говорил sqram, у Dropzone есть дополнительная недокументированная опция «hiddenInputContainer». Все, что вам нужно сделать, это установить эту опцию на селектор формы, к которой вы хотите добавить поле скрытого файла. И вуаля! Поле «.dz-hidden-input», которое Dropzone обычно добавляет к телу, волшебным образом перемещается в вашу форму. Не изменять исходный код Dropzone.

Теперь, пока это работает, чтобы переместить поле файла Dropzone в вашу форму, поле не имеет имени. Так что вам нужно будет добавить:

_this.hiddenFileInput.setAttribute("name", "field_name[]");

в dropzone.js после этой строки:

_this.hiddenFileInput = document.createElement("input");

вокруг линии 547.

4
Codedragon

Вы можете изменить formData, отлавливая событие 'send' из вашей зоны сброса.

dropZone.on('sending', function(data, xhr, formData){
        formData.append('fieldname', 'value');
});
4
shawnrushefsky

Чтобы отправить все файлы вместе с другими данными формы в одном запросе, вы можете скопировать в форму временно скрытые input узлы Dropzone.js. Вы можете сделать это в обработчике событий addedfiles:

var myDropzone = new Dropzone("myDivSelector", { url: "#", autoProcessQueue: false });
myDropzone.on("addedfiles", () => {
  // Input node with selected files. It will be removed from document shortly in order to
  // give user ability to choose another set of files.
  var usedInput = myDropzone.hiddenFileInput;
  // Append it to form after stack become empty, because if you append it earlier
  // it will be removed from its parent node by Dropzone.js.
  setTimeout(() => {
    // myForm - is form node that you want to submit.
    myForm.appendChild(usedInput);
    // Set some unique name in order to submit data.
    usedInput.name = "foo";
  }, 0);
});

Очевидно, что это обходной путь, зависящий от деталей реализации. Связанный исходный код .

3
Leonid Vasilev

У меня есть более автоматизированное решение для этого. 

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'));

Нет необходимости отключать DropZone Discovery, и обычная форма отправки сможет отправить файл с любыми другими полями формы через стандартную сериализацию формы. 

Этот механизм сохраняет содержимое файла в виде строки base64 в скрытом поле ввода при его обработке. Вы можете декодировать его обратно в двоичную строку в PHP с помощью стандартного метода base64_decode().

Я не знаю, будет ли этот метод скомпрометирован с большими файлами, но он работает с ~ 40 МБ файлами. 

3
Umair Ahmed

Это просто еще один пример того, как вы можете использовать Dropzone.js в существующей форме. 

dropzone.js:

 init: function() {

   this.on("success", function(file, responseText) {
     //alert("HELLO ?" + responseText); 
     mylittlefix(responseText);
   });

   return noop;
 },

Затем позже в файл я положил 

function mylittlefix(responseText) {
  $('#botofform').append('<input type="hidden" name="files[]" value="'+ responseText +'">');
}

Это предполагает, что у вас есть div с идентификатором #botofform, поэтому при загрузке вы можете использовать имена загруженных файлов. 

Примечание: мой скрипт загрузки возвратил theuploadedfilename.jpeg Dubblenote, вам также потребуется создать скрипт очистки, который проверяет каталог загрузки на наличие файлов, которые не используются, и удаляет их ..if в внешнем интерфейсе без аутентификации :)

0
taggart

Вот мой пример, основанный на Django + Dropzone. Для просмотра выберите (обязательно) и отправьте.

<form action="/share/upload/" class="dropzone" id="uploadDropzone">
    {% csrf_token %}
        <select id="warehouse" required>
            <option value="">Select a warehouse</option>
                {% for warehouse in warehouses %}
                    <option value={{forloop.counter0}}>{{warehouse.warehousename}}</option>
                {% endfor %}
        </select>
    <button id="submit-upload btn" type="submit">upload</button>
</form>

<script src="{% static '/js/libs/dropzone/dropzone.js' %}"></script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
    var filename = "";

    Dropzone.options.uploadDropzone = {
        paramName: "file",  // The name that will be used to transfer the file,
        maxFilesize: 250,   // MB
        autoProcessQueue: false,
        accept: function(file, done) {
            console.log(file.name);
            filename = file.name;
            done();    // !Very important
        },
        init: function() {
            var myDropzone = this,
            submitButton = document.querySelector("[type=submit]");

            submitButton.addEventListener('click', function(e) {
                var isValid = document.querySelector('#warehouse').reportValidity();
                e.preventDefault();
                e.stopPropagation();
                if (isValid)
                    myDropzone.processQueue();
            });

            this.on('sendingmultiple', function(data, xhr, formData) {
                formData.append("warehouse", jQuery("#warehouse option:selected").val());
            });
        }
    };
</script>
0
smartworld-dm