【问题标题】:DropZonejs: Submit form without filesDropZonejs:提交没有文件的表单
【发布时间】:2014-01-21 12:45:20
【问题描述】:

我已成功地将 dropzone.js 集成到现有表单中。此表单发布附件和其他输入,如复选框等。

当我提交带有附件的表单时,所有输入都正确发布。但是,我想让用户可以在没有任何附件的情况下提交表单。 Dropzone 不允许表单提交,除非有附件。

有谁知道我可以如何覆盖此默认行为并提交不带任何附件的 dropzone.js 表单?谢谢!

   $( document ).ready(function () {
    Dropzone.options.fileUpload = { // The camelized version of the ID of the form element

      // The configuration we've talked about above
      autoProcessQueue: false,
      uploadMultiple: true,
      parallelUploads: 50,
      maxFiles: 50,
      addRemoveLinks: true,
      clickable: "#clickable",
      previewsContainer: ".dropzone-previews",
      acceptedFiles: "image/*,application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.spreadsheetml.template, application/vnd.openxmlformats-officedocument.presentationml.template, application/vnd.openxmlformats-officedocument.presentationml.slideshow, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.presentationml.slide, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.wordprocessingml.template, application/vnd.ms-excel.addin.macroEnabled.12, application/vnd.ms-excel.sheet.binary.macroEnabled.12,text/rtf,text/plain,audio/*,video/*,.csv,.doc,.xls,.ppt,application/vnd.ms-powerpoint,.pptx",



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

        // First change the button to actually tell Dropzone to process the queue.
        this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
          // Make sure that the form isn't actually being sent.
          e.preventDefault();
          e.stopPropagation();
          myDropzone.processQueue();
        });

        // Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
        // of the sending event because uploadMultiple is set to true.
        this.on("sendingmultiple", function() {
          // Gets triggered when the form is actually being sent.
          // Hide the success button or the complete form.
        });
        this.on("successmultiple", function(files, response) {
            window.location.replace(response.redirect);
            exit();
        });
        this.on("errormultiple", function(files, response) {
          $("#notifications").before('<div class="alert alert-error" id="alert-error"><button type="button" class="close" data-dismiss="alert">×</button><i class="icon-exclamation-sign"></i> There is a problem with the files being uploaded. Please check the form below.</div>');
          exit();
        });

      }

    }
  });

