How to check duplicate of my input file upload?
Asked Answered
S

3

6

I have this form which has a button for file upload. When you select a file it shows at upload_prev div. My problem is that when I try to select the same file nothing happens. I would like a validation or kind of non duplication function to run. I did that. I tried many things and methods like using child nodes and seeing if the inner text is the same. I tried to loop using jquery each and getting the value, but all of them failed. I want to display a message that this file is already in the Box of upload_prev when I select it again.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">

  <script type="text/javascript" src="https://code.jquery.com/jquery-1.10.1.js"></script>

      <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css">

      <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css">

  <style type="text/css">
    .fileUpload {
  position: relative;
  overflow: hidden;
  margin: 10px;
}

.fileUpload input.upload {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  padding: 0;
  font-size: 20px;
  cursor: pointer;
  opacity: 0;
  background-color: #fff;
  filter: alpha(opacity=0);
}

.buttonwrap {
  text-align: center;
  padding-top: 20px;
  float: left;
  display: block;
}

.buttonsend:hover {
  background-color: rgba(255, 255, 255, 0.2);
  color: #225C51;
}

.buttonsend {
  text-decoration: none;
  color: #fff;
  font-size: 18px;
  padding-top: 5px;
  padding-bottom: 5px;
  padding-left: 10px;
  padding-right: 10px;
  background-color: rgba(72, 133, 130, .5);
}

span {
  float: left;
  display: flex;
  width: 100%;
}

p.closed {
  margin: 0 0 0 7px;
  cursor: pointer;
}

  </style>

  <title></title>

<script type='text/javascript'>//<![CDATA[

$(window).load(function(){  
//  TO CLOSE THE SLECTED FILE
$(document).on('click', '.close', function() {
  $(this).parents('span').remove();
})

//JUST TO PUT A VALUE IN THE BOX WHICH HAS 
document.getElementById("uploadBtn").onchange = function() {
  document.getElementById("uploadFile").value = this.value;
};

document.getElementById('uploadBtn').onchange = uploadOnChange;
//document.getElementById('uploadBtn').onchange = myFunction;


function uploadOnChange() {

  var filename = this.value;
  var lastIndex = filename.lastIndexOf("\\");
  if (lastIndex >= 0) {
    filename = filename.substring(lastIndex + 1);
  }


//  alert (filename);

  var files = $('#uploadBtn')[0].files;

  for (var i = 0; i < files.length; i++) {
    $("#upload_prev").append('<span>' + '<div class="hesh">' + files[i].name +'</div>' + '<p class="close">X</p></span>');
  }
  document.getElementById('filename').value = filename;

        document.getElementById("demo").innerHTML = files.length;

}


});//]]> 

</script>


</head>

<body>
  <FORM METHOD="post" ACTION="" ENCTYPE="multipart/form-data">
<!--  <input id="uploadFile" placeholder="Add files from My Computer" class="steptextboxq3" />-->
  <div class="fileUpload btn btn-primary">
    <span>Browse</span>
    <input id="uploadBtn" type="file" class="upload" multiple="multiple" name="browsefile" />
  </div>
  <input id="filename" type="text" />

  <div id="upload_prev"></div>


  <div style="clear:both;"></div>
  <div class="buttonwrap">
    <a href="contactus.html" class="buttonsend" style="float:right;">Send </a> </div>
</FORM>

    <p id="demo"></p>

</body>

</html>

This is my fiddle. How can I find a way to do this.

https://jsfiddle.net/Lc5gb7c9/

Sophiasophie answered 19/6, 2016 at 3:33 Comment(3)
Is requirement to prevent the same file from being uploaded more than once?Pentheus
yes i want to check in my view if this file name available or not. if available an alert will come the file is already in the list if not the file get added in the view.Sophiasophie
Is requirement to also upload selected files?Pentheus
P
6

You can create an array to store files[i].name, use Array.prototype.indexOf() to check if file name has been added to array, if true call alert(), else add file name to array. You can reset array to [] at any point during process.

Note, <div> and <p> elements are not valid content of <span> element

