how to use one function for multiple file upload buttons - javascript

I have four upload buttons with their respective ids.
<div class="card-body">
<div class="container">
<div class="row">
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader" value="0" max="100">0%</progress>
<input type="file" id="fileButton" value="upload" />
</div>
</div>
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader" value="0" max="100">0%</progress>
<input type="file" id="fileButton" value="upload" />
</div>
</div>
</div>
<br>
<div class="row">
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader2" value="0" max="100">0%</progress>
<input type="file" id="fileButton2" value="upload" />
</div>
</div>
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader3" value="0" max="100">0%</progress>
<input type="file" id="fileButton3" value="upload" />
</div>
</div>
</div>
</div>
</div>
I am able to upload to firebase storage through one button with this function
$("#fileButton").on('change', function(e) {
var file = evt.target.files[0];
var storageRef = firebase.storage().ref('img/' + file.name);
var task = storageRef.put(file);
task.on('state_changed', function progress(snapshot) {
var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
uploader.value = percentage;
}, function error(err) {
}, function complete() {
});
})
the function works great but what I want to do is to prevent duplicating functions. I want to use that function for each of the upload input and uploader status.
I tried this but it does not work
$("#fileButton0", "#fileButton1", "#fileButton2", "#fileButton3").on('change'
how could I use the same function for each of the upload and uploader?
here is the jsfiddle
https://jsfiddle.net/dhs8g7fb/

Here is a working code !
const FileBtns = document.querySelectorAll("input[type='file'][id]");
FileBtns.forEach(function(btn) {
btn.addEventListener("change", function(e) {
console.log(this);
var file = e.target.files[0];
var storageRef = firebase.storage().ref('img/' + file.name);
var task = storageRef.put(file);
task.on('state_changed', function progress(snapshot) {
var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
uploader.value = percentage;
}, function error(err) {
//Some error task
}, function complete() {
console.log("we dit");
});
});
});
<div class="card-body">
<div class="container">
<div class="row">
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader0" value="0" max="100">0%</progress>
<input type="file" id="fileButton0" value="upload" />
</div>
</div>
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader1" value="0" max="100">0%</progress>
<input type="file" id="fileButton1" value="upload" />
</div>
</div>
</div><br>
<div class="row">
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader2" value="0" max="100">0%</progress>
<input type="file" id="fileButton2" value="upload" />
</div>
</div>
<div class="col-6">
<div class="mainDiv" align="right">
<progress id="uploader3" value="0" max="100">0%</progress>
<input type="file" id="fileButton3" value="upload" />
</div>
</div>
</div>
</div>
</div>

Related

Javascript:: Image previews

I want to preview 4 pictures before I upload them to my laravel app.
I can see the first preview image when I upload the first picture.
But if I upload a second picture, the first preview image changes to the second picture. But I cannot see the second picture preview in the second preview field.
The same thing happens to the third and the fourth picture. Only the first preview field changes.
How can I show 4 image previews?
html
<div class="image-preview" id="imagePreview">
#if(isset($post))
<img src="" id="image-preview__image">
#else
<img src="../../blog-image/S__3530766.jpg" id="preview">
#endif
</div>
<input type="text" class="name" value="NAME">
<textarea name="profile" cols="20" rows="5" class="profile" value="profile">profile</textarea>
<div class="preview">
<input type="file" id="file" accept="image/*" name="profile_img">
<label for="file" >
Add profile photo
</label>
</div>
<div class="content-image-preview" id="imagePreview">
#if(isset($post))
<img src="" id="image-preview__image">
#else
<img src="../../LPImages/jezael-melgoza-alY6_OpdwRQ-unsplash.jpg" id="preview2">
#endif
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">
Add photo
</label>
</div>
<input type="text" value="TITLE" class="section-title">
<div class="content-image-preview" id="imagePreview">
#if(isset($post))
<img src="" id="image-preview__image">
#else
<img src="../../LPImages/jezael-melgoza-alY6_OpdwRQ-unsplash.jpg" id="preview3">
#endif
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">
Add photo
</label>
</div>
<div class="content-image-preview" id="imagePreview">
#if(isset($post))
<img src="" id="image-preview__image">
#else
<img src="../../LPImages/jezael-melgoza-alY6_OpdwRQ-unsplash.jpg" id="preview4">
#endif
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">
Add photo
</label>
</div>
javascript
const input = document.getElementById("file");
const previewImage = document.getElementById("image-preview__image");
input.addEventListener('change', function(e){
const file = this.files[0];
if (previewImage != null && previewImage.length < 1){
for (var i=0; i<previewImage.length; i+=1){
if(file) {
const reader = new FileReader();
reader.addEventListener("load", function(){
previewImage.setAttribute("src", this.result);
});
previewImage.style.display = "block";
reader.readAsDataURL(file);
} else {
previewImage.setAttribute("src", "");
}
}
}
}
);
In order to access the correct preview element you need a reliable way to query elements further up the DOM in this case - and because the HTML is not constant I modified your original slightly so that various distinct parts were separated using section tags - thus allowing a simple DOM traversal to find the correct preview img tag. In the following you'll note that I have omitted the template tags you were using
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Image previews</title>
</head>
<body>
<form method='post'>
<!--
slightly modified and without templating tags, otherwise essentially the same. ID attributes replaced with class attributes
-->
<section>
<div class="image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<input type="text" class="name" value="NAME">
<textarea name="profile" cols="20" rows="5" class="profile" value="profile">profile</textarea>
<div class="preview">
<input type="file" id="file" accept="image/*" name="profile_img">
<label for="file" >Add profile photo</label>
</div>
</section>
<section>
<div class="content-image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">Add photo</label>
</div>
</section>
<section>
<input type="text" value="TITLE" class="section-title">
<div class="content-image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">Add photo</label>
</div>
</section>
<section>
<div class="content-image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">Add photo </label>
</div>
</section>
</form>
<script>
const findsection=function(n){
while(n && n.tagName.toLowerCase()!='section')n=n.parentNode;
return n;
};
Array.from( document.querySelectorAll('input[type="file"]') ).forEach( input=>{
input.addEventListener('change',function(e){
let section=findsection( e.target );
let file=this.files[0];
let reader = new FileReader();
reader.addEventListener('load', function(){
let img=section.querySelector( 'img.image-preview__image' );
img.src=this.result;
img.width=200;
});
reader.readAsDataURL(file);
})
})
</script>
</body>
</html>
const findsection=function(n){
while(n && n.tagName.toLowerCase()!='section')n=n.parentNode;
return n;
};
Array.from( document.querySelectorAll('input[type="file"]') ).forEach( input=>{
input.addEventListener('change',function(e){
let section=findsection( e.target );
let file=this.files[0];
let reader = new FileReader();
reader.addEventListener('load', function(){
let img=section.querySelector( 'img.image-preview__image' );
img.src=this.result;
img.width=200;
});
reader.readAsDataURL(file);
})
})
<section>
<div class="image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<input type="text" class="name" value="NAME">
<textarea name="profile" cols="20" rows="5" class="profile" value="profile">profile</textarea>
<div class="preview">
<input type="file" id="file" accept="image/*" name="profile_img">
<label for="file" >Add profile photo</label>
</div>
</section>
<section>
<div class="content-image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">Add photo</label>
</div>
</section>
<section>
<input type="text" value="TITLE" class="section-title">
<div class="content-image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">Add photo</label>
</div>
</section>
<section>
<div class="content-image-preview" id="imagePreview">
<img class="image-preview__image">
</div>
<div class="preview" id="add">
<input type="file" id="file" accept="image/*" name="image">
<label for="file">Add photo </label>
</div>
</section>
you have multiple IMG elements with the same id image-preview__image.
User different ID for each element then it will work.
<input type="file" id="file" accept="image/*" name="image">
further name can not be same in multiple places.

Unable to validate the uploading image type

I am following a tutorial series to make an Android wallpaper application. For that I have to design and create the admin area where I manage the images. I got struck with image validation. I have pasted my whole code below.
<h1>Catogeries</h1>
<hr>
<div class="row">
<div class="col-lg-5">
<h1>Add new</h1>
<form class="form-group">
<div>
<label for="Catogery-name">Enter name</label>
<input type="text" class="form-control" id="Catogery-name">
<div class="invalid-feedback">Please enter a catogery name</div>
</div>
<div>
<label for="Catogery-description">Description</label>
<input type="text" class="form-control" id="Catogery-description">
<div class="invalid-feedback">Please enter the valid description</div>
</div>
<div>
<label for="Catogery-thumbnail">Thumbnail</label>
<input type="file" class="form-control" id="Catogery-thumbnail">
<div class="invalid-feedback">Please upload a valid image</div>
</div>
<div class="form-group" style="margin-top:3%">
<img src="#" id="selected-thumbnail" width="250px" height="150px">
</div>
<div class="form-group">
<div class="progress" style="margin-top:2%">
<div class="progress-bar" style="width:0%" id="upload-progress">0%</div>
</div>
</div>
<div class="btn btn-primary" type="button" id="save-catogery">Save</div>
</form>
<div id="result">
</div>
</div>
<div class="col-lg-7">
<h1>Saved Catogeries</h1>
</div>
</div>
<script>
var validImageTypes = ["image/gif", "image/jpeg", "image/png"];
$("#selected-thumbnail").hide();
function previewThumbnail(thumbnail) {
if (thumbnail.files && thumbnail.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$("#selected-thumbnail").attr('src', e.target.result);
$("#selected-thumbnail").fadeIn();
}
reader.readAsDataURL(thumbnail.files[0]);
}
}
$("#Catogery-thumbnail").change(function() {
previewThumbnail(this);
});
$("#save-catogery").click(function() {
var catName = $("#Catogery-name").val();
var desc = $("#Catogery-description").val();
var thumbnail = $("#Catogery-thumbnail").prop("files")[0];
if (!catName) {
$("#Catogery-name").addClass("is-invalid");
return;
}
if (!desc) {
$("#Catogery-description").addClass("is-invalid");
return;
}
if (thumbnail == null) {
$("#Catogery-thumbnail").addClass("is-invalid");
return;
}
if ($.inArray(thumbnail["type"], validImageTypes) < 0) {
$("#Catogery-thumbnail").addClass("is-invalid");
return;
}
});
</script>

