删除并重建文件输入时清除文件列表

时间:2014-10-09 12:38:01

标签: javascript jquery forms file file-io

在使用多个文件类型输入时控制我的文件列表时遇到一些麻烦。要清楚,我没有使用具有多个但多个单个文件输入的文件输入。方案是用户可以选择1到5个文件,如果需要可以清除所有文件,但仍然必须发送至少1个文件。所以我将在表单上使用最多五个文件输入。对于初学者来说,我有两个我已经放入一个小提琴和一个CodePen(由于某种原因,他们不像他们在我当地的工作)。用户选择一个文件,该文件和大小被添加到一个单独的列表中,该列表显示了名称和大小,并且附加了一个调用clearfileInput函数的按钮。 clearFileInput函数删除该文件输入(因为这似乎是真正删除文件的唯一方法,因此它不会被发送),我也需要它来清除列表。

CODEPEN HERE JS FIDDLE HERE

这是HTML:

  <input type="file" name="filesToUpload" id="filesToUpload" onChange="makeFileList();" />
  <input type="file" name="filesToUpload" id="filesToUpload2" onChange="makeFileList2();" />

 <ul id="fileList"><li>No Files Selected</li></ul>
 <ul id="fileList2"><li>No Files Selected</li></ul>

我使用的脚本很长,因为我必须复制所有内容,但这里是一个完整的脚本:

function makeFileList() {
    var input = document.getElementById("filesToUpload");
    var ul = document.getElementById("fileList");
    while (ul.hasChildNodes()) {
        ul.removeChild(ul.firstChild);
    }
    for (var i = 0; i < input.files.length; i++) {
        var li = document.createElement("li");
        var fileSize = input.files[i].size;
        li.innerHTML = input.files[i].name +"&nbsp;"+ "<span id=\"lblSize\"></span><input onclick=\"clearFileInput()\" type=\"button\" value=\"Clear\" \/>";
        ul.appendChild(li);
    }
    if(!ul.hasChildNodes()) {
        var li = document.createElement("li");
        li.innerHTML = 'No Files Selected';
        ul.appendChild(li);
    }
};
function makeFileList2() {
    var input = document.getElementById("filesToUpload2");
    var ul = document.getElementById("fileList2");
    while (ul.hasChildNodes()) {
        ul.removeChild(ul.firstChild);
    }
    for (var i = 0; i < input.files.length; i++) {
        var li = document.createElement("li");
        var fileSize = input.files[i].size;
        li.innerHTML = input.files[i].name +"&nbsp;"+"<span id=\"lblSize2\"></span><input onclick=\"clearFileInput2()\" type=\"button\" value=\"Clear\" \/>";
        ul.appendChild(li);
    }
    if(!ul.hasChildNodes()) {
        var li = document.createElement("li");
        li.innerHTML = 'No Files Selected';
        ul.appendChild(li);
    }
};
//Code Starts
$(document).ready(function() {
    $("#filesToUpload").change(function ()
    {
        var iSize = 0;
        if($.browser.msie)
        {
            var objFSO = new ActiveXObject("Scripting.FileSystemObject");
            var sPath = $("#filesToUpload")[0].value;
            var objFile = objFSO.getFile(sPath);
            var iSize = objFile.size;
            iSize = iSize/ 1024;
        }
        else
            iSize = ($("#filesToUpload")[0].files[0].size / 1024);

        if (iSize / 1024 > 1)
        {
            if (((iSize / 1024) / 1024) > 1)
            {
                iSize = (Math.round(((iSize / 1024) / 1024) * 100) / 100);
                $("#lblSize").html( iSize + "Gb");
            }
            else
            {
                iSize = (Math.round((iSize / 1024) * 100) / 100)
                $("#lblSize").html( iSize + "Mb");
            }
        }
        else
        {
            iSize = (Math.round(iSize * 100) / 100)
            $("#lblSize").html( iSize  + "kb");
        }
    });
    $("#filesToUpload2").change(function ()
    {
        var iSize2 = 0;
        if($.browser.msie)
        {
            var objFSO = new ActiveXObject("Scripting.FileSystemObject");
            var sPath = $("#filesToUpload2")[0].value;
            var objFile = objFSO.getFile(sPath);
            var iSize2 = objFile.size;
            iSize = iSize/ 1024;
        }
        else
            iSize2 = ($("#filesToUpload2")[0].files[0].size / 1024);

        if (iSize2 / 1024 > 1)
        {
            if (((iSize2 / 1024) / 1024) > 1)
            {
                iSize2 = (Math.round(((iSize2 / 1024) / 1024) * 100) / 100);
                $("#lblSize2").html( iSize2 + "Gb");
            }
            else
            {
                iSize2 = (Math.round((iSize2 / 1024) * 100) / 100)
                $("#lblSize2").html( iSize2 + "Mb");
            }
        }
        else
        {
            iSize2 = (Math.round(iSize2 * 100) / 100)
            $("#lblSize2").html( iSize2  + "kb");
        }
    });
});
function clearFileInput(){
    var oldInput = document.getElementById("filesToUpload");
    var newInput = document.createElement("input");
    newInput.type = "file";
    newInput.id = oldInput.id;
    newInput.name = oldInput.name;
    newInput.className = oldInput.className;
    newInput.style.cssText = oldInput.style.cssText;
    newInput.setAttribute("onclick", "makeFileList()");
    oldInput.parentNode.replaceChild(newInput, oldInput);
};
function clearFileInput2(){
    var oldInput = document.getElementById("filesToUpload2");
    var newInput = document.createElement("input");
    newInput.type = "file";
    newInput.id = oldInput.id;
    newInput.name = oldInput.name;
    newInput.className = oldInput.className;
    newInput.style.cssText = oldInput.style.cssText;
    newInput.setAttribute("onclick", "makeFileList2()");
    oldInput.parentNode.replaceChild(newInput, oldInput);
}

