Dropzone.js를 다른 필드와 함께 기존 HTML 양식에 통합


181

현재 사용자가 게시하려는 광고의 세부 정보를 채우는 HTML 양식이 있습니다. 이제 판매 할 상품의 이미지를 업로드하기위한 드롭 존 을 추가하고 싶습니다 .

필요한 대부분의 작업을 수행하는 Dropzone.js 를 찾았 습니다 . 그러나 설명서를 볼 dropzone입력 요소 와 달리 전체 양식의 클래스를 지정해야합니다 . 이것은 내 전체 양식이 dropzone 이됨을 의미합니다 .

내 양식의 일부로 만 dropzone을 사용할 수 있습니까? 예 를 들어 요소를 전체 양식이 아닌 "dropzone" 클래스 로만 지정하면 됩니까?

별도의 양식을 사용할 수 있지만 사용자가 하나의 버튼으로 모든 양식을 제출할 수 있기를 바랍니다.

또는 이것을 할 수있는 다른 라이브러리가 있습니까?

많은 감사

답변:


59

또 다른 방법 div은 클래스 이름 dropzone을 사용하여 양식에 a를 추가하고 프로그래밍 방식으로 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");
        }
    });
});

참고 : autoDiscover를 비활성화하면 Dropzone에서 두 번 연결을 시도합니다.

블로그 기사 : Dropzone js + Asp.net : 대량 이미지를 업로드하는 쉬운 방법


25
그것으로, 그는 기본 제출 버튼을 사용할 수 없습니다, 그것은 그의 질문에 응답하지 않습니다
clement

5
그러나 이것은 여전히 ​​원래 양식을 사용하여 제출하지 않습니다
dangel

3
이것은 내 문제 였고 당신은 그것을 해결했습니다. ty @Satindersingh
Su4p

1
@ Su4p : 도움이되어 기쁩니다. 또한 업로드하는 동안 이미지 크기 조정 옵션과 함께 자세한 설명을 보려면 블로그 기사 링크를 확인할 수 있습니다
Satinder singh

2
URL을 수동으로 설정하면 요소를 놓기 영역으로 설정할 수 있습니다. 성공 처리기를 사용하여 파일 이름을 기본 양식의 숨겨진 / 비활성화 된 필드에 게시했습니다.
DigitalDesignDj

40

나는 똑같은 문제를 겪었고 Varan Sinayee의 대답이 실제로 원래의 질문을 해결 한 유일한 방법이라는 것을 알았습니다. 그 대답은 단순화 될 수 있으므로 여기 더 간단한 버전이 있습니다.

단계는 다음과 같습니다.

  1. 일반적인 형식을 만듭니다 (더 이상 dropzone에서 처리하지 않기 때문에 메소드와 enctype 인수를 잊지 마십시오).

  2. class="dropzone"(Dropzone이 연결되는 방식) 및 id="yourDropzoneName"(옵션 변경에 사용 ) 으로 div를 넣습니다 .

  3. 양식 및 파일이 게시 될 URL을 설정하려면 Dropzone의 옵션을 설정하고 autoProcessQueue를 비활성화하고 (사용자가 'submit'을 누를 때만 발생) 여러 업로드를 허용합니다 (필요한 경우).

  4. 제출 단추를 클릭 할 때 기본 동작 대신 Dropzone을 사용하도록 init 기능을 설정하십시오.

  5. 여전히 init 함수에서 "sendingmultiple"이벤트 핸들러를 사용하여 파일과 함께 양식 데이터를 보내십시오.

oil! 이제 $ _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());
        });
    }
}

1
이 솔루션은 훌륭하고 효과적이지만 기본 제출 동작을 막기 때문에 더 이상 다음 페이지로 리디렉션되지 않습니다.
Felix G.

@TIIUNDER-페이지를 다시로드하지 않고 Ajax 호출을 통해 양식 정보를 보낼 준비가되었습니다. e.preventDefault ();
born2fr4g

1
@TIUNDER 당신은 성공 이벤트에 리디렉션을 추가 할 수 있습니다
doflamingo

processQueue()통화 후 양식을 제출할 수 있습니까? 내가 사용하려고 submit()하거나 click(), 둘 다없는 일.
그레이 리