【问题讨论】:

    标签: dropzone.js


    【解决方案1】:

    使用以下内容:

    $('input[type="submit"]').on("click", function (e) {
    
                        e.preventDefault();
                        e.stopPropagation();
    
                        var form = $(this).closest('#dropzone-form');
                        if (form.valid() == true) { 
                            if (myDropzone.getQueuedFiles().length > 0) {                        
                                myDropzone.processQueue();  
                            } else {                       
                                myDropzone.uploadFiles([]); //send empty 
                            }                                    
                        }               
                    });
    

    参考:https://github.com/enyo/dropzone/issues/418

    【讨论】:

    • 我收到错误 Uncaught TypeError: Cannot read property 'status' of undefined dropzone.js?body=1:1447 提交时没有文件。你测试过吗?
    • 显然这需要修改源代码(请参阅参考资料)以避免我遇到的错误。
    • @light24bulbs 很高兴你知道了。这就是参考的用途,因此您可以获得解决方案的整个上下文。
    • 有一个未解决的问题。请投票,以便解决此问题。 github.com/enyo/dropzone/issues/687
    【解决方案2】:

    您应该检查队列中是否有文件。如果队列为空,直接调用 dropzone.uploadFile()。此方法需要您传入一个文件。如 [caniuse][1] 所述,IE/Edge 不支持 File 构造函数,因此只需使用 Blob API,因为 File API 是基于此的。

    dropzone.uploadFile() 中使用的 formData.append() 方法要求您传递一个实现 Blob 接口的对象。这就是你不能传入普通对象的原因。

    dropzone 版本 5.2.0 需要 upload.chunked 选项

    if (this.dropzone.getQueuedFiles().length === 0) {
        var blob = new Blob();
        blob.upload = { 'chunked': this.dropzone.defaultOptions.chunking };
        this.dropzone.uploadFile(blob);
    } else {
        this.dropzone.processQueue();
    }
    

    【讨论】:

    • 这个答案应该是最重要的!谢谢
    • 是的,这只是对我有用的方法。这是参考:github.com/enyo/dropzone/issues/687
    • 只有 5.7.0 版对我有用的解决方案。所有其他答案对版本 4.x 有效。
    • 感谢您的解决方案!对于未定义的defaultOptions,也可以使用this.dropzone.options.chunking
    【解决方案3】:

    根据您的情况,您可以简单地提交表单:

    if (myDropzone.getQueuedFiles().length > 0) {                        
       myDropzone.processQueue();  
    } else {                       
       $("#my_form").submit();
    }
    

    【讨论】:

    • @Limon 检查您的表单是否被标记为 enctype="multipart/form-data"
    • 您是对的,但我想指出,如果您不想重新加载页面而是用 JavaScript 处理服务器响应,那么您完全分离事件处理程序。 Dropzone 在提交之前/期间/之后触发几个事件,在您的“其他”情况下不会触发。
    【解决方案4】:

    第一种方法对我来说有点太贵了,我不想深入研究源代码并修改它,

    如果你恰好和我一样,就用这个吧。

    function submitMyFormWithData(url)
        {
            formData = new FormData();
            //formData.append('nameOfInputField', $('input[name="nameOfInputField"]').val() );
    
            $.ajax({
                    url: url,
                    data: formData,
                    processData: false,
                    contentType: false,
                    type: 'POST',
    
                    success: function(data){
                    alert(data);
                    }
            });
        }
    

    在你的 dropzone 脚本中

    $("#submit").on("click", function(e) {
                          // Make sure that the form isn't actually being sent.
                          e.preventDefault();
                          e.stopPropagation();
    
                            if (myDropzone.getQueuedFiles().length > 0)
                            {                        
                                    myDropzone.processQueue();  
                            } else {                 
                                    submitMyFormWithData(ajaxURL);
                            }     
    
                        });
    

    【讨论】:

    • 目前最好的解决方案,因为 blob 方法会创建一个您需要在服务器端处理的文件,而不是上传它
    【解决方案5】:

    我尝试了 Matija Grcic 的回答,但出现以下错误:

    Uncaught TypeError: Cannot read property 'name' of undefined
    

    而且我不想修改 dropzone 源代码,所以我做了以下操作:

            if (myDropzone.getQueuedFiles().length > 0) {                        
                myDropzone.processQueue();  
            } else {                       
                myDropzone.uploadFiles([{name:'nofiles'}]); //send empty 
            }                                    
    

    注意:我将数组中的一个对象传递给 uploadFiles 函数。

    然后我检查服务器端,如果 name != 'nofiles' 确实上传东西。

    【讨论】:

    • @Agu.nice 解决方案。 myDropzone.uploadFiles([{name:'nofiles'}]);它帮助了我
    【解决方案6】:

    很简单,只有当你有文件要通过 Dropzone 提交时,你才停止传播:

    // First change the button to actually tell Dropzone to process the queue.
    this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
      // Stop the propagation ONLY if you have files to be submitted via Dropzone
      if (myDropzone.getQueuedFiles().length > 0) {
            e.preventDefault();
            e.stopPropagation();
            myDropzone.processQueue();
      }
    });
    

    【讨论】:

      【解决方案7】:

      我已经成功使用了:

      submitButton.addEventListener("click", function () {  
        if(wrapperThis.files.length){
              error = `Please select a file`; 
          } else {
              wrapperThis.processQueue(); 
          }
      }); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        • 2019-10-16
        • 2010-10-11
        • 1970-01-01
        • 1970-01-01
        • 2015-04-19
        相关资源
        最近更新 更多