Display selected picture under it's button with multiple buttons - javascript

Sorry the title is not better. Here is where I'm at. I am trying to open an openFileDialog, then display the image I picked below that button. I can do it fine with one button and one image. However I can't seem to get the selected picture to show under only the appropriate button. My script looks like this.
$('.custom-upload input[type=file]').change(function() {
var parentCommentId = $(this).id
$(this).next().find('input').val($(this).val());
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
function imageIsLoaded(e) {
$('img').attr('src', e.target.result);
$('img').fadeIn();
};
});
.custom-upload {
position: relative;
height: 40px;
width: 350px;
margin: 30px;
}
.custom-upload input[type=file] {
outline: none;
position: relative;
text-align: right;
-moz-opacity: 0;
filter: alpha(opacity: 0);
opacity: 0;
z-index: 2;
width: 100%;
height: 100%;
}
.custom-upload .fake-file {
background: url(http://www.fold3.com/i/upload-icon.png) center right no-repeat;
position: absolute;
top: 0px;
left: 0px;
width: 350px;
padding: 0;
margin: 0;
z-index: 1;
line-height: 100%;
}
.custom-upload .fake-file input {
font-size: 16px;
height: 40px;
width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="custom-upload" id="taco">
<input type="file" id="eatme">
<div class="fake-file">
<input disabled="disabled" id="damn">
</div>
<img id="myImg" src="#" style="display: none;height:400px;" width=100% height=100%/>
</div>
<br>
<div id="result"></div>
<div class="custom-upload">
<input type="file">
<div class="fake-file">
<input disabled="disabled">
</div>
<img id="myImg" src="#" alt="your image" style="display: none;" width=100% />
</div>

Using $("img") selects all img elements. You need to use DOM navigation methods to get from the input for which the change event occurred to its related img element.
$('.custom-upload input[type=file]').change(function() {
var $this = $(this); // store a reference to current input
$this.next().find('input').val($(this).val());
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
function imageIsLoaded(e) {
$this.closest('.custom-upload')
.find('img')
.attr('src', e.target.result)
.fadeIn();
};
});
I've saved a reference to the current file input in the (new) variable $this. Then in the img onload handler I've used .closest() to navigate up to the containing div and then .find() to go back down to the img in that div.
(You could use $this.siblings("img") or $this.next().next(), but that would only work for your specific html structure as it is right now - using .closest() plus .find() will work even if you later add an extra (sub-)container div around the img or otherwise tweak the structure, just as long as the file input and img are still within the same containing div.)
Demo: http://jsfiddle.net/jndL3rj5/

Related

Replace CHOOSE FILE with an image

Hi I am trying to replace the choose file button with an image. I am using javascript to create the button but when I am inspecting the website, it shows me a html script of the button which is of type= file.
To create it, I used:
input = createFileInput(handleFile);
input.elt.style["width"] = "40%";
input.elt.style["font-size"]="3vmin";
function handleFile(file) {
print(file);
if (file.type === 'image') {
imgFile = file.data;
img = createImg(file.data);
img.hide();
canvas.image(img, 0, 0, 224, 224);
image(img, 0, 0, width, height/2);
img.remove();
}
mode = 1;
tint = false;
}
Can anyone suggest how I can change the generic button with an image.
I think you can cheat and position an image over the input, then add a click handler to the image and pass it through to the input button below.
Is this what you are trying to achieve?
const input = document.querySelector("#avatar");
const button = document.querySelector("#button");
button.addEventListener('click', event => input.click(event));
.body {
font-family: sans-serif;
}
label {
display: inline-block;
padding: 1em 0;
}
.wrapper {
position: relative;
}
#avatar {
display: block;
height: 50px;
border: 1px solid #333;
}
#button {
position: absolute;
left: 1px;
top: 1px;
}
<div class="body">
<label for="avatar">Choose a profile picture:</label>
<div class="wrapper">
<input type="file" id="avatar" name="avatar">
<img id="button" src="https://via.placeholder.com/75x50/333333/ffffff?text=Avatar"></img>
</div>
</div>

How to change file upload text to image and upload the file and render to a div