1
+1 이것이 유일하게 작동하는 솔루션 인 것 같습니다. formData.append를 하나씩 수행하는 대신 할 수도 있습니다 $(":input[name]", $("form")).each(function () { formData.append(this.name, $(':input[name=' + this.name + ']', $("form")).val()); }); (죄송합니다. 여기서
줄 바꿈을

20

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

2
게시물 주셔서 감사합니다! 내 문제를 해결했다. 또 다른 빠른 질문은, 업로드 할 이미지를 선택하지 않은 경우 작동하지 않습니다.이 문제를 해결하는 방법은 무엇입니까?
Sato

BTW : 모델 바인딩으로 컨트롤러 작업을 사용하고 이와 같이 양식을 제출하면 모델이 비어 있습니다. 어떤 이유로이 방법은 실제 데이터를 모델에 바인딩하지 않습니다.
Edward Chopuryan

1
autoProcessQueue = false 일 때 이벤트가 발생하지 않음
cyril

제출 버튼의 @Sato on click 이벤트는 galleryfile.getAcceptedFiles (). length를 사용하여 dropzone에서 허용되는 파일의 길이를 확인할 수 있으며 업로드 된 파일이 없으면 양식을 제출해야합니다.
Varan Sinayee

@EdwardChopuryan 이것은 dropzone으로 데이터를 제출하는 방법과 관련이 없습니다. ASP.Net MVC와 같은 플랫폼에서 입력 태그의 "이름 지정 규칙"에 문제가있을 수 있습니다.
Varan Sinayee

11

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

23
양식 안에 양식을 가지고 제출할 수 없습니다.
paul

1
이것을 시도하면 dropzone-previews 컨테이너가 무시되는 것 같습니다. Dropzone은 양식의 맨 아래에 미리보기를 추가합니다. 'previewsContainer :'.dropzone-previews ''를 구성에 추가해야합니다.
Aaron Hill

6
이것은 원래 질문에 대한 답변이 아닙니다. 원래 질문은 Dropzone을 사용하여 동작을 트리거하는 버튼의 위치가 아니라 기존 양식과 함께 사용하는 방법이었습니다.
CSSian

7

sqram이 말한 것 외에도 Dropzone에는 "hiddenInputContainer"라는 추가 문서화되지 않은 옵션이 있습니다. 숨겨진 파일 필드를 추가 할 양식의 선택기로이 옵션을 설정하기 만하면됩니다. 그리고 짜잔! Dropzone이 일반적으로 본문에 추가하는 ".dz-hidden-input"파일 필드는 마술처럼 양식으로 이동합니다. Dropzone 소스 코드를 변경하지 않습니다.

이제 Dropzone 파일 필드를 양식으로 이동하는 동안 필드 이름이 없습니다. 따라서 다음을 추가해야합니다.

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

이 줄 다음에 dropzone.js를 삭제하십시오.

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

547 행.


5

이에 대한 자동화 된 솔루션이 있습니다.

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>

자바 스크립트 :

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

라 라벨 :

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

DropZone Discovery를 비활성화 할 필요가 없으며 일반 양식 제출은 표준 양식 직렬화를 통해 다른 양식 필드와 함께 파일을 보낼 수 있습니다.

이 메커니즘은 파일 내용이 처리 될 때 숨겨진 입력 필드에 base64 문자열로 저장합니다. 표준 base64_decode()방법을 통해 PHP에서 이진 문자열로 다시 디코딩 할 수 있습니다 .

이 방법이 큰 파일로 손상 될지 모르겠지만 ~ 40MB 파일로 작동합니다.


이미지와 함께 제출 될 다른 필드의 데이터를 어떻게 디코딩하고 처리합니까?
sam

@sam 다른 필드를 해독 할 필요가 없습니다. 그들은 처음부터 인코딩되지 않고 파일 만 인코딩됩니다.
Umair Ahmed

HTML, 자바 스크립트 및 laravel PHP에서 검색하는 방법에 대한 샘플 코드를 공유 할 수 있습니까?
sam

2
여러 이미지를 추가하려면 html 파일 입력을 제거하고 각 이미지에 대해 quing js를 추가해야합니다 $ ( '# fileUpload'). append ( '<input hidden name = "files []"value ='+ content + ' /> ') 여기서 content는 base64로 인코딩 된 이미지입니다.
AleXzpm

1
@codepushr는 우리가 유료 솔루션을 고려하지 않은 시간의 오래된 대답입니다. FileUploader를 구입했지만 자체 Shenanigan이 있지만 거의 모든 작업을 수행하도록 사용자 정의 할 수 있다고 말하면 충분합니다.
Umair Ahmed

4

dropzone에서 'sending'이벤트를 포착하여 formData를 수정할 수 있습니다.

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

1
나는이 답변을 좋아하지만 필드 이름과 값이 채워 졌다고 가정합니다. 이것은 양식 제출에 별도의 시간에 발생할 수있는 업로드에서 트리거됩니다. 다시 말해, 이미지를 전송할 때 양식이 작성되었다고 가정 할 수 없습니다.
Antony

4

단일 요청으로 다른 양식 데이터와 함께 모든 파일을 제출하기 위해 Dropzone.js 임시 숨겨진 input노드를 양식에 복사 할 수 있습니다 . 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);
});

