【问题标题】:Giving option "add more files" after "choose file" and listing names of all the files chosen before submitting the form在“选择文件”之后提供“添加更多文件”选项,并在提交表单之前列出所有选择的文件的名称
【发布时间】:2021-04-16 19:48:11
【问题描述】:

目标:选择“选择文件”按钮后,我想显示文件的名称(f1.txt 和 f2.txt)。之后,我希望能够再次单击该按钮并列出之前的按钮(f1.txt、f2.txt、f3.txt 和 f4.txt)。在此之后单击“上传文件”我想上传所有 4 个文件。

我尝试隐藏以前的按钮,但在另一部分没有成功。我遇到了这篇似乎很有帮助的帖子:List selected files from file input。我已经做了一个星期,并决定发布这个。

以下是供您参考的代码。

附:我是这个领域的新手,所以请详细说明你的答案。(对不起,一团糟)

function restrictTypeAndSize(obj) {

  var s = true;
  for (var i = 0; i < obj.files.length; i++) {
    s = writefiles(obj.files[i]);
  }
}

function writefiles(file) {

  if (file.type.indexOf("image") == -1 && file.type.indexOf("pdf") == -1) {
    alert("Invalid Type!");
    $("#fileAttachment").attr("src", "blank");
    document.getElementById("fileAttachment").value = "";
    return false;
  }

  if (file.size > 10485760) {
    alert("Individual Image size should not be greater than 10 Mb!");
    $("#fileAttachment").attr("src", "blank");
    document.getElementById("fileAttachment").value = "";
    return false;
  }
  var result = $('div#result');
  if (window.FileReader && window.Blob) {
    var file = file;
    console.log('Loaded file: ' + file.name);
    console.log('Blob mime: ' + file.type);

    var reader = new FileReader();
    reader.onloadend = function(e) {
      var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
      var header = '';
      for (var i = 0; i < arr.length; i++) {
        header += arr[i].toString(16);
      }
      console.log('File header: ' + header);

      // Check the file signature against known types
      var type = 'unknown';
      switch (header) {
        case '89504e47':
          type = 'image/png';
          break;
        case 'ffd8ffe0':
        case 'ffd8ffe1':
        case 'ffd8ffe2':
          type = 'image/jpeg';
          break;
        case '25504446':
          type = 'application/pdf';
          break;
      }

      if (file.type !== type) {
        alert("File extension doesn't match the image type !");
        $("#fileAttachment").attr("src", "blank");
        document.getElementById("fileAttachment").value = "";
        console.log('Mime type detected: ' + type +
          '. Does not match file extension.');
      } else {
        console.log('Mime type detected: ' + type +
          '. Matches file extension.');
      }
    };
    reader.readAsArrayBuffer(file);

  } else {
    result
      .html('<span style="color: red; ">Your browser is not supported. Sorry.</span>');
    console
      .error('FileReader or Blob is not supported by the browser.');
  }

}
&lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/yeti/bootstrap.min.css" /&gt;
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Servlet File Upload/Download</title>
  <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
</head>

