I'm using html5 for drag and drop image, my code is still running normally. But, i can only drop image to background-image in dropbox, not image file. So, i can't get and insert image into database. This is my code:
script
var holder = document.getElementById('leftbox'), state = document.getElementById('status');
if ( typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'Drop files here'
}
holder.ondragover = function() {
this.className = '';
return false;
};
holder.ondragend = function() {
this.className = '';
return false;
};
holder.ondrop = function(e) {
this.className = '';
e.preventDefault();
var file = e.dataTransfer.files[0], reader = new FileReader();
reader.onload = function(event) {
console.log(event.target);
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
console.log(file);
reader.readAsDataURL(file);
return false;
};
HTML
<div class="medium-4 medium-centered columns">
<p id="status"></p>
<div id="leftbox"></div>
</div>
What should i do to change holder.style.background to image file? please help me :)
This should help you:
javascript onClick change background picture of div
$('#clickMe').on('click', function() { $('#changeMe').css('background-image', 'url(http://placehold.it/200x200/ff0000)'); })
Related
Actually I have a form where with image input. I want to validate image for three condition like
extension should be png, jpg
size should be less than 2048kb
less than 200px x 200px is consider as dimension
I wrote an function and solve 1 and 2 issue. To solve issue 3 , I use image reader inside onload listener and when I clicked it can not prevent submit also if I remove 3, then it works fine ! Is there any solution in JS that solve above issue?
Here is a slide of my code in below.
function isImageValid(idName) {
var fileUpload = document.getElementById(idName);
var fileName = document.getElementById(idName).value;
if (typeof (fileUpload.files) != "undefined") {
for (var i=0; i<fileUpload.files.length;i++)
{
// console.log(fileUpload.files[i]);
var valid_dimension = 0;
var reader = new FileReader();
//Read the contents of Image File.
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
//Initiate the JavaScript Image object.
var image = new Image();
//Set the Base64 string return from FileReader as source.
image.src = e.target.result;
//Validate the File Height and Width.
image.onload = function () {
var height = this.height;
var width = this.width;
if (height>200||width>200) {
valid_dimension =1;
// alert("Height and Width must not exceed 200px.");
return false;
}
// alert("Uploaded image has valid Height and Width.");
return true;
};
};
var size = parseFloat(fileUpload.files[0].size / 1024).toFixed(2);
var extension = fileName.split('.').pop();
if( valid_dimension ==1||size>2048||(extension!='jpg'&&extension!='JPG'&&extension!='JPEG'&&extension!='jpeg'&&extension!='png'&&extension!='PNG'))
return false;
else
return true;
}
} else {
return false;
}
}
And,
const form = document.getElementById('employee_form');
form.addEventListener('submit', (e)=>{
var is_avatar_img_valid = isImageValid('avatar');
if(is_avatar_img_valid==false){
e.preventDefault();
document.getElementById("avatar").style.borderColor = "red";
document.getElementById('avatar_validator_message').innerHTML = 'Invalid image';
}
else{
document.getElementById("avatar").style.borderColor = "black";
document.getElementById('avatar_validator_message').innerHTML = '';
}
}
The problem is reader.onload and image.onload functions are async in nature. So your form submits before these onload methods execute.
To solve this you need to follow the below steps
Prevent default in submit event handler
Pass callbacks for valid and invalid image to the isImageValid function
Manually submit the form if image is valid
Below is the code. Please mark the answer as accepted, if it helps
function isImageValid(idName, onValidCallback, onInvalidCallback) {
var fileUpload = document.getElementById(idName);
var fileName = document.getElementById(idName).value;
if (typeof (fileUpload.files) != "undefined") {
for (var i = 0; i < fileUpload.files.length; i++) {
// console.log(fileUpload.files[i]);
//--------------------
const allowedExtension = ['jpg', 'JPG', 'JPEG', 'jpeg', 'png', 'PNG'];
const maxAllowedSize = 2048;
const maxAllowedHeight = 200;
const maxAllowedWidth = 200;
const size = parseFloat(fileUpload.files[i].size / 1024).toFixed(2);
const extension = fileName.split('.').pop();
console.log({ size, extension });
//Check for valid extension and size limit
if (allowedExtension.some(ext => ext === extension) && size <= maxAllowedSize) {
//Extension and size are valid
// Now check for valid dimensions
const reader = new FileReader();
reader.readAsDataURL(fileUpload.files[i]);
reader.onload = function (e) {
//Initiate the JavaScript Image object.
var image = new Image();
//Set the Base64 string return from FileReader as source.
image.src = e.target.result;
//Validate the File Height and Width.
image.onload = function () {
const height = this.height;
const width = this.width;
console.log({ height, width });
if (height > maxAllowedHeight || width > maxAllowedWidth) {
// alert("Height and Width must not exceed 200px.");
//File does not meet the dimensions guidline
if (onInvalidCallback)
onInvalidCallback();
return false;
}
// alert("Uploaded image has valid Height and Width.");
//Everything is fine, form canbe submitted now
if (onValidCallback)
onValidCallback();
};
};
}
break;
}
}
else {
// There are no files selected
if (onInvalidCallback)
onInvalidCallback();
}
}
const form = document.getElementById('employee_form');
form.addEventListener('submit', (e) => {
e.preventDefault();
isImageValid('avatar', () => {
alert('going to submit');
document.getElementById("avatar").style.borderColor = "black";
document.getElementById('avatar_validator_message').innerHTML = '';
//Manually submit the form
form.submit();
},
() => {
alert('stop submit');
document.getElementById("avatar").style.borderColor = "red";
document.getElementById('avatar_validator_message').innerHTML = 'Invalid image';
}
);
return false;
});
Inside the form eventlister you need to use
e.preventDefault()
The full code looks like this
const form = document.getElementById('employee_form');
form.addEventListener('submit', (e) => {
e.preventDefault()
var is_avatar_img_valid = isImageValid('avatar');
if (is_avatar_img_valid == false) {
e.preventDefault();
document.getElementById("avatar").style.borderColor = "red";
document.getElementById('avatar_validator_message').innerHTML = 'Invalid image';
}
else {
document.getElementById("avatar").style.borderColor = "black";
document.getElementById('avatar_validator_message').innerHTML = '';
}
});
Hi I need help on how I can make my drag and drop read the .text files that is dropped in the dropzone.. I'm still exploring javascript and would need help to guide me on what is wrong with my code..
The content of the text file should be shown on the displayarea
Reference: http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api
Thanks in advance!
https://jsfiddle.net/d6nur0wc/1/
(function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(event) {
event.preventDefault();
this.className = "dropzone";
console.log(event.dataTransfer.files[0]);
window.onload = function() {
var fileInput = document.getElementById('dropzone');
var fileDisplayArea = document.getElementById('displayarea');
fileInput.addEventListener('dropzone.ondrop', function(read) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(read) {
fileDisplayArea.innerText = reader.result;
}
reader.readAsText(file);
}
else {
fileDisplayArea.innerText = "File not supported!";
}
});
}
}
dropzone.ondragover = function() {
this.className = "dropzone dragover";
return false;
};
dropzone.ondragleave = function() {
this.className = "dropzone";
return false;
};
}())
Your code should be like this. you have to remove onload event listener. it can't be compatible here.
(function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(event) {
event.preventDefault();
this.className = "dropzone";
console.log(event.dataTransfer.files[0]);
var fileInput = document.getElementById('dropzone');
var fileDisplayArea = document.getElementById('displayarea');
var file = event.dataTransfer.files[0]
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(read) {
fileDisplayArea.innerText = reader.result;
}
reader.readAsText(file);
}
else {
fileDisplayArea.innerText = "File not supported!";
}
}
dropzone.ondragover = function() {
this.className = "dropzone dragover";
return false;
};
dropzone.ondragleave = function() {
this.className = "dropzone";
return false;
};
}())
Hi i am creating an web chat application in that i want user can copy paste the image from desktop or can paste directly the screen shot but i am unable to achieve it.
I used following code:
$("#dummy").on("paste",function(event){
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
for (index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onload = function(event){
console.log(event.target.result)}; // data url!
reader.readAsDataURL(blob);
}
}
})
using the above code in Chrome and Firefox i am getting Clipboarddata undefined in case of image.
I tried lots of links on google but not able to reach the target.
I also tried below link from stackoverflow:
Paste an image from clipboard using JavaScript
also the below link:
http://strd6.com/2011/09/html5-javascript-pasting-image-data-in-chrome/
http://codepen.io/netsi1964/pen/IoJbg
can any one help me with complete example how to achieve It?
Demo
Works on latest chrome/firefox. Chrome implementation is simple. Firefox has restrictions that user must give command to do paste like keyboard event and editable input must be focused, so we do tricks here - on ctrl down we focusthat input field, on release unfocus.
HTML:
<canvas style="border:1px solid grey;" id="my_canvas" width="300" height="300"></canvas>
JS:
var CLIPBOARD = new CLIPBOARD_CLASS("my_canvas", true);
/**
* image pasting into canvas
*
* #param string canvas_id canvas id
* #param boolean autoresize if canvas will be resized
*/
function CLIPBOARD_CLASS(canvas_id, autoresize) {
var _self = this;
var canvas = document.getElementById(canvas_id);
var ctx = document.getElementById(canvas_id).getContext("2d");
var ctrl_pressed = false;
var reading_dom = false;
var text_top = 15;
var pasteCatcher;
var paste_mode;
//handlers
document.addEventListener('keydown', function (e) {
_self.on_keyboard_action(e);
}, false); //firefox fix
document.addEventListener('keyup', function (e) {
_self.on_keyboardup_action(e);
}, false); //firefox fix
document.addEventListener('paste', function (e) {
_self.paste_auto(e);
}, false); //official paste handler
//constructor - prepare
this.init = function () {
//if using auto
if (window.Clipboard)
return true;
pasteCatcher = document.createElement("div");
pasteCatcher.setAttribute("id", "paste_ff");
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;';
pasteCatcher.style.marginLeft = "-20px";
pasteCatcher.style.width = "10px";
document.body.appendChild(pasteCatcher);
document.getElementById('paste_ff').addEventListener('DOMSubtreeModified', function () {
if (paste_mode == 'auto' || ctrl_pressed == false)
return true;
//if paste handle failed - capture pasted object manually
if (pasteCatcher.children.length == 1) {
if (pasteCatcher.firstElementChild.src != undefined) {
//image
_self.paste_createImage(pasteCatcher.firstElementChild.src);
}
}
//register cleanup after some time.
setTimeout(function () {
pasteCatcher.innerHTML = '';
}, 20);
}, false);
}();
//default paste action
this.paste_auto = function (e) {
paste_mode = '';
pasteCatcher.innerHTML = '';
var plain_text_used = false;
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
paste_mode = 'auto';
//access data directly
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
//image
var blob = items[i].getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
this.paste_createImage(source);
}
}
e.preventDefault();
}
else {
//wait for DOMSubtreeModified event
//https://bugzilla.mozilla.org/show_bug.cgi?id=891247
}
}
};
//on keyboard press -
this.on_keyboard_action = function (event) {
k = event.keyCode;
//ctrl
if (k == 17 || event.metaKey || event.ctrlKey) {
if (ctrl_pressed == false)
ctrl_pressed = true;
}
//c
if (k == 86) {
if (document.activeElement != undefined && document.activeElement.type == 'text') {
//let user paste into some input
return false;
}
if (ctrl_pressed == true && !window.Clipboard)
pasteCatcher.focus();
}
};
//on kaybord release
this.on_keyboardup_action = function (event) {
k = event.keyCode;
//ctrl
if (k == 17 || event.metaKey || event.ctrlKey || event.key == 'Meta')
ctrl_pressed = false;
};
//draw image
this.paste_createImage = function (source) {
var pastedImage = new Image();
pastedImage.onload = function () {
if(autoresize == true){
//resize canvas
canvas.width = pastedImage.width;
canvas.height = pastedImage.height;
}
else{
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(pastedImage, 0, 0);
};
pastedImage.src = source;
};
}
Safari doesn't implement DataTransfer.items, so there's no way to
extract image data (i.e. a screenshot copied to the clipboard) in
Javascript. You can get copied files, but not data.
[From stakeoverflow post]
Chrome
Add your code to he code from codepen and give an id to the div (line 50)
Include your script as posted above with the divs id
$("#one").on("paste", function (event) {
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
for (index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onload = function (event) {
console.log(event.target.result)
}; // data url!
reader.readAsDataURL(blob);
}
}
})
Make a screenshot, select the first div (that one with the id one), hit ctrl+v, the screenshot appears in the div and the imagedata is loged to console.
Firefox
Use the code I prepeared you within this fiddle
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<style>
#one {
border: 1px solid black;
min-height: 100px;
min-width: 100px;
}
</style>
</head>
<body>
Copy image from clipboard in Firefox.
<br /> Select the box below and paste a image from clipboard via ctrl+v
<br /> Data printed at console
<br />
<div id="one" contenteditable="true"></div>
<script>
$(function () {
$("#one").bind("input paste", function (ev) {
window.setTimeout(function (ev) {
var input = $("#one").children()[0].src;
var s = input.split(',');
var mime = s[0];
var data = s[1];
console.log(mime);
console.log(data);
}, 300);
});
});
</script>
</body>
</html>
Chrome & Firefox combined
A combined version, using the code from #pareshm for Chrome and my code for Firefox may be found in this updated fiddle (Tested with clipboard content created via system screendump by ctrl+print and copy image part from gimp)
I have a problem with a dragstart event in my javascript. When using chrome it works perfectly fine, but not in firefox, where it wont fire at all.
(function () {
var dropzone = document.getElementById('dropzone-add');
var dropzone2 = document.getElementById('dropzone-del');
var draggedItem;
function drag (e) { //This one does not fire in firefox.. I have tried many methods..
e.dataTransfer.setData('text/plain', e.target.src);
draggedItem = e.target;
}
var displayUploads = function (data) {
var uploads = document.getElementById('uploads');
for(index=0; index<data.length; index=index+1){
var div = document.createElement('div');
var anchor = document.createElement('a');
var image = document.createElement('img');
div.className = 'col-lg-2 col-md-4 col-xs-6 thumb';
anchor.className = 'thumbnail';
anchor.href = '#';
image.className = 'img-responsive';
image.src = data[index].file;
image.alt = data[index].name;
anchor.appendChild(image);
div.appendChild(anchor);
uploads.insertBefore(div, uploads.firstChild);
image.setAttribute('draggable', true);
image.ondragstart = function(event) {drag(event)}; //This is the elment that will be draggable.
//image.addEventListener('dragstart', drag, false);
}
}
var upload = function (files) {
var formData = new FormData(),
xhr = new XMLHttpRequest(),
index;
for(index=0; index<files.length; index = index+1){
formData.append('file[]', files[index]);
}
xhr.onload = function () {
var data = JSON.parse(this.responseText);
displayUploads(data);
}
xhr.open('post', 'upload.php');
xhr.send(formData);
}
var removeFile = function(src){
xhr = new XMLHttpRequest();
xhr.onload = function () {
var data = this.responseText;
console.log(data);
}
xhr.open('post', 'delete.php');
xhr.send(src);
}
dropzone.ondrop = function (e) {
e.preventDefault();
this.className = 'dropzone';
if(e.dataTransfer.files.length < 1){
alert('Use the other dropzone to delete.');
return false;
}
else
upload(e.dataTransfer.files);
}
dropzone.ondragover = function () {
this.className = 'dropzone dragover';
return false;
}
dropzone.ondragleave = function () {
this.className = 'dropzone';
return false;
}
dropzone2.ondrop = function (e) {
e.preventDefault();
this.className = 'dropzone';
var data = e.dataTransfer.getData('text');
console.log(draggedItem);
console.log(data);
//removeFile(data);
}
dropzone2.ondragover = function () {
this.className = 'dropzone dragover';
return false;
}
}());
The outputed images becomes properly draggable and is working fine in chrome. I have tried to use methods like event.originalEvent without success. Would appreciate any help, I am stuck right now. Please ignore the awfulness in the loop.
On top html
<html>
<head>
<meta charset="utf-8">
<title>Upload - drag drop</title>
<link rel="stylesheet" href="global.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div class="content-fluid">
<div class="dropzone" id="dropzone-add">Drag the file you want to upload here</div>
<div class="dropzone" id="dropzone-del">Drag the file you want to delete here</div>
<div class="row" id="uploads">
</div>
</div>
Upload.php
<?php
$uploaded = array();
if(!empty($_FILES['file']['name'][0])){
$upload_folder = 'uploads/';
foreach($_FILES['file']['name'] as $position => $name){
$upload_path = $upload_folder . time() . '_' . basename($_FILES['file']['name'][$position]);
if(move_uploaded_file($_FILES['file']['tmp_name'][$position], $upload_path)){
$uploaded[] = array('name' => $name, 'file' => $upload_path);
}
}
echo json_encode($uploaded);
}
?>
I had created a plugin that were showing image thumbnail and information before uploading the Image but as it is using html5 features well it doesn't work with old IE versions. I'm just trying do update this plugin to tell the user yo update his browser or use another browser if the features are not supported. here is the part of the code that was reading image (fired on onchange event of the file input ):
function readImg() {
$('#preview').html('<br /><span>Preview</span><br />');
var file = document.getElementById('addfile').files[0];
if (file.size > 1048576) {
parent.$('<div></div>').html('Photo file must be at most 1MB!').alertBox({ title: 'Upload Photo' });
document.getElementById('addfile').value = '';
return;
}
ldimgext = desiredExt(file.name);
if (!ldimgext) {
parent.$('<div></div>').html('Only gif,jpg and png files are accepted!').alertBox({ title: 'Upload Photo' });
document.getElementById('addfile').value = '';
return;
}
var reader = new FileReader();
reader.onload = imgLoaded;
reader.readAsDataURL(file);
}
function imgLoaded(e) {
tsimg = e.target.result.replace(/^data:image\/(png|jpeg|gif);base64,/, "");
var img = $('<img src="'+ e.target.result + '"/>');
var tmp = new Image();
tmp.src = e.target.result;
tmp.onload = function () {
if (tmp.width > tmp.height) img.attr('width', '80'); else img.attr('height', '80');
$('#preview').html('').append(img);
}
How can I check If FileReader and filesize, ... all Options I used here are supported in browser or not?
on change event of the element you can check to see if the size is supported by checking the returned value of your file variable, if it is null then it is not supported. so your code would end up being:
function readImg() {
$('#preview').html('<br /><span>Preview</span><br />');
var file = document.getElementById('addfile').files[0];
//the added part
if(file==null){
alert('your browser does not support this feature');
return false;
}
if (file.size > 1048576) {
parent.$('<div></div>').html('Photo file must be at most 1MB!').alertBox({ title: 'Upload Photo' });
document.getElementById('addfile').value = '';
return;
}
ldimgext = desiredExt(file.name);
if (!ldimgext) {
parent.$('<div></div>').html('Only gif,jpg and png files are accepted!').alertBox({ title: 'Upload Photo' });
document.getElementById('addfile').value = '';
return;
}
var reader = new FileReader();
reader.onload = imgLoaded;
reader.readAsDataURL(file);
}
function imgLoaded(e) {
tsimg = e.target.result.replace(/^data:image\/(png|jpeg|gif);base64,/, "");
var img = $('<img src="'+ e.target.result + '"/>');
var tmp = new Image();
tmp.src = e.target.result;
tmp.onload = function () {
if (tmp.width > tmp.height) img.attr('width', '80'); else img.attr('height', '80');
$('#preview').html('').append(img);
}