// outside of `onchange`
var arr = [];

for (var i = 0; i < files.length; i++) {
  if (arr.indexOf(files[i].name) === -1) { 
  arr.push(files[i].name)
    $("#upload_prev").append('<div>' 
     + '<div class="hesh">' 
     + files[i].name + '</div>' 
     + '<p class="close">X</p></div>');
  } else {
    alert(files[i].name + " already selected")
  }
}

jsfiddle https://jsfiddle.net/Lc5gb7c9/2/

Pentheus answered 19/6, 2016 at 4:19 Comment(3)
thank you so much it really worked and i cant believe, Thank you again i have a small question why you did this ? indexOf(files[i].name) === -1 could you please confirm me if what i understand , you did it so we make sure that its is not in our array is that right ?Sophiasophie
@Sophiasophie Yes, if files[i].name is not present in arr array, push file name to arrayPentheus
I have a similar issue. The difference is that I allow user to select images from multiple times and each time a new set of files are found I want to append them to a list and show them the same. In this case will using name work ? Same file name can be present in different folders, the files with same name can actually be different in different folders ? Is is possible to check these cases ?Biliary
I
9

There is a low chance that a file with same name, size, type, modified time to repeat and have different content

const existingFiles = []

function findFile(file) {
  return existingFiles.find(function(existingFile) {
    return (
      existingFile.name         === file.name &&
      existingFile.lastModified === file.lastModified &&
      existingFile.size         === file.size &&
      existingFile.type         === file.type
    )
  })
}

const input = document.querySelector('input')

input.addEventListener('change', function(e) {
  const files = e.target.files
  Array.from(files).forEach(function(file) {
    const existingFile = findFile(file)
    
    if (existingFile) {
      console.error('Existing file: ', existingFile)
      return
    }
    
    existingFiles.push(file)
    console.warn('Added file: ', file)
  })
})
<input type="file" />
Immortalize answered 29/11, 2018 at 14:37 Comment(0)
P
6

You can create an array to store files[i].name, use Array.prototype.indexOf() to check if file name has been added to array, if true call alert(), else add file name to array. You can reset array to [] at any point during process.

Note, <div> and <p> elements are not valid content of <span> element

// outside of `onchange`
var arr = [];

for (var i = 0; i < files.length; i++) {
  if (arr.indexOf(files[i].name) === -1) { 
  arr.push(files[i].name)
    $("#upload_prev").append('<div>' 
     + '<div class="hesh">' 
     + files[i].name + '</div>' 
     + '<p class="close">X</p></div>');
  } else {
    alert(files[i].name + " already selected")
  }
}

jsfiddle https://jsfiddle.net/Lc5gb7c9/2/

Pentheus answered 19/6, 2016 at 4:19 Comment(3)
thank you so much it really worked and i cant believe, Thank you again i have a small question why you did this ? indexOf(files[i].name) === -1 could you please confirm me if what i understand , you did it so we make sure that its is not in our array is that right ?Sophiasophie
@Sophiasophie Yes, if files[i].name is not present in arr array, push file name to arrayPentheus
I have a similar issue. The difference is that I allow user to select images from multiple times and each time a new set of files are found I want to append them to a list and show them the same. In this case will using name work ? Same file name can be present in different folders, the files with same name can actually be different in different folders ? Is is possible to check these cases ?Biliary
W
0

I think you're running into issues with how your assigning your files to the dom. Remember FileLists are read only, meaning you can't select multiple files then keep going and append them to an existing element.

But you CAN append them to a JavaScript array:

files=[]; files.push(fileList);

So, I've edited your JSFiddle to include this functionality, as well as the check you were asking for:

https://jsfiddle.net/Lc5gb7c9/3/

I would recommend you look at: http://blog.teamtreehouse.com/uploading-files-ajax for the way to upload via Ajax, as you'll need to create the formData object and then loop through your uploaded_files array and append them to the correct formData key. They are getting file from the html element, but you already have file in the uploaded_files array, so you would do it like:

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

Once that's done, you can make your ajax call.

Waft answered 19/6, 2016 at 4:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.