简体   繁体   English

将“拖放区域”与“常规文件输入”组合

[英]Combining a 'Drop-Zone' with a 'regular file-input'

This is something I fear has been answered before, but I couldn't find anything. 我担心这是以前已经回答过的问题,但是我找不到任何东西。

I am working on a modest web application. 我正在开发一个适度的Web应用程序。 Part of it is a file-uploader which uploads xml-files to a Java servlet, which are parsed and imported into a database. 它的一部分是文件上传器,它将xml文件上传到Java Servlet,然后将其解析并导入到数据库中。

Until recently, the html and javascript enabling this looked something like the following (Note that the ironic and/or unhelpful comments are put in place of large chunks of code irrelevant to the question): 直到最近,启用此功能的html和javascript看起来都类似于以下内容(请注意,具有讽刺意味和/或无益的注释已替换为与问题无关的大块代码):

html HTML

<form id="import_form">
  <!-- Some irrelevant divs here --> 
  <span class="btn btn-default btn-file">
        Browse <input name="filesToUpload[]" id="filesToUpload" type="file" multiple="" accept="" onchange="updateFileList();"/>
  </span>
  <!-- Some irrelevant divs here --> 
</form>

Javascript 使用Javascript

function submitImport() {
    var formData = new FormData($('#import_form')[0]);

    $.ajax({
        url : "uploadEndpoint",
        type : "POST",
        data : formData,
        /* Some more elements */
        success : function(response) {
            // Handle success, it ain't easy
        },
        error : function(request, error, status){
            // Handle failure, weep
        }
    });

The submitImport method is called when the user clicks himself/herself through a set of buttons. 当用户通过一组按钮单击自己时,将调用submitImport方法。

This is all fine and dandy, and works just fine. 这一切都很好,很花哨,并且很好用。 However, in an effort to make the web application cool and stuff , today, I tried to add a 'drop-zone': 但是,为了使Web应用程序更酷 ,今天,我尝试添加一个“放置区”:

html HTML

<div id="drop-zone">
    <p class="info">Or drop files here</p>
</div>

Javascript 使用Javascript

// Handler for the drop-zone
$('#drop-zone').on('dragover', function(event){
    event.preventDefault();
    event.stopPropagation();

    if(!event.dataTransfer){
        event.dataTransfer = event.originalEvent.dataTransfer;
    }

    event.dataTransfer.dropEffect = "copy";
    $(this).css("background-color", "#f5f5f5");

}).on('dragleave', function(event){
    event.preventDefault();
    event.stopPropagation();
    $(this).css("background-color", "#fff");
}).on('drop', function(event){
    event.preventDefault();
    event.stopPropagation();

    if(!event.dataTransfer){
        event.dataTransfer = event.originalEvent.dataTransfer;
    }    

    var files = event.dataTransfer.files;

    // Okey so what now?
});

Still with me? 还在我这儿? Okey, so my question is the following: Okey,所以我的问题如下:

How do I in one chunk send, via $.ajax , the files added both from the "Browse"-input, and the drop-zone? 我如何在一个块发送,通过$.ajax ,将文件添加无论是从“浏览” -输入, 以及落区?

As indicated by the Okey so what now? 正如Okey so what now?所指出的, Okey so what now?Okey so what now? comment, I don't really know what to do with the files added in the drop-zone. 评论,我真的不知道该如何处理放置在拖放区中的文件。 I can easily fetch the "Browse"-input-form files with 我可以轻松地获取“浏览”输入形式的文件

$("#filesToUpload").prop("files");

However, I've come to understand that FileLists are immutable , so that doesn't really help me much, as I cannot append the first to the second. 但是,我开始了解FileLists不可变的 ,因此对我没有太大帮助,因为我无法将第一个附加到第二个。

The one chunk part is vital for application-specific reasons. 一层大块的部分是应用程序特定的原因,是至关重要的。 Consequently, solutions like sequentially sending all FileLists are not ideal. 因此,诸如顺序发送所有FileList的解决方案并不理想。

Note that I am quite the novice in anything web related, so apologies if the answer is staring me in the face. 请注意,我是与网络相关的任何事物的新手,如果答案在我的面前,我深表歉意。

 var files = event.dataTransfer.files;

// Okey so what now?

Ok, now would be the following: 好的,现在将是以下内容:

Yes, the FileList objects are immutable. 是的,FileList对象是不可变的。 But you don't need to modify them. 但是您不需要修改它们。 Just add the dropped files from FileList to an array named, say, 'files', one by one. 只需将从FileList中删除的文件一个接一个地添加到名为“ files”的数组中即可。

Then, just before calling jQuery.ajax, you can add all files from the files array to the FormData object, as regular fields. 然后,就在调用jQuery.ajax之前,您可以将文件数组中的所有文件作为常规字段添加到FormData对象中。

At example: 例如:

Step 1 - to remember dropped files 步骤1-记住已删除的文件

var files = event.dataTransfer.files; var files = event.dataTransfer.files;

var files = [];
// (be sure to declare 'files' in a scope available in both of ondrop and form-submit methods)

At onDrop: 在onDrop:

for(var i = 0;i < event.dataTransfer.files.length;i++) {
    files.push(event.dataTransfer.files.item(i));
    // here you can add some DOM manipulations to show users what files have been dropped here
}

Step 2 - adding files to FormData object 第2步-将文件添加到FormData对象

for(var i = 0;i < fileList.length;i++) {
    formData.append('droppedFile[]', fileList[i]);
}

Voilà

The problem is that you can't check for duplicates in subsequent file drops, because the full local path of the file is not accessible for security reasons (it is available on some browsers, but we have not to rely on this unreliable feature). 问题是您不能在后续的文件删除中检查重复项,因为出于安全原因,无法访问文件的完整本地路径(某些浏览器中可用该路径,但我们不必依赖此不可靠的功能)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM