I have a function that uploads and image and adds a preview to this image, and i have two buttons, when i click on the first one it clicks on the input type file and opens it, a
One common problem I see with this file previews are that most of them are unable to correctly render jpg's rotated with exif orientation
The second thing is that it's better to use URL.createObjectURL rather then using a base64 dataURL. That also raises an other issue and that is that most developers forget to revoked objectURL's
That is why i have created Screw-FileReader so you can easily call blob.image()
and get a image back with a object url that is automatically revoked and also has a exif auto-rotation built in using canvas.
var $file = $('#filepicker').on('change', preview);
$('.uploader button').click(function() {
$file.click()
})
function preview(evt) {
var preview = document.querySelector('.preview')
Array.from(this.files).forEach(function(file) {
file.image().then(function(img) {
preview.appendChild(img)
}, function() {
// err not an image...
})
})
}
input {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/jimmywarting/Screw-FileReader/master/index.js"></script>
<div class="uploader">
<button type="button">Open uploader</button>
<input id="filepicker" type="file" multiple accept="image/*">
<div class="preview"></div>
</div>
the third thing i notis with Soltani Neji answer was that when you click dublicate button before the first upload button it dose unexpected things. it don't keep track of the index so well.
Now to my suggestions: Use the multiple
attribute instead and just have one button to make it simpler. it also helps to add the accept="image/*"
to filter out only images
Duplication the element and the script together will be helpful
check this i got it working as you want (took me a good time)
var i = 0;
$('#inputfile' + i).change(function() {
console.log(i);
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
});
function imageIsLoaded(e) {
console.log(i);
$('#ImgUpload' + i).attr('src', e.target.result);
};
function upload(id) {
$('#' + id).click();
};
$('#duplicate').click(function() {
i++;
var newelement =
'<br><div class="uploader">' +
'<button type="button" class="uploadimg" onclick="upload(\'inputfile' + i + '\')">Open uploader</button>' +
'<input type="file" id="inputfile' + i + '" >' +
'<img id="ImgUpload' + i + '" alt="Your Image" />' +
'<br><br>' +
'<script>$(\'#inputfile' + i + '\').change(function() { ' +
'console.log(i);' +
'if (this.files && this.files[0]) {' +
'var reader = new FileReader();' +
'reader.onload = imageIsLoaded;' +
'reader.readAsDataURL(this.files[0]);' +
'}' +
'});</sc'+'ript></div>';
$(newelement).insertBefore("#duplicate");
});
input {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="uploader">
<button type="button" onclick="upload('inputfile0')">Open uploader</button>
<input type="file" id="inputfile0">
<img id="ImgUpload0" alt="Your Image" />
<br>
<br>
</div>
<button type="button" id="duplicate">Duplicate button</button>
you can append the element instead of duplicating it. you can change the classes and ids using variables.
$('.duplicate').click(function() {
var newClass="new-class";
var toAppendElement = '<div class="uploader">' +
'<button type="button" class="uploadimg '+newClass+'">Open uploader</button>' +
'<input type="file">' +
'<img id="ImgUpload" alt="Your Image" />' +
'<br><br></div>';
$(".cloned").append(toAppendElement);
})
http://jsfiddle.net/8h3gcyhz/