Upload from desktop with HTML5 and Javascript (drag and drop) - javascript

I'm making a typical drag and drop for upload images from desktop to browser, i can drop content inside the box and with a console.log view the content in the browser console:
File { name: "deam230mthumb.jpg", lastModified: 1194641808000, lastModifiedDate: Date 2007-11-09T20:56:48.000Z, size: 60313, type: "image/jpeg" }
I want to view the image inside a box and then upload on submit.
Here my code is use Jade template engine:
Jade (HTML)
form(action="" enctype="multipart/form-data")
div(class="all-100 miniatures")
div(class="all-100 drop ink-droppable align-center fallback" id="dropZone" ondrop="drop(event)" ondragover="allowDrop(event)")
Javascript
script.
var dropZone = document.getElementById('dropZone');
function allowDrop(e){
e.preventDefault();
}
function drop(e){
var file = e.dataTransfer.files[0];
e.preventDefault();
console.log(file);
//e.target.appendChild(file);
}

I added an array for content each file from the event, on the following code we need to add a controller for handle each file from the array with a register of each one on the database.
script.
var dropZone = document.getElementById('dropZone');
function allowDrop(e){
e.preventDefault();
}
var files = [];
function drop(e){
var file = e.dataTransfer.files[0];
files.push(file);
console.log(file)
e.preventDefault();
var reader = new FileReader();
reader.onload = function(event){
var miniatures = document.getElementById("miniatures");
var img = new Image();
img.src = event.target.result;
var miniature = document.createElement("div");
miniature.className = "all-20";
miniature.appendChild(img);
miniatures.appendChild(miniature);
}
var readerContent = reader.readAsDataURL(file);
var input = document.getElementById("upload");
input.files = readerContent;
console.log(files);
}

Ok, my Javascript looks this now:
At this point we can drag images from our desktop to browser and view
them, now, we need to upload that files.
script.
var dropZone = document.getElementById('dropZone');
function allowDrop(e){
e.preventDefault();
}
function drop(e){
var file = e.dataTransfer.files[0];
e.preventDefault();
console.log(file);
var reader = new FileReader();
reader.onload = function(event){
var miniatures = document.getElementById('miniatures');
var miniature = new Image();
miniature.src = event.target.result;
miniature.width = 100;
miniatures.appendChild(miniature);
}
reader.readAsDataURL(file);
}

Related

Change drag image inside a DragEnter event

I'm trying to define the image that appears when I drag an element inside my page.
I saw how to do it with DataTransfer.setDragImage() in that link but with me it is not working.
There are two differences between my code and the example:
I'm trying to make this change through the DragEnter event while the link is done in DragStart;
The image to be dragged will be in the user's file explorer, not in the HTML document.
I already did a test and the image is being generated correctly.
This is the code responsible for this functionality:
function handleDragEnter(event)
{
const img = new Image;
const reader = new FileReader;
reader.readAsDataURL((new Blob(icon(faPhotoFilmMusic).html, { type: 'image/svg+xml' })));
reader.addEventListener('load', () => {
img.src = reader.result;
event.dataTransfer.setDragImage(img, 10, 10);
});
}
I think the problem is in missing parentheses:
function handleDragEnter(event)
{
const img = new Image(); // <=== change this
const reader = new FileReader(); // <=== change this
reader.readAsDataURL((new Blob(icon(faPhotoFilmMusic).html, { type: 'image/svg+xml' })));
reader.addEventListener('load', () => {
img.src = reader.result;
event.dataTransfer.setDragImage(img, 10, 10);
});
}

Detect if file upload was from drag or regular input click