<body>
  <div class="container">
    <div style="margin: 50px">
      <!-- <h1 style="text-align:center;font-family: garamond, serif ">File Upload</h1> -->
      <h2 style="text-align: center; color: black; font-family: courier">
        Welcome!
      </h2>
      <br>
      <form id="fileUploadForm" method="post" action="fileUploadServlet" enctype="multipart/form-data">
        <div class="form_group">

          <div class="form-group">
            <label for="staticEmail" class="col-sm-0 col-form-label"><strong>User
                                Id :</strong></label>
            <div class="col-sm-0">
              <input type="text" readonly="" class="form-control-plaintext" id="staticId" name="staticId" value="" style="font-family: courier">
            </div>
          </div>
          <div class="form-group">
            <label for="exampleInputEmail1"><b><strong>Full Name :</strong></b></label> <input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter Full Name" required style="font-family: courier">
          </div>
          <br>
          <div class="form-group">
            <label for="exampleTextarea"><b><strong>File
                                    Description :</strong></b></label>
            <textarea class="form-control" id="exampleTextarea" rows="3" style="font-family: courier" name="description"></textarea>
          </div>

          <label><i>Upload File</i></label><span id="colon">: </span><input id="fileAttachment" type="file" name="fileUpload" multiple="multiple" accept="image/jpeg, image/png, .pdf" onchange="restrictTypeAndSize(this)" /> <span id="fileUploadErr"><b><i><strong>Please Choose A File!</strong></i></b></span>
        </div>
        <button id="uploadBtn" type="submit" class="btn btn-primary" onclick="return showAlert()">Upload</button>
      </form>
      <br> <br>
      <!-- List All Uploaded Files -->
      <div class="panel">
        <a id="allFiles" class="hyperLink" href="<%=request.getContextPath()%>/uploadedFilesServlet"><button
                        type="button" class="btn btn-outline-warning">List all
                        uploaded files</button></a>
      </div>
      <div class="panel">
        <a id="fileUpload" class="hyperLink" href="<%=request.getContextPath()%>/index.jsp"><button
                        type="button" class="btn btn-danger" style="float: right">Logout</button></a>
      </div>
    </div>
  </div>
</body>

</html>

【问题讨论】:

  • 欢迎来到 Stack Overflow。本质上,您将希望将文件存储在某个地方,而不是作为文件输入的一部分。这样,您可以将更多文件附加到列表中。提交表单后,您需要将文件列表构建为一个文件列表,以便通过 AJAX 上传或在后台上传。
  • &lt;input type='file'&gt;multiple 属性怎么样? documentation -- 保持简单;)
  • Twisty,截至目前,在单击“上传”后,文件将被发送到 servlet,并存储在服务器文件系统中。我想暂时只使用javascript。谢谢
  • Louys,请阅读问题,这不是我要的:)
  • @Manish 我知道,我的建议是在 JavaScript 中完成。存储一个文件数组,然后用户可以在该列表中添加更多文件,然后再将其发送到服务器。

标签: javascript html jquery forms file-upload


【解决方案1】:

从您的帖子中,尚不清楚您到底想要完成什么。我了解基本情况。只是不清楚您尝试了什么或希望用户做什么。

我首先清理了一些代码。请考虑以下内容。

$(function() {
  function restrictTypeAndSize(o, t, s) {
    var r = [];
    if (t == undefined) {
      t = "image/jpeg";
    }
    if (s == undefined) {
      s = 10485760;
    }
    $.each(o.files, function(i, f) {
      if (t.indexOf(f.type) < 0) {
        r.push($.extend({}, f, {
          error: "Incorrect Type"
        }));
      } else if (f.size > s) {
        r.push($.extend({}, f, {
          error: "File Size"
        }));
      } else {
        writeFiles(f);
        r.push($.extend({}, f, {
          error: false
        }));
      }
    });
    return r;
  }

  function writeFiles(file) {
    var result = $('div#result');
    if (window.FileReader && window.Blob) {
      var file = file;
      console.log('Loaded file: ' + file.name);
      console.log('Blob mime: ' + file.type);

      var reader = new FileReader();
      reader.onloadend = function(e) {
        var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
        var header = '';
        for (var i = 0; i < arr.length; i++) {
          header += arr[i].toString(16);
        }
        console.log('File header: ' + header);

        // Check the file signature against known types
        var type = 'unknown';
        switch (header) {
          case '89504e47':
            type = 'image/png';
            break;
          case 'ffd8ffe0':
          case 'ffd8ffe1':
          case 'ffd8ffe2':
            type = 'image/jpeg';
            break;
          case '25504446':
            type = 'application/pdf';
            break;
        }

        if (file.type !== type) {
          alert("File extension doesn't match the image type !");
          $("#fileAttachment").attr("src", "blank");
          $("#fileAttachment").val("");
          console.log('Mime type detected: ' + type +
            '. Does not match file extension.');
        } else {
          console.log('Mime type detected: ' + type +
            '. Matches file extension.');
        }
      };
      reader.readAsArrayBuffer(file);

    } else {
      result
        .html('<span style="color: red; ">Your browser is not supported. Sorry.</span>');
      console
        .error('FileReader or Blob is not supported by the browser.');
    }
  }

  $("#fileAttachment").change(function(e) {
    var results = restrictTypeAndSize(this, $(this).attr("accept"));
    console.log(results);
  });
});
&lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/yeti/bootstrap.min.css" /&gt;
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>