I have 2 different upload button through which I need to upload the image and render to a div,I can able to render image on click of Upload button 1 but on click of Upload button 2 I am not able to render the image.
$(document).ready(function(e) {
$(".showonhover").click(function(){
$("#selectfile").trigger('click');
});
});
var input = document.querySelector('input[type=file]'); // see Example 4
input.onchange = function () {
var file = input.files[0];
drawOnCanvas(file); // see Example 6
displayAsImage(file); // see Example 7
};
function drawOnCanvas(file) {
var reader = new FileReader();
reader.onload = function (e) {
var dataURL = e.target.result,
c = document.querySelector('canvas'), // see Example 4
ctx = c.getContext('2d'),
img = new Image();
img.onload = function() {
c.width = img.width;
c.height = img.height;
ctx.drawImage(img, 0, 0);
};
img.src = dataURL;
};
reader.readAsDataURL(file);
}
function displayAsImage(file) {
var imgURL = URL.createObjectURL(file),
img = document.createElement('img');
img.onload = function() {
URL.revokeObjectURL(imgURL);
};
img.src = imgURL;
// document.body.removeChild(img);
document.getElementById("demo").appendChild(img);
}
function displayAsImage2(file) {
var imgURL = URL.createObjectURL(file),
img = document.createElement('img');
img.onload = function() {
URL.revokeObjectURL(imgURL);
};
img.src = imgURL;
// document.body.removeChild(img);
document.getElementById("demo1").appendChild(img);
}
$("#upfile1").click(function () {
$("#file1").trigger('click');
});
input {
font-size: 20px;
height:50px;
}
.imagediv {
float:left;
margin-top:50px;
}
.imagediv .showonhover{
background:red;
padding:20px;
opacity:0.9;
color:white;
width: 100%;
display:block;
text-align:center;
cursor:pointer;
}
#upfile1 {
background:red;
padding:20px;
opacity:0.9;
color:white;
width: 10%;
display:block;
text-align:center;
cursor:pointer;
}
#demo img,#demo1 img{
width:200px;
height:auto;
display:block;
margin-bottom:10px;
}
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>To an image "click on the image below"</h3>
<p>
<input type="file" id="file1" name="image" accept="image/*" capture style="display:none"/>
<span id="upfile1" style="cursor:pointer" />upload button1</span>
</p>
<p id="demo"></p>
<p id="demo1"></p>
<div align="left" class="imagediv">
<span>Or click here</span>
<span class="visibleimg"></span>
<span class="showonhover">upload button2</span>
<input id="selectfile" type="file" name="" style="display: none;" />
</div>
<script src="script.js"></script>
The main issue I see is that querySelector only returns "the first Element within the document that matches the specified selector."
Since there are more than one input, I suggest using querySelectorAll to return "a list of the document's elements that match the specified group of selectors."
Below, I'm using forEach to bind the onchange listener to each input.
// Code goes here
$(document).ready(function(e) {
$(".showonhover").click(function() {
$("#selectfile").trigger('click');
});
$("#upfile1").click(function() {
$("#file1").trigger('click');
});
});
var inputs = document.querySelectorAll('input[type=file]');
inputs.forEach(function(input) {
input.onchange = function() {
var file = this.files[0];
displayAsImage(file);
};
});
function displayAsImage(file) {
var imgURL = URL.createObjectURL(file),
img = document.createElement('img');
img.onload = function() {
URL.revokeObjectURL(imgURL);
};
img.src = imgURL;
document.getElementById("demo").appendChild(img);
}
/* Styles go here */
input {
font-size: 20px;
height: 50px;
}
.imagediv {
float: left;
margin-top: 50px;
}
.imagediv .showonhover {
background: red;
padding: 20px;
opacity: 0.9;
color: white;
width: 100%;
display: block;
text-align: center;
cursor: pointer;
}
#upfile1 {
background: red;
padding: 20px;
opacity: 0.9;
color: white;
width: 10%;
display: block;
text-align: center;
cursor: pointer;
}
#demo img,
#demo1 img {
width: 200px;
height: auto;
display: block;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>To an image "click on the image below"</h3>
<p>
<input type="file" id="file1" name="image" accept="image/*" capture style="display:none" />
<span id="upfile1" style="cursor:pointer">upload button1</span>
</p>
<p id="demo"></p>
<p id="demo1"></p>
<div align="left" class="imagediv">
<span>Or click here</span>
<span class="visibleimg"></span>
<span class="showonhover">upload button2</span>
<input id="selectfile" type="file" name="" style="display: none;" />
</div>
<script src="script.js"></script>

Lazy loading of images for website to load faster

