0

I'm trying to combine two concepts. This code works...

HTML

  <input type="file" name="files" multiple>
     <ul id="file_list">
       <ul id="file_names">
       </ul>
      </ul>

Javascript

  const dt = new DataTransfer();

  $("#my_files").on('change', function(e){
   for(var i = 0; i < this.files.length; i++){
     let filearea = $('<ul/>', {class: 'attachmentname3'}),
         fileName = $('<ul/>', {class: 'attachmentname3', text: this.files.item(i).name});
     filearea.append('<ul class="button125">Delete</ul></ul></ul>')
       .append(fileName);
   $("#file_list > #file_names").append(filearea);
   };
   for (let file of this.files) {
   dt.items.add(file);
   }
   this.files = dt.files;
   });

Essentially I'm trying to create a list of attachments based on the user clicking to attach multiple files....This totally works and has been working well.

I'm trying to incorporate some logic so that if a user clicks on a duplicate file I can send an alert at the time of the user clicking on the duplicate file.

I've been using this solution to try to guide my solution...

Input file avoid duplicates

But I can't quite make it out....I do have a solution that is close to working I think...

  const dt = new DataTransfer();

  $("#my_files").on('change', function(e){
   var arr = [];
   var fileInputs = document.querySelectorAll(".attachmentname3");
   fileInputs.forEach(function(input){
    if(arr.length == 0){
      arr.push(input.files[0].name);
      let filearea = $('<ul/>', {class: 'attachmentname3'}),
          fileName = $('<ul/>', {class: 'attachmentname3', text: input.files[0].name});
          filearea.append('<ul class="button125">Delete</ul></ul></ul>').append(fileName);
   $("#file_list > #file_names").append(filearea);
   for (let file of input.files) {
   dt.items.add(file);
   }
   input.files = dt.files;

   } else {
     if(arr.indexOf(input.files[0].name) > -1){
       e.preventDefault();
       alert("You can not send two or more same files.");
     } else {
       arr.push(input.files[0].name);
       let filearea = $('<ul/>', {class: 'attachmentname3'}),
           fileName = $('<ul/>', {class: 'attachmentname3', text: input.files[0].name});
           filearea.append('<ul class="button125">Delete</ul></ul></ul>').append(fileName);
    $("#file_list > #file_names").append(filearea);
    for (let file of input.files) {
    dt.items.add(file);
    }
    input.files = dt.files;
     }
    };
  });
 });

I'm new to Javascript...or not very good at it....I realize in one case I'm referencing $this...and the other I'm using input. I suspect that I'm confusing these two....

I'm currently getting an error on this line...

   arr.push(input.files[0].name);

I've been trying various approaches to solve this for the last 3 days and just can't quite figure out how to trigger the duplicate message once the user clicks on a duplicate. Thanks in advance for any thoughts.

Steve Smith
  • 1,019
  • 3
  • 16
  • 38
  • Your input element looks like this: ``. You can select multiple files. But how do you end in a situation where you have more files that are the same? You can only select a file once. In the question that you link to there are more input[type=file] elements -- in that situation the same file can be selected more than once. – chrwahl Jul 03 '23 at 15:08
  • It looks like they are trying to prevent uploads with the same file *name*. – kmoser Jul 03 '23 at 15:33

1 Answers1

0

The error you are getting could be because of files[0] being undefined. Change to

  if(input.files?.[0]) arr.push(input.files[0].name);

Also, to be more precise, you may want to add file name as well as size to check for uniqueness.

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122