I'm currently trying create a drag and drop file uploader with the standard option to just use the regular input. I'm not sure what to be targeting to write if the user clicked the upload or dropped a file in.
My first thought was to check if the FileList is empty but both ways produce a FileList. Second thought was just write two functions one for the input and one for the drop but that seems like I would be repeating. Last thought was writing an if statement in the read_file function. However, I'm not sure what to target exactly.
Any ideas would be greatly appreciated!! thanks!!
https://jsfiddle.net/nick1572/b4xzt8oh/3/
var uploader = document.querySelector('.uploader');
var output = document.getElementById('output');
var file = document.getElementById('file');
file.addEventListener('change', function(event) {
read_file(event);
});
function read_file(event) {
file = event.target;
var reader = new FileReader();
reader.onload = function() {
var data_url = reader.result;
output.src = data_url;
};
// This will read when the image is dropped.
//reader.readAsDataURL(event.dataTransfer.files[0]);
reader.readAsDataURL(file.files[0]);
/*
Something like this
if () {
reader.readAsDataURL(file.files[0]);
} else if() {
reader.readAsDataURL(event.dataTransfer.files[0]);
}
*/
};
uploader.addEventListener('dragover', function(e) {
console.log('drag over');
e.preventDefault();
});
uploader.addEventListener('dragenter', function(e) {
console.log('drag enter');
e.preventDefault();
});
uploader.addEventListener('dragleave', function() {
console.log('drag leave');
});
uploader.addEventListener('drop', function(event) {
console.log('drop');
event.preventDefault();
read_file(event);
});
Check the type property of the event object to see which event has been used.
function read_file(event) {
file = event.target;
var reader = new FileReader();
reader.onload = function() {
var data_url = reader.result;
output.src = data_url;
};
if (event.type === 'change') {
reader.readAsDataURL(file.files[0]);
} else if(event.type === 'drop') {
reader.readAsDataURL(event.dataTransfer.files[0]);
}
};

Preview an Image in Div before its uploaded using IE9