i want that before the actual image gets loaded a spinner should be shown so that my website can load faster
window.addEventListener('load', function(){
var allimages= document.getElementsByTagName('img');
for (var i=0; i<allimages.length; i++) {
if (allimages[i].getAttribute('data-src')) {
allimages[i].setAttribute('src', allimages[i].getAttribute('data-src'));
}
}
}, false)
<img src="https://loremflickr.com/400/600" data-src="images/banguet-hall-location-icon.png" class="secEightImg" />
<img src="http://www.jettools.com/images/animated_spinner.gif" data-src="images/banguet-hall-location-icon.png" class="secEightImg" />
<script>
</script>
the problem is the actual image is shown two times and instead of spinner a broken image (which is shown when no image is found) is shown first
please help
If you want a spinner per image, just add the spinner URL as the initial src attribute for all of them:
<img src="spinner.gif" data-src="actual-image.png" />
Then, once the page loads, change all those src for the real URL (data-src) and listen for the load and error events on each image.
For each of them, add a .loaded class or .error class to the images and style them as you want. For example, you could hide the ones that could not be loaded, show a custom "error" image (using background-image) or style them as you wish, like in this example:
function imageLoaded(e) {
updateImage(e.target, 'loaded');
}
function imageError(e) {
updateImage(e.target, 'error');
}
function updateImage(img, classname) {
// Add the right class:
img.classList.add(classname);
// Remove the data-src attribute:
img.removeAttribute('data-src');
// Remove both listeners:
img.removeEventListener('load', imageLoaded);
img.removeEventListener('error', imageError);
}
window.addEventListener('load', () => {
Array.from(document.getElementsByTagName('img')).forEach(img => {
const src = img.getAttribute('data-src');
if (src) {
// Listen for both events:
img.addEventListener('load', imageLoaded);
img.addEventListener('error', imageError);
// Just to simulate a slow network:
setTimeout(() => {
img.setAttribute('src', src);
}, 2000 + Math.random() * 2000);
}
});
})
html,
body {
margin: 0;
height: 100%;
}
.images {
width: 100%;
height: 100%;
background: #000;
display: flex;
align-items: center;
overflow-x: scroll;
}
.margin-fix {
border-right: 1px solid transparent;
height: 16px;
}
img {
width: 16px;
height: 16px;
margin: 0 64px;
}
img.loaded {
width: auto;
height: 100%;
margin: 0;
}
img.error {
background: red;
border-radius: 100%;
/* You could add a custom "error" image here using background-image */
}
<div class="images">
<img
src="https://i.stack.imgur.com/RvfGz.gif"
data-src="https://d39a3h63xew422.cloudfront.net/wp-content/uploads/2014/07/20145029/driven-by-design-the-incomparable-lancia-stratos-1476934711918-1000x573.jpg" />
<img
src="https://i.stack.imgur.com/RvfGz.gif"
data-src="https://car-images.bauersecure.com/pagefiles/76591/1752x1168/ford_racing_puma_01.jpg?mode=max&quality=90&scale=down" />
<img
src="https://i.stack.imgur.com/RvfGz.gif"
data-src="http://doesntexist.com/image.jpg" />
<span class="margin-fix"></span>
</div>
The problem is that the spinner image you use initially might take some time to load.
One solution would be to use a data URI, so instead of:
<img src="https://i.stack.imgur.com/RvfGz.gif" data-src="actual-image.png" />
You would have:
<img src="data:image/gif;base64,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cXVlcnknPmZ1bmN0aW9uLm15c3FsLXF1ZXJ5PC9hPl06IENhbid0IGNvbm5lY3QgdG8gbG9jYWwgTXlTUUwgc2VydmVyIHRocm91Z2ggc29ja2V0ICcvdmFyL3J1bi9teXNxbGQvbXlzcWxkLnNvY2snICgyKSBpbiA8Yj4vaG9tZS9hamF4bG9hZC93d3cvbGlicmFpcmllcy9jbGFzcy5teXNxbC5waHA8L2I+IG9uIGxpbmUgPGI+Njg8L2I+PGJyIC8+CjxiciAvPgo8Yj5XYXJuaW5nPC9iPjogIG15c3FsX3F1ZXJ5KCkgWzxhIGhyZWY9J2Z1bmN0aW9uLm15c3FsLXF1ZXJ5Jz5mdW5jdGlvbi5teXNxbC1xdWVyeTwvYT5dOiBBIGxpbmsgdG8gdGhlIHNlcnZlciBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQgaW4gPGI+L2hvbWUvYWpheGxvYWQvd3d3L2xpYnJhaXJpZXMvY2xhc3MubXlzcWwucGhwPC9iPiBvbiBsaW5lIDxiPjY4PC9iPjxiciAvPgo8YnIgLz4KPGI+V2FybmluZzwvYj46ICBteXNxbF9xdWVyeSgpIFs8YSBocmVmPSdmdW5jdGlvbi5teXNxbC1xdWVyeSc+ZnVuY3Rpb24ubXlzcWwtcXVlcnk8L2E+XTogQ2FuJ3QgY29ubmVjdCB0byBsb2NhbCBNeVNRTCBzZXJ2ZXIgdGhyb3VnaCBzb2NrZXQgJy92YXIvcnVuL215c3FsZC9teXNxbGQuc29jaycgKDIpIGluIDxiPi9ob21lL2FqYXhsb2FkL3d3dy9saWJyYWlyaWVzL2NsYXNzLm15c3FsLnBocDwvYj4gb24gbGluZSA8Yj42ODwvYj48YnIgLz4KPGJyIC8+CjxiPldhcm5pbmc8L2I+OiAgbXlzcWxfcXVlcnkoKSBbPGEgaHJlZj0nZnVuY3Rpb24ubXlzcWwtcXVlcnknPmZ1bmN0aW9uLm15c3FsLXF1ZXJ5PC9hPl06IEEgbGluayB0byB0aGUgc2VydmVyIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCBpbiA8Yj4vaG9tZS9hamF4bG9hZC93d3cvbGlicmFpcmllcy9jbGFzcy5teXNxbC5waHA8L2I+IG9uIGxpbmUgPGI+Njg8L2I+PGJyIC8+CjxiciAvPgo8Yj5XYXJuaW5nPC9iPjogIG15c3FsX3F1ZXJ5KCkgWzxhIGhyZWY9J2Z1bmN0aW9uLm15c3FsLXF1ZXJ5Jz5mdW5jdGlvbi5teXNxbC1xdWVyeTwvYT5dOiBDYW4ndCBjb25uZWN0IHRvIGxvY2FsIE15U1FMIHNlcnZlciB0aHJvdWdoIHNvY2tldCAnL3Zhci9ydW4vbXlzcWxkL215c3FsZC5zb2NrJyAoMikgaW4gPGI+L2hvbWUvYWpheGxvYWQvd3d3L2xpYnJhaXJpZXMvY2xhc3MubXlzcWwucGhwPC9iPiBvbiBsaW5lIDxiPjY4PC9iPjxiciAvPgo8YnIgLz4KPGI+V2FybmluZzwvYj46ICBteXNxbF9xdWVyeSgpIFs8YSBocmVmPSdmdW5jdGlvbi5teXNxbC1xdWVyeSc+ZnVuY3Rpb24ubXlzcWwtcXVlcnk8L2E+XTogQSBsaW5rIHRvIHRoZSBzZXJ2ZXIgY291bGQgbm90IGJlIGVzdGFibGlzaGVkIGluIDxiPi9ob21lL2FqYXhsb2FkL3d3dy9saWJyYWlyaWVzL2NsYXNzLm15c3FsLnBocDwvYj4gb24gbGluZSA8Yj42ODwvYj48YnIgLz4K" data-src="actual-image.png" />
As you can see, your HTML document will grow fast using this approach, which is a problem.
A better approach might be to use CSS to add the spinner so that you only include the data URI once. To do that, you need to add an empty src attribute to your images initially anyway:
<img src data-src="actual-image.png" />
Or:
<img src="" data-src="actual-image.png" />
If you don't put it, the image will have an annoying gray border you can't get rid of until you add a src attribute.
function imageLoaded(e) {
updateImage(e.target, 'loaded');
}
function imageError(e) {
updateImage(e.target, 'error');
}
function updateImage(img, classname) {
// Add the right class:
img.classList.add(classname);
// Remove the data-src attribute:
img.removeAttribute('data-src');
// Remove both listeners:
img.removeEventListener('load', imageLoaded);
img.removeEventListener('error', imageError);
}
window.addEventListener('load', () => {
Array.from(document.getElementsByTagName('img')).forEach(img => {
const src = img.getAttribute('data-src');
if (src) {
// Listen for both events:
img.addEventListener('load', imageLoaded);
img.addEventListener('error', imageError);
// Just to simulate a slow network:
setTimeout(() => {
img.setAttribute('src', src);
}, 2000 + Math.random() * 2000);
}
});
})
html,
body {
margin: 0;
height: 100%;
}
.images {
width: 100%;
height: 100%;
background: #000;
display: flex;
align-items: center;
overflow-x: scroll;
}
.margin-fix {
border-right: 1px solid transparent;
height: 16px;
}
img {
width: 16px;
height: 16px;
margin: 0 64px;
background-image: url("data:image/gif;base64,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cXVlcnknPmZ1bmN0aW9uLm15c3FsLXF1ZXJ5PC9hPl06IENhbid0IGNvbm5lY3QgdG8gbG9jYWwgTXlTUUwgc2VydmVyIHRocm91Z2ggc29ja2V0ICcvdmFyL3J1bi9teXNxbGQvbXlzcWxkLnNvY2snICgyKSBpbiA8Yj4vaG9tZS9hamF4bG9hZC93d3cvbGlicmFpcmllcy9jbGFzcy5teXNxbC5waHA8L2I+IG9uIGxpbmUgPGI+Njg8L2I+PGJyIC8+CjxiciAvPgo8Yj5XYXJuaW5nPC9iPjogIG15c3FsX3F1ZXJ5KCkgWzxhIGhyZWY9J2Z1bmN0aW9uLm15c3FsLXF1ZXJ5Jz5mdW5jdGlvbi5teXNxbC1xdWVyeTwvYT5dOiBBIGxpbmsgdG8gdGhlIHNlcnZlciBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQgaW4gPGI+L2hvbWUvYWpheGxvYWQvd3d3L2xpYnJhaXJpZXMvY2xhc3MubXlzcWwucGhwPC9iPiBvbiBsaW5lIDxiPjY4PC9iPjxiciAvPgo8YnIgLz4KPGI+V2FybmluZzwvYj46ICBteXNxbF9xdWVyeSgpIFs8YSBocmVmPSdmdW5jdGlvbi5teXNxbC1xdWVyeSc+ZnVuY3Rpb24ubXlzcWwtcXVlcnk8L2E+XTogQ2FuJ3QgY29ubmVjdCB0byBsb2NhbCBNeVNRTCBzZXJ2ZXIgdGhyb3VnaCBzb2NrZXQgJy92YXIvcnVuL215c3FsZC9teXNxbGQuc29jaycgKDIpIGluIDxiPi9ob21lL2FqYXhsb2FkL3d3dy9saWJyYWlyaWVzL2NsYXNzLm15c3FsLnBocDwvYj4gb24gbGluZSA8Yj42ODwvYj48YnIgLz4KPGJyIC8+CjxiPldhcm5pbmc8L2I+OiAgbXlzcWxfcXVlcnkoKSBbPGEgaHJlZj0nZnVuY3Rpb24ubXlzcWwtcXVlcnknPmZ1bmN0aW9uLm15c3FsLXF1ZXJ5PC9hPl06IEEgbGluayB0byB0aGUgc2VydmVyIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCBpbiA8Yj4vaG9tZS9hamF4bG9hZC93d3cvbGlicmFpcmllcy9jbGFzcy5teXNxbC5waHA8L2I+IG9uIGxpbmUgPGI+Njg8L2I+PGJyIC8+CjxiciAvPgo8Yj5XYXJuaW5nPC9iPjogIG15c3FsX3F1ZXJ5KCkgWzxhIGhyZWY9J2Z1bmN0aW9uLm15c3FsLXF1ZXJ5Jz5mdW5jdGlvbi5teXNxbC1xdWVyeTwvYT5dOiBDYW4ndCBjb25uZWN0IHRvIGxvY2FsIE15U1FMIHNlcnZlciB0aHJvdWdoIHNvY2tldCAnL3Zhci9ydW4vbXlzcWxkL215c3FsZC5zb2NrJyAoMikgaW4gPGI+L2hvbWUvYWpheGxvYWQvd3d3L2xpYnJhaXJpZXMvY2xhc3MubXlzcWwucGhwPC9iPiBvbiBsaW5lIDxiPjY4PC9iPjxiciAvPgo8YnIgLz4KPGI+V2FybmluZzwvYj46ICBteXNxbF9xdWVyeSgpIFs8YSBocmVmPSdmdW5jdGlvbi5teXNxbC1xdWVyeSc+ZnVuY3Rpb24ubXlzcWwtcXVlcnk8L2E+XTogQSBsaW5rIHRvIHRoZSBzZXJ2ZXIgY291bGQgbm90IGJlIGVzdGFibGlzaGVkIGluIDxiPi9ob21lL2FqYXhsb2FkL3d3dy9saWJyYWlyaWVzL2NsYXNzLm15c3FsLnBocDwvYj4gb24gbGluZSA8Yj42ODwvYj48YnIgLz4K");
}
img.loaded {
width: auto;
height: 100%;
margin: 0;
}
img.error {
background: red;
border-radius: 100%;
/* You could add a custom "error" image here using background-image */
}
<div class="images">
<img
src
data-src="https://d39a3h63xew422.cloudfront.net/wp-content/uploads/2014/07/20145029/driven-by-design-the-incomparable-lancia-stratos-1476934711918-1000x573.jpg" />
<img
src
data-src="https://car-images.bauersecure.com/pagefiles/76591/1752x1168/ford_racing_puma_01.jpg?mode=max&quality=90&scale=down" />
<img
src
data-src="http://doesntexist.com/image.jpg" />
<span class="margin-fix"></span>
</div>
Other approaches might be to just hide the images initially with display: none for example, in which case you might want a wrapper around them to show something like an empty box to indicate the users that something will be shown in there, or even a spinner made with other elements if you want/need to get fancy.
What you can do is something like:
$(".sly-main-slider div img").attr('src', "#");
$(".sly-main-slider").addClass("loading");
$(".sly-main-slider div").hide();
$(".sly-main-slider div img").load(function() {
$(".sly-main-slider div").show();
$(".sly-main-slider").removeClass("loading");
}).attr('src', "https://loremflickr.com/400/600");
.loading {
position: absolute;
top: 10%;
left: 10%;
z-index: 2000;
background: url(http://1.bp.blogspot.com/-nfXo9GWbDtM/VOn0vr4yLMI/AAAAAAAABCA/dDNgd7_QCFo/s1600/block-loader.gif) no-repeat center center;
height: 32px;
width: 32px;
}
.loading:after {
position: absolute;
top: 8px;
left: 40px;
content: 'Loading...';
}
body {
position: relative;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='sly-main-slider'>
<div>
<img src="https://loremflickr.com/400/600" alt="" />
</div>
</div>

Drag and Drop input for files not handling files

I've made a form where the user can upload a file and I wanted to add a drag and drop feature so I made it like this:
<small id="filename"></small>
<!-- <input id="thumbnail" type="file" name="thumbnail" class="input input-thumbnail form-control"> -->
<div class="dropzone" id="droparea">
<div class="input-container">
<input type="file" class="dropzone-input" id="thumbnail-input" name="thumbnail">
</div>
<div class="overlay">
<small class="overlay-text" id="overlay-text">Drag and Drop</small>
</div>
</div>
<script>
(function() {
let dropzone = document.getElementById('droparea');
let dropzonetext = document.getElementById('overlay-text');
let filenametext = document.getElementById('filename');
let fileImput = document.getElementById('thumbnail-input');
dropzone.ondrop = function(e) {
e.preventDefault();
this.className = 'dropzone';
dropzonetext.className = 'overlay';
fileImput.files[0] = e.target.files[0];
filenametext = fileImput.files[0].name
};
dropzone.ondragover = function() {
this.className = 'dropzone dragover';
dropzonetext.className = 'overlay dragover';
return false;
};
dropzone.ondragleave = function() {
this.className = 'dropzone';
dropzonetext.className = 'overlay';
return false;
};
}());
</script>
The expected behavior of this code is that the box changes color (controlled by css) whenever the user hovers over it when holding 1 or multiple files (I want to limit it to only accept 1 file). But this does not work.
Also whenever the file is dropped on the box the value of the input should become the file dropped by the user but this is not happening either.
Instead I'm getting this error in the console whenever I drop the file there:
Uncaught TypeError: Cannot read property '0' of undefined
at HTMLDivElement.dropzone.ondrop ((index):79)
dropzone.ondrop # (index):79
With line 79 being: fileImput.files[0] = e.target.files[0];
What is causing this problem?
Here is also the css for the drag and drop:
.dropzone-input{
opacity: 0;
-moz-opacity: 0;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0)
width: 30vw;
height: 25vh;
z-index:0;
position: absolute;
color: #ccc;
line-height:25vh;
text-align: center;
}
.dragover{
border-color: black;
text-color: black;
}
.dropzone {
width: 30vw;
height: 25vh;
overflow: hidden;
position: relative;
border: 2px dashed #ccc;
}
.overlay {
width: 30vw;
height: 25vh;
position: absolute;
top: 0;
left: 0;
z-index:1;
line-height:25vh;
text-align: center;
}
.overlay-text{
color: darkgrey;
}
.overlay-text.dragover{
text-color: black;
}
**EDIT: **
Someone asked for a screenshot:
you can see the file selected is the one I dropped on the input
The result is that, e.target.files is null. Because you set event ondrop on dropzone, so e.target maybe any ele in dropzone where you drop (detail in the picture test on my local). But some elements don't have files property. The ele which have files property is the input. So you should try 1 option:
Option 1,set the ondrop event for only the input
Option 2, check the e.target .
if(e.target is input) use
fileImput.files[0] = e.target.files[0];
else use
fileImput.files[0] = e.target.parentElement.querySelector('#thumbnail-input').files[0];

Jquery 'do' code after 'on.change' happens

I'm trying to something after an on.change happens.
I'm submitting this image throw an .on('change', function(){}) and I need to have some code running after the image is completly rendered in the browser.
So far I have this:
$('.photoimg').on('change', function (){
$('.db_result').html('<img src="images/loader.gif" />');
$('.imageform').ajaxForm({ target: $(this).closest('.child')}).submit();
$('.db_result').delay(500).queue(function(n) {
$(this).html('');
n();
});
});
I've tried this but it executes all the lines at onde before the image even beggins to render:
$('.photoimg').on('change', function (){
$('.db_result').html('<img src="images/loader.gif" />');
$('.imageform').ajaxForm({ target: $(this).closest('.child')}).submit();
$('.db_result').delay(500).queue(function(n) {
$(this).html('');
n();
});
/////////////////////////////
alert($(this).closest('.child').html());
/////////////////////////////
});
What I'm looking for is something like this:
$('.photoimg').on('change', function (){
$('.db_result').html('<img src="images/loader.gif" />');
$('.imageform').ajaxForm({ target: $(this).closest('.child')}).submit();
$('.db_result').delay(500).queue(function(n) {
$(this).html('');
n();
});
}).[[afterComplete]](function(){
alert($(this).closest('.child').html());
});
HTML [page wqith the input type file]
<div class="child" style="z-index: 70; position: absolute; top: 0px; left: 0px; width: 800px; height: 172px; cursor: default; background-color: rgba(254, 202, 64, 0.701961);" alt="reset">
<div class="fileinput-holder" style="position: relative;"><input type="text" class="fileinput-preview" style="width: 100%; padding-right: 81px;" readonly="readonly" placeholder="No file selected...">
<span class="fileinput-btn btn" type="button" style="display:block; overflow: hidden; position: absolute; top: 0; right: 0; cursor: pointer;">Browse...<input type="file" class="photoimg" name="photoimg" style="position: absolute; top: 0px; right: 0px; margin: 0px; cursor: pointer; font-size: 999px; opacity: 0; z-index: 999;"></span>
</div>
</div>
PHP [file for processing the input]
...
if(move_uploaded_file($tmp, $path.$actual_image_name)) //check the path if it is fine
{
move_uploaded_file($tmp, $path.$actual_image_name); //move the file to the folder
//display the image after successfully upload
echo "<div class=\"imgh\" style=\"width:auto; height:auto;\" alt=\"reset3\"><img src='data:image/".$ext.";base64,".base64_encode(file_get_contents($path.$actual_image_name))."' style=\"width:inherit; height:inherit; min-width:50px; min-height:50px;\" class='img_set'><div class=\"close\"><i class=\"icon-remove-sign\"></i></div></div>";
}
else
{
echo "<input type='file' class='photoimg' name='photoimg'/><br/><strong style='color:red;'>Carregamento Falhou!</strong>";
}
}
...
Keep your change handler for your input form to handle changes on it, but use the load event for your image, and use that to handle code that needs to execute after the image loaded:
$('img.img_set').on('load', function (){
//...
});
This not always reliable as it may not fire if the image has been cached.
See: jQuery callback on image load (even when the image is cached)

Categories