<div class="container">
  <div style="margin: 50px">
    <h2 style="text-align: center; color: black; font-family: courier">Welcome!</h2>
    <br>
    <form id="fileUploadForm" method="post" action="fileUploadServlet" enctype="multipart/form-data">
      <div class="form_group">
        <div class="form-group">
          <label for="staticEmail" class="col-sm-0 col-form-label"><strong>User Id :</strong></label>
          <div class="col-sm-0">
            <input type="text" readonly="" class="form-control-plaintext" id="staticId" name="staticId" value="" style="font-family: courier">
          </div>
        </div>
        <div class="form-group">
          <label for="exampleInputEmail1"><b><strong>Full Name :</strong></b></label> <input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter Full Name" required style="font-family: courier">
        </div>
        <br>
        <div class="form-group">
          <label for="exampleTextarea"><b><strong>File Description :</strong></b></label>
          <textarea class="form-control" id="exampleTextarea" rows="3" style="font-family: courier" name="description"></textarea>
        </div>
        <label><i>Upload File</i></label><span id="colon">: </span><input id="fileAttachment" type="file" name="fileUpload" multiple="multiple" accept="image/jpeg, image/png, application/pdf" /> <span id="fileUploadErr"><b><i><strong>Please Choose A File!</strong></i></b></span>
      </div>
      <button id="uploadBtn" type="submit" class="btn btn-primary" onclick="return showAlert()">Upload</button>
    </form>
    <br> <br>
    <div class="panel">
      <a id="allFiles" class="hyperLink" href="<%=request.getContextPath()%>/uploadedFilesServlet"><button type="button" class="btn btn-outline-warning">List all uploaded files</button></a>
    </div>
    <div class="panel">
      <a id="fileUpload" class="hyperLink" href="<%=request.getContextPath()%>/index.jsp"><button type="button" class="btn btn-danger" style="float: right">Logout</button></a>
    </div>
  </div>
</div>

由于您的文件输入中有multiple,因此用户已经可以添加多个文件。这一切似乎都有效,但我看不到所选文件在本地存储的位置,因此用户可以选择更多文件。此时用户应该怎么做?他们怎么知道他们已经选择了哪些文件?如果他们想删除文件怎么办?

【讨论】:

  • 非常感谢您提供这个更简洁的版本。这是我的代码,我可以一次添加多个文件并将它们提交到 Servlet(我在 Eclipse IDE 中使用 Java 和 Tomcat 服务器)。我的问题是,如果我再次单击选择文件按钮,以前的文件会被覆盖,并且只会上传新选择的文件。我不希望这种情况发生。
  • Twisty,我有代码可以完成工作并将文件保存在数组中,如您所说,但使用 ajax 提交它们。我希望他们使用表单发布请求本身提交。我不知道如何根据我的要求调整代码。如果你能帮我解决这个问题,那将是一个很大的帮助。这是代码的链接——plnkr.co/edit/yTPAY41kZfhBD9kouoPQ?preview
  • @Manish 您必须在发布表单之前重建表单数据或附加它。我会看看我是否可以放在一起并举例说明。请使用您当前的代码示例更新您的 OP。
  • 当然。谢谢。
  • Twisty,我终于解决了。我创建了一个隐藏的输入字段和一个可见的按钮。单击按钮时,会触发输入字段并接受文件。除此之外,我创建了一个新的输入标签并“appendChild”-ed它,然后在下一个按钮上单击这个新的输入字段被触发等等..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
相关资源
最近更新 更多