1 个答案:

答案 0 :(得分:2)

好的,我们首先要解决这个问题。删除/重新创建文件输入。这是从存档问题深入到SO ...

不使用手动复制输入,而是使用jquery的本机克隆功能,因为它还可以选择保留所有事件处理程序。如下......

var upload1 = $('#fileUpload');
upload1.replaceWith( upload1 = upload1.clone( true ) );
//passing true to .clone persists all event handlers

至于其余部分,您可以通过在html中添加一些非标准属性并将其定位而不是通过id(并且必须复制JS 5次)来进一步简化它。

<input type="file" name="filesToUpload" id="filesToUpload" onChange="makeFileList();" />
<input type="file" name="filesToUpload" id="filesToUpload2" onChange="makeFileList2();" />

<ul class="fileList" fileUploadId="filesToUpload"><li>No Files Selected</li></ul>
<ul class="fileList" fileUploadId="filesToUpload2"><li>No Files Selected</li></ul>

在这里,我们采用精简版JS

$(document).ready(function() {
    $('[name="filesToUpload"]').change(function() {
        var activeInput = $(this); //grabs the jq object of whatever is sending the click event
        //Do all your file handling here, I'm going to skip to the li tinkering.

        var ul = $('ul[fileUploadId="' + activeInput.attr('id') + '"]');
        ul.empty(); //performs the same action as your loop clearing out children
        //The rest of this is pretty straight forward to figure out, so I'll leave that
        //for you, and skip ahead to using the 'clear' button. just use the 'ul' var
        //and it will target the correct ul for what you are trying to do.

        //After you have added the button and actually attached it to the DOM, in this same function, we will give it its click listener. 
        //Give the button the 'clearFile' class
        $('.clearFile').off('click'); //remove the click listeners so we don't have them multiple times.
        $('.clearFile').click(function(){
            var buttonClicked = $(this);
            var parentUl = buttonClicked.closest('ul');
            //the following two lines replace that entire oldInput newInput process you were doing.
            var fileUpload = $('#' + parentUl.attr('fileUploadId'));
            fileUpload .replaceWith( fileUpload = fileUpload .clone( true ) );
            parentUl.empty();
    )};
)};

你也可以创建一个单独的ul,并在li级别上执行所有操作,通过改组&#39; fileUploadId&#39;归属于li而不是......可能会使代码更加整洁。

我意识到我已经离开了一些块,以便用类似速度的东西写出来,所以如果你需要澄清,请问。