how to use a form and controller to store inputs

I'm currently working on a web app I'm stuck on deleting the elements that I have created.
I'm using jQuery to display thumbnail pictures and I'm trying to include a hovering X to the top right corner that will on-click delete the thumbnail and the original file upload before sending the form.
This is my code:
$(document).ready(function() {
// This is where I create the thumbnail:
$('#uploadImage').on('change', function() {
resizeImages(this.files[0], function(dataUrl) {
$('#photo1').val(dataUrl);
document.getElementById("uploadPreview").src = dataUrl;
});
});
// This is where I am attempting to delete it:
$('.hiddenImages .close').on('click', function() {
var id = $(this).closest('.hiddenImages').find('img').data('id');
alert('remove picture: ' + id);
document.getElementById(".hiddenImages").remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="pictureHolders">
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview" data-id="photo-1" style="width: 100px;
height: 100px;" />
</div>
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview2" data-id="photo-2" style="width: 100px;
height: 100px;" />
</div>
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview3" data-id="photo-3" style="width:
100px; height: 100px;" />
</div>
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview4" data-id="photo-4" style="width: 100px;
height: 100px;" />
</div>
</div>
<div class="inputs">
<div> Photo 1:
<input type="text" id="desc1" name="desc1" />
<input id="uploadImage" type="file" />
</div>
<input type="hidden" class="photos" id="photo1" name="photo1" value="" />
<br/>
<div> Photo 2:
<input type="text" id="desc2" name="desc2" />
<input id="uploadImage2" type="file" />
</div>
<input type="hidden" class="photos" id="photo2" name="photo2" value="" />
<br/>
<div> Photo 3:
<input type="text" id="desc3" name="desc3" />
<input id="uploadImage3" type="file" />
</div>
<input type="hidden" class="photos" id="photo3" name="photo3" value="" />
<br/>
<div> Photo 4:
<input type="text" id="desc4" name="desc4" />
<input id="uploadImage4" type="file" />
</div>
<input type="hidden" class="photos" id="photo4" name="photo4" value="" />
<br/>
</div>
Any help would be appreciated.
You are trying to get a handle to an identifier by using a class name inside getElemlementById
You should be able to simply remove the container of the clcked x, similar to this: $(this).closest('.hiddenImages').remove();
In addition your selector for the click event on the x might need to change as you are removing the container your binding to and as such any new .hiddenImages container will not have that click event bound.
You might need to update $('.hiddenImages .close').on('click', function... to $('.pictureHolders').on('click', '.hiddenImages .close', function...
$(document).ready(function() {
// This is where I create the thumbnail:
$('#uploadImage').on('change', function() {
resizeImages(this.files[0], function(dataUrl) {
$('#photo1').val(dataUrl);
document.getElementById("uploadPreview").src = dataUrl;
});
});
// This is where I am attempting to delete it:
$('.pictureHolders').on('click', '.hiddenImages .close', function() {
$(this).closest('.hiddenImages').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="pictureHolders">
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview" data-id="photo-1" style="width: 100px;
height: 100px;" />
</div>
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview2" data-id="photo-2" style="width: 100px;
height: 100px;" />
</div>
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview3" data-id="photo-3" style="width:
100px; height: 100px;" />
</div>
<div class="hiddenImages">
<span class="close">×</span>
<img id="uploadPreview4" data-id="photo-4" style="width: 100px;
height: 100px;" />
</div>
</div>
<div class="inputs">
<div> Photo 1:
<input type="text" id="desc1" name="desc1" />
<input id="uploadImage" type="file" />
</div>
<input type="hidden" class="photos" id="photo1" name="photo1" value="" />
<br/>
<div> Photo 2:
<input type="text" id="desc2" name="desc2" />
<input id="uploadImage2" type="file" />
</div>
<input type="hidden" class="photos" id="photo2" name="photo2" value="" />
<br/>
<div> Photo 3:
<input type="text" id="desc3" name="desc3" />
<input id="uploadImage3" type="file" />
</div>
<input type="hidden" class="photos" id="photo3" name="photo3" value="" />
<br/>
<div> Photo 4:
<input type="text" id="desc4" name="desc4" />
<input id="uploadImage4" type="file" />
</div>
<input type="hidden" class="photos" id="photo4" name="photo4" value="" />
<br/>
</div>
$('.hiddenImages .close').on('click', function() {
var id = $(this).closest('.hiddenImages').find('img').data('id');
alert('remove picture: ' + id);
document.getElementById(".hiddenImages").remove();
});
become:
$('.hiddenImages .close').on('click', function() {
var img = $(this).closest('.hiddenImages').find('img');
img.remove()
});

Calculator form alternative

I have the current code below, which is working. The problem is this code will be in a form and i can't have nested forms. How do i change the code, so this works with a div parent element instead of a form?
<form>
<script type="text/javascript">
function inmet(form){
form.in2met.value = ((form.inch.value -0) * 25.4).toFixed(2)
}
</script>
<div id="calcbody">
<div class="calctitle">Convert <br />Inches to Millimetres</div>
<div class="singcalcquestion">Enter the Inches:
<input class="box1" type="text" name="inch" />
</div>
<div class="singsubmit">
<input onclick="inmet(this.form)" type="button" value="GO" />
</div>
<div class="singcalcanswer">Equals in Millimetres:<br />
<input class="calcbox2" type="text" readonly="readonly" name="in2met" />
</div>
</div>
</form>
One option would be to use Element.getElementsByClassName() or a similar method to get the input field you want:
<div id="form-root">
<script type="text/javascript">
function inmet(calcRoot){
calcRoot.getElementsByClassName('calcbox2')[0].value = ((form.inch.value -0) * 25.4).toFixed(2);
}
// example: inmet(document.getElementById('form-root'))
</script>
<div id="calcbody">
<div class="calctitle">Convert <br />Inches to Millimetres</div>
<div class="singcalcquestion">Enter the Inches: <input class="box1" type="text" name="inch" /></div>
<div class="singsubmit"><input onclick="inmet(document.getElementById('form-root'))" type="button" value="GO" /></div>
<div class="singcalcanswer">Equals in Millimetres:<br /><input class="calcbox2" type="text" readonly="readonly" name="in2met" /></div>
</div>
</div>
Not the cleanest solution, but it should do the job:
<div>
<script>
function inmet() {
document.getElementById('in2met').value = ((document.getElementById('inch').value - 0) * 25.4).toFixed(2)
}
</script>
<div id="calcbody">
<div class="calctitle">Convert <br/>Inches to Millimetres</div>
<div class="singcalcquestion">
<label for="inch">Enter the Inches:</label>
<input class="box1" type="text" name="inch" id="inch"/>
</div>
<div class="singsubmit">
<input onclick="inmet()" type="button" value="GO"/>
</div>
<div class="singcalcanswer">
<label for="in2met">Equals in Millimetres:</label>
<input class="calcbox2" type="text" readonly="readonly" name="in2met" id="in2met"/>
</div>
</div>
</div>

Div id passing to a java script

This is my html page.
<div>
<div id="defaultcard" class="container">
<div id="imgspace1" class="container">
<input id="edit" type="button" name="answer" value="Edit" onclick="showDiv()" />
<input id="cancel" type="button" name="answer" value="Cancel" onclick="showBtn()" />
<div id="image_preview">
<img id="previewing" src="" />
</div>
</div>
<div id="imgspace2" class="container">
<input id="edit" type="button" name="answer" value="Edit" onclick="showDiv()" />
<div id="image_preview">
<img id="previewing1" src="" />
</div>
</div>
<div id="imgspace3" class="container">
</div>
<div id="imgspace4" class="container">
</div>
</div>
and this is my js file(image preview part only).
function imageIsLoaded(e)
{
$("#file").css("color","green");
$('#image_preview').css("display", "block");
$('#previewing').attr('src', e.target.result);
$('#previewing').attr('width', '100%');
$('#previewing').attr('height', '100%');
};
});
how can i upload different images to each div. i want know how to pass that div id to this js file.

Categories

Resources