분명히 이것은 구현 세부 사항에 따라 해결 방법입니다. 관련 소스 코드 .


나는 기본적 으로이 접근법을 사용했지만 명백한 처리 지연으로 인해 결국 myDropzone.on("thumbnail", () => {})이벤트 에서 파일 내용 처리를 연결했습니다 . "addedFile"파일에서 즉시 처리를 수행해도 여전히 undefined액세스 할 수 있습니다.
Matti

이것을 사용하려고하는데 숨겨진 파일 입력 필드를 양식으로 가져 오는 데 효과적이며 제출하면 게시물 데이터에 내 필드가 표시 files[]되지만 내가하는 일에 관계없이 비어 있습니다. 어떤 아이디어? 차이가 있다면 Laravel에서 수행하십시오.
zen

여보세요! 선택한 파일이 업로드되는 이유는 무엇입니까? 그러나 파일을 삭제 한 경우에는 그렇지 않습니다 (오류 4)?
Ingus

2

나는 같은 문제에 직면했을 때 여기에 답변을 드리고 싶습니다. 우리는 $ _FILES 요소를 다른 양식과 동일한 게시물의 일부로 사용할 수 있기를 원합니다. 내 대답은 @mrtnmgs를 기반으로하지만 해당 질문에 추가 된 의견을 기록합니다.

첫째 : Dropzone은 Ajax를 통해 데이터를 게시합니다.

formData.append옵션을 여전히 사용 한다고해서 UX 작업을 처리해야한다는 의미입니다. 즉,이 모든 것이 장면 뒤에서 발생하며 일반적인 양식 게시물이 아닙니다. 데이터가 url매개 변수에 게시됩니다 .

둘째 : 양식 게시물을 모방하려면 게시 된 데이터를 저장해야합니다.

게시 된 데이터가 수신 된 페이지로 이동하지 않으므로 다른 페이지로드에서 사용자가 사용할 수있는 세션 $_POST또는 $_FILES세션에 서버 측 코드를 저장해야합니다 .

셋째 :이 데이터가 실행되는 페이지로 사용자를 리디렉션해야합니다.

이제 데이터를 게시하고 세션에 저장 했으므로 추가 페이지에서 사용자를 위해 표시 / 조치해야합니다. 해당 페이지로 사용자를 보내야합니다.

내 예를 들어 :

[드롭 존 ​​코드 : Jquery 사용]

$('#dropArea').dropzone({
    url:        base_url+'admin/saveProject',
    maxFiles:   1,
    uploadMultiple: false,
    autoProcessQueue:false,
    addRemoveLinks: true,
    init:       function(){
        dzClosure = this;

        $('#projectActionBtn').on('click',function(e) {
            dzClosure.processQueue(); /* My button isn't a submit */
        });

        // My project only has 1 file hence not sendingmultiple
        dzClosure.on('sending', function(data, xhr, formData) {
            $('#add_user input[type="text"],#add_user textarea').each(function(){
                formData.append($(this).attr('name'),$(this).val());
            })
        });

        dzClosure.on('complete',function(){
            window.location.href = base_url+'admin/saveProject';
        })
    },
});

1

이것은 기존 양식에서 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 +'">');
}

이것은 #botofform업로드 할 때 업로드 된 파일 이름을 사용할 수 있는 ID 를 가진 div가 있다고 가정합니다 .

참고 : 내 업로드 스크립트가 uploadedfilename.jpeg dubblenote를 반환 했으므로 업로드 디렉토리를 사용하지 않는 파일이 있는지 확인하고 파일을 삭제하는 정리 스크립트를 만들어야합니다.


드롭 존 이미지를 다른 양식 필드와 함께 제출하지 않습니다. 당신이하는 일은 이미지를 정상적으로 업로드하고 이미지 이름을 저장 한 다음 나머지 양식 필드를 이미지 이름으로 다시 제출하는 것입니다.
zen

1

여기 내 샘플이 있습니다 .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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.