How can I able to preview a image before it is uploaded. The preview action should be executed in all browsers without using Ajax to upload the image.
Most of the examples are using FileReader, which wont work in IE9.
Is there any plugins or any alternative to make it working in IE9
f (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
Here's the updated code. Hope it works for you.
if (input.files && input.files[0]) {
var url = URL.createObjectURL(input.files[0]);
$('#blah').attr('src', url);
}
JavaScript:
$('#fileID').on('change',function(){ }
var imageName = '';
if (this.files && this.files.length > 0) {
imageName = this.files[0].name;
}
else if (this.value) {
imageName = this.value;
}
if (window.FileReader) {
//as same as other samples
}
else{
var image = document.getElementById('imgItem');
image.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale', src='" + imageName + "')";
image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';
}
//code end
I find this works well in emulation-IE9.
Another way to draw a image:
var canvas = document.getElementById('imgArea');
var img = new Image();
img.src = imageName;
img.onload = function () {
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0, 200, 200);
}
Note: Add 2017/12/27
One solution to preview a local image with IE-9:
IE-9 does`nt support FileReader, so I tried to upload it first then return the imageName(with server path) to View to change the 'src' attribute of the img.
and it works well.
Points:(the example is using MVC)
1.In the 'change' event of input-type-file, do the ajaxSubmit(the action method:void)
2.In the Controller,using [Newtonsoft.Json.JsonConvert.SerializeObject],to return the json-formatted string.
Response.Write(strData);
3.In the callback of the ajaxSubmit, just change the src of the img.
(dont forget convert the result to json)

Simplifiying/modularizing my code in javascript

I know that I should follow the DRY principle in coding. However, I am not that into javascript so I want to ask how to make the code below more readable and maintanable.
$('#frontfile_v').change(function(){
reader = Main.Mod.image_change(this);
reader.onload = frontvImageIsLoaded;
});
$('#rearfile_v').change(function(){
reader = Main.Mod.image_change(this);
reader.onload = rearvImageIsLoaded;
});
$('#rightfile_v').change(function(){
reader = Main.Mod.image_change(this);
reader.onload = rightvImageIsLoaded;
});
$('#leftfile_v').change(function(){
reader = Main.Mod.image_change(this);
reader.onload = leftvImageIsLoaded;
});
//called after an image file has been chosen
function frontvImageIsLoaded(e) {
$("#frontimagepreview").attr('src', e.target.result);
$("#frontpreview-msg").css('color', 'green');
};
function rearvImageIsLoaded(e) {
$("#rearimagepreview").attr('src', e.target.result);
$("#rearpreview-msg").css('color', 'green');
};
function rightvImageIsLoaded(e) {
$("#rightimagepreview").attr('src', e.target.result);
$("#rightpreview-msg").css('color', 'green');
};
function leftvImageIsLoaded(e) {
$("#leftimagepreview").attr('src', e.target.result);
$("#leftpreview-msg").css('color', 'green');
};
This is the code for Main.Mod.image_change()
var image_change = function handleFileImageChange(obj){
//holds the image preview object
var file = obj.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
if(!((imagefile==match[0]) || (imagefile==match[1]) || (imagefile==match[2]))){
alert("Incorrect image file. You still be able to upload this form but the system " +
"will be using the default image.");
$("#preview-msg").css('color', 'red');
return false;
}else{
var reader = new FileReader();
//reader.onload = imageIsLoaded;
reader.readAsDataURL(obj.files[0]);
return reader;
}
};
The code above, will handle file input change event then change img src base on the file input.
I know the code i wrote really sucks since I have to repeat my code several times. How can I implement it in a more efficient way?
Thanks.
use , to combine selectors:
$('#frontfile_v,#rearfile_v').change(function(){
// ...
})
The "change" event will be bound to every object matched by the selector. This way you don't need to duplicate the binding.
Merge the "image loaded" functions into one function by passing parameters:
var idsMap = {
leftfile_v : {preview : '#frontimagepreview', msg : '#frontpreview-msg'},
// etc...
};
$('#leftfile_v,#rearfile_v').change(function(){
var ids = idsMap[$(this).attr('id')];
reader = Main.Mod.image_change(this);
reader.onload = function(e) {
imageIsLoaded(e, ids.preview, ids.msg);
};
});
function imageIsLoaded(e, preview, msg) {
$(preview).attr('src', e.target.result);
$(msg).css('color', 'green');
};
Yet another variant. As say #Malki: use comma in selector
$('#frontfile_v, #rearfile_v,#rightfile_v,#leftfile_v').change(function(){
var id = this.id.replace(/file_v$/,'');
reader = Main.Mod.image_change(this);
if(reader){ //for case when `image_change` return not "false"
// use mode generic function
reader.onload = function(e){
$("#"+id+"imagepreview").attr('src', e.target.result);
$("#"+id+"preview-msg").css('color', 'green');
};
}
});
As for handleFileImageChange you need use Array.indexOf function
var image_change = function handleFileImageChange(obj){
//holds the image preview object
var file = obj.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
if(match.indexOf(imagefile) == -1){
alert("Incorrect image file. You still be able to upload this form but the system will be using the default image.");
$("#preview-msg").css('color', 'red');
return false;
}else{
var reader = new FileReader();
//reader.onload = imageIsLoaded;
reader.readAsDataURL(file); //you not need use "obj.files[0]" because you already save it in "var file"
return reader;
}
};

drag file to browser from local

I want drop jpg to Browser from local, and display it on Browser.
I write code, but it don't display jpg.
Please advice.
html
<img id="img1" ondragover="doDragOver(event);"
ondrop="doDrop(event);"
class="droppable">
css
.droppable {
width:500px;
height:500px;
background-color: gray;
}
script
function doDragOver(event){
var type = event.dataTransfer.types.contains("Files");
if (type){
event.preventDefault();
}
}
function doDrop(event){
var img = document.getElementById("img1");
var file = event.dataTransfer.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
img.src = reader.result;
}
}
The problem is that the dragOver function the type list is empty (to it's empty in some browsers), but why check it content? You can check it in the drop function.
Be sure to cancel the default browser behavior using event.preventDefault(); and return false
Code:
function doDragOver(event) {
event.preventDefault();
return false
}
function doDrop(event) {
event.preventDefault();
var img = document.getElementById("img1");
var file = event.dataTransfer.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
img.src = reader.result;
}
}
Demo: http://jsfiddle.net/IrvinDominin/Up2NF/

Categories