I have found a code on internet to upload multiple images. While you select the image, it will show the selected image just below as preview, now the problem is what if I selected the wrong image and I want to remove that particular image, also no more than 4 image should be allowed
hope you get what I want to say below is the code
<input type="file" multiple id="gallery-photo-add">
<div class="gallery"></div>
and jquery for the code is
$(function() {
// Multiple images preview in browser
var imagesPreview = function(input, placeToInsertImagePreview) {
if (input.files) {
var filesAmount = input.files.length;
for (i = 0; i < filesAmount; i++) {
var reader = new FileReader();
reader.onload = function(event) {
$($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
}
reader.readAsDataURL(input.files[i]);
}
}
};
$('#gallery-photo-add').on('change', function() {
imagesPreview(this, 'div.gallery');
});
});
The file list of HTML5 file input is readonly. So it's not possible to remove a single file out from a multiple file selection.
It's perfectly fine to empty a file input by resetting the form. You just can't modify it. So if you use 4 seperate single file selections, it's a simple matter of clearing the one that's being removed by the user:
HTML:
<form>
<input type="file" name='images[]' class="gallery-photo-add" id='image1' />
<input type="file" name='images[]' class="gallery-photo-add" id='image2' />
<input type="file" name='images[]' class="gallery-photo-add" id='image3' />
<input type="file" name='images[]' class="gallery-photo-add" id='image4' />
</form>
<div class="gallery"></div>
JS:
$(function() {
// Multiple images preview in browser
var imagesPreview = function(placeToInsertImagePreview) {
// Empty preview so we can safely rebuild it
$(placeToInsertImagePreview).empty();
// Get all files
var elems = document.getElementsByClassName("gallery-photo-add");
// Loop through each file and append them to the preview if available
for (i = 0; i < elems.length; i++) {
if (elems[i].files.length != 0) {
var reader = new FileReader();
var id = $(elems[i]).attr('id');
reader.onload = (function(id) {
return function(e){
$($.parseHTML('<img>')).attr({
'src' : e.target.result,
'data-id' : id
}).appendTo(placeToInsertImagePreview);
}
})(id);
reader.readAsDataURL(elems[i].files[0]);
}
}
};
// Temporarely wrap a form element around the input to reset it
window.reset = function(e) {
e.wrap("<form>").closest('form').get(0).reset();
e.unwrap();
}
$('div.gallery').on('click', 'img', function() {
var id = $(this).attr("data-id");
reset($('#'+id));
$(this).remove();
});
$('.gallery-photo-add').on('change', function() {
imagesPreview('div.gallery');
});
});
You can test it here: https://jsfiddle.net/81nytqsc/2/
$('div.gallery').on('click','img',function(){
var files= $('#gallery-photo-add).get(0).files;
for(i=0;i<files.length;i++){
if(files[i]==$(this).attr('src')){
files= jQuery.grep(files, function(value) {
return value != files[i];
}
}
}
$(this).remove();
});
Related
This question already has answers here:
Javascript - How to extract filename from a file input control
(15 answers)
Closed 2 years ago.
Trying to display the file names from a file input element. I am able to console log when I am inside the onchange function but not the addeventlistener. In the code below the console.log('Inside change eventlistener'); will not execute. I can I both log being inside the event listener and get the file names in order to display them? Here is the codepen of the code. Thank you.
html:
<label>Attachments</label>
<div>
<input type="file" class="form-control input-lg" name="attachments" id="attachments" multiple onchange="getFileData()">
</div>
js:
function getFileData() {
console.log('Inside getFileData()...')
var elem = document.getElementById('attachments');
console.log(elem);
elem.addEventListener('change', function(e) {
console.log('Inside change eventlistener');
console.log(e.target);
var fileName = e.target.files[0].name;
console.log(fileName);
});
};
UPDATE:
I am able to console the file names but still not able to display the names to the user. How do I show the names of the files within on the html page. elem.value = ... does not work.
Updated JS:
function getFileData() {
console.log('Inside getFileData()...')
var elem = document.getElementById('attachments');
var files = document.getElementById('attachments').files;
var names = '';
for (let i = 0; i < files.length; i++) {
console.log(files[i].name);
names += files[i].name;
}
console.log(names);
console.log(Object.keys(elem));
//elem.setAttribute('value', names);
};
You may try something like this
var elem = document.getElementById('attachments');
elem.addEventListener('change', getFileData);
function getFileData() {
const files = this.files;
const list = document.getElementById("result");
let child;
for ( let i = 0; i < files.length; i++) {
child = document.createElement("li")
child.textContent = files[i].name;
list.append(child);
}
}
<label>Attachments</label>
<div>
<input type="file" class="form-control input-lg" name="attachments" id="attachments" multiple>
</div>
<ul id="result"></ul>
given this html snippet
<div id="imageSelection" class="form-group">
#Html.LabelFor(m => m.PostedFiles,"Select images/videos" ,new {id="fileSelect",#for="fileElem", #class="form-control btn btn-sm btn-success", style="width:144px;" })
#Html.TextBoxFor(m => m.PostedFiles, new
{
type = "file",
id = "fileElem",
#class = "col-md-10 form-control",
style="display:none;",
multiple = "multiple",
accept = "image/*",
onchange = "handleFiles(this.files)"
})
</div>
which works fine, you click the button, the file picker opens, you select some files and click the button to close the file picker. The onchange event is not firing (onchange is the event suggested by the example here)
It generates this html in the page
<div id="imageSelection" class="form-group">
<label class="form-control btn btn-sm btn-success" for="fileElem" id="fileSelect" style="width:144px;">Select images/videos</label>
<input accept="image/*" class="col-md-10 form-control" id="fileElem" multiple="multiple" name="PostedFiles" onchange="handleFiles(this.files)" style="display:none;" type="file" value="" />
</div>
Here is the script
<script>
$(document)
.ready(function () {
//element variables for the thumbnail display
var dropbox = $("#dropbox"),
filePropertyDisplay = $("#loadingImageFileProperties"),
fileName = $("#dd_filename"),
fileSize = $("#dd_filesize"),
fileType = $("#dd_filetype"),
gallery = $("#imageGallery"),
uploading = $("#imageUploading"),
fileSelect = document.getElementById("fileSelect"), //$("#fileSelect"),
fileElem = document.getElementById("fileElem"), //$("#fileElem"),
messages = $("#messageArea");
gallery.hide();
uploading.hide();
//add event listeners to handle events
dropbox.on("dragenter", function(e) {
e.stopPropagation();
e.preventDefault();
});
dropbox.on("dragover", function (e) {
e.stopPropagation();
e.preventDefault();
});
dropbox.on("drop", function (e) {
e.stopPropagation();
e.preventDefault();
var dt = e.originalEvent.dataTransfer;
var files = dt.files;
handleFiles(files);
});
fileSelect.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault(); // prevent navigation to "#"
}, false);
//fileSelect.on("click", function (e) {
// if (fileElem) {
// fileElem.click();
// }
// // prevent navigation to "#"
// e.preventDefault();
//});
function handleFiles(files) {
alert(files.length);
}
});
</script>
I originally was trying to stick with JQuery but couldn't get that to work with .on() either, so i reverted back to Javascript, per the example, but that doesn't work either.
The drop functionality works, and calls handleFiles but the fileElem onchange method doesn't fire.
EDIT:
Sorry that made me realize that the problem was reading the files you've selected instead of just getting the code to work.
I've just added:
var files = $(this)[0].files;
To get the files collection the user selected (it could be one or more);
and then:
for (var i = 0; i < files.length; i++) {
alert(files[i].name);
}
loop through all the files selected and just get the name of it. You can also read .size if you need to.
This will the proper way to handle what you are trying to achieve.
$(document)
.ready(function () {
//element variables for the thumbnail display
var dropbox = $("#dropbox"),
filePropertyDisplay = $("#loadingImageFileProperties"),
fileName = $("#dd_filename"),
fileSize = $("#dd_filesize"),
fileType = $("#dd_filetype"),
gallery = $("#imageGallery"),
uploading = $("#imageUploading"),
fileSelect = document.getElementById("fileSelect"), //$("#fileSelect"),
fileElem = document.getElementById("fileElem"), //$("#fileElem"),
messages = $("#messageArea");
gallery.hide();
uploading.hide();
//add event listeners to handle events
dropbox.on("dragenter", function(e) {
e.stopPropagation();
e.preventDefault();
});
dropbox.on("dragover", function (e) {
e.stopPropagation();
e.preventDefault();
});
dropbox.on("drop", function (e) {
e.stopPropagation();
e.preventDefault();
var dt = e.originalEvent.dataTransfer;
var files = dt.files;
handleFiles(files);
});
fileSelect.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault(); // prevent navigation to "#"
}, false);
$('#fileElem').on('change',function(e){
var files = $(this)[0].files;
for (var i = 0; i < files.length; i++) {
alert(files[i].name);
//alert(files[i].size);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="imageSelection" class="form-group">
<label for="fileElem" class="form-control btn btn-sm btn-success", style="width:144px;" id="fileSelect">Select images/videos</label>
<input type="file" id = "fileElem" class = "col-md-10 form-control"
style="display:none;"
multiple = "multiple"
accept = "image/*"
</div>
I need one help.I have one image icon, when user will select that icon the file dialog will open and user will select the image.After selecting the image the image should display on that image icon.I am explaining my code below.
<div class="image-upload">
<label for="bannerimage">
<img src="{{attachImage}}"/>
</label>
<input type="file" data-size="lg" name="bannerimage" id="bannerimage" ng-model="file" ngf-pattern="'image/*'" accept="image/*" ngf-max-size="2MB" ngf-min-height="100" ngf-resize="{width: 100, height: 100}" custom-on-change="uploadFile" required="required" ngf-select="onFileSelect($file);" ngf-multiple="true">
</div>
my controller side code is given below.
$scope.attachImage="upload/logo.png";
$scope.uploadFile = function(event){
console.log('event',event.target.files);
var files = event.target.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = $scope.imageIsLoaded;
reader.readAsDataURL(file);
}
};
$scope.imageIsLoaded = function(e){
$scope.$apply(function() {
//var data={'image':e.target.result};
// $scope.stepsModel.push(data);
//$scope.myImage=e.target.result;
$scope.attachImage='';
$scope.attachImage=$scope.myImage;
});
});
Here i need when user will select the image the image will display on that particular image icon.Please help me.
I believe you need to use reader.onloadend instead of reader.onload
reader.onloadend = function () {
// set $scope.attachImage to reader.result;
}
I have problem with uploading files in my existing form.
What I am looking for is script that will make possible to add multiple files (max 5) and you can add at once from one to five files. If you add one by one, I need it to add new, not replace the previous one.
I got form looking like this:
Name
LastName
Email
Phone number
Interests
Files
and filenames are created like this: name+lastname+phonenumber+filename
And I add entry to database with path of everyfile - this is done and I need only good drag and drop zone.
I need it to show added filename and make it possible to delete added file from queue.
But I don't want files to upload when I add them. I want it to upload when I submit my whole form so filename can be created and path to DB can be added.
Could anyone please provide me good script to that, or based on my scripts from two topics I mentioned before make it avaiable to do what I want?
I was able to add 5 files one by one and I described it here:
HTML Add multiple file to the input
Also I was able to add more at once what I described here:
https://stackoverflow.com/questions/30499388/dropzone-js-into-another-form
I think that this example help you.
This app allow drag and drop files to gray zone (1 or 5)
If you click on the file name, it removes file from the list.
function init() {
//get dragdrop element
var dd = document.getElementById("dragdrop");
//get files element
$files = document.getElementById("files");
dd.ondragover = stop;
dd.ondragleave = stop;
if ('FileReader' in window) {
document.ondrop = dragAccept;
}
//get form
var $form = document.querySelector("form");
//catch on submit
$form.onsubmit = function (e) {
stop(e);
var fd = new FormData();
//apend files to FormData
for (var i in files){
var file = files[i].file;
var filename = file.name;
var name = "file";
fd.append(name, file, filename);
};
//append inputs to FormData
var $inputs = $form.querySelectorAll("input");
for (var i = 0; i < $inputs.length; i++) {
var $input = $inputs[i];
fd.append($input.getAttribute("name"), $input.value);
}
//Send data
var xhr = new XMLHttpRequest();
xhr.open('POST', '/echo/html/', true);
xhr.send(fd)
}
}
function stop(e) {
e.stopPropagation();
e.preventDefault();
}
function dragAccept(e) {
stop(e);
if (e.dataTransfer.files.length > 0)
for (var i = 0; i < e.dataTransfer.files.length; i++) {
addFile(e.dataTransfer.files[i]);
}
}
//file list store
var files = {};
// html element of file list
var $files = null;
//add file to file list
function addFile(file) {
//add files with diferent name, max files count 5
if (!(file.name in files) && Object.keys(files).length < 5) {
var div = createFile(file.name);
$files.appendChild(div);
files[file.name] = {
file: file,
element: div
}
}
}
//create html element with file name
function createFile(name) {
var div = document.createElement("div");
div.innerText = name;
var input = document.createElement("input")
//remove on click
div.addEventListener("click", function () {
$files.removeChild(this);
delete files[name];
})
return div;
}
window.addEventListener("load", init);
<form method="post" enctype="multipart/form-data" action="">
<label>Name<input name="name" /></label>
<label>Last name<input name="lastName" /></label>
<label>Email<input name="email" /></label>
<div id="dragdrop" style="width: 300px; height: 300px; background-color:lightgray">Drag drop zone</div>
<div id="files"></div>
<button type="submit">Send</button>
</form>
I have the following jquery enabled javascript:
<form>
<input type="file">
</form>
jQuery(function($) {
$('form').delegate('input[type=file]', 'change', function() {
var form = $(this).closest('form');
form.append('<input type="file">');
});
});
it will dynamically add a file upload field as the user add files they want to upload. how can I limit it to images only, and stop adding new fields after they've added 5 images?
I'm trying to switch from having numerous field, which I validated as images like so:
var valid_extensions = /(.gif|.jpg|.jpeg|.png)$/i;
function CheckExtension(fld){
if (valid_extensions.test(fld.value)) return true;
alert('only gif, png or jpg formats are allowed!');
fld.select();
fld.value="";
fld.focus();
return false;
}
<input type="file" onChange="return CheckExtension(this);">
Knowing your goal, you should rewrite your function:
var checkExtension;
var valid_extensions = /(.gif|.jpg|.jpeg|.png)$/i;
var limit = 5; // define the limit of rows here
var i = 0;
$('form').delegate("input[type=file]", "change", function () {
if (i < limit && checkExtension(this)) {
$('form').append( $("<input>").attr({type: "file"}) );
}
i++;
});
checkExtension = function (fld) {
if (valid_extensions.test(fld.value)) return true;
alert('only gif, png or jpg formats are allowed!');
fld.select();
fld.value="";
fld.focus();
return false;
}
You can use HTML5's accept attribute to specify which mimetypes you will accept.
For your limit, a simple incrementing integer and a ternary should handle it, like so:
var i = 0;
$('form').delegate('input[type=file]', 'change', function() {
var form = $(this).closest('form');
i < 5 ? form.append('<input type="file">') : "";
i++;
});
If you want to use javascript, a google search returned this Stack Overflow answer:
Preview an image before it is uploaded
With the help of #Austin, here is the final code that works for me. it will dynamically create a file input field and accept images only. I'm still testing, but this should work in all browsers that support js.
<form>
<input type="file">
<script>
jQuery(function($) {
var checkExtension;
var valid_extensions = /(.gif|.jpg|.jpeg|.png)$/i;
var limit = 5; // define the limit of rows here
var i = 1;
$('form').delegate("input[type=file]", "change", function () {
if (i < limit && checkExtension(this)) {
$('form').append( $('<input type="file">') );
}
i++;
});
checkExtension = function (fld) {
if (valid_extensions.test(fld.value)) return true;
alert('only gif, png or jpg formats are allowed!');
fld.select();
fld.value="";
fld.focus();
return false;
}
});
</script>
</form>