I want to make text area that will handle image drop event on it from the desktop.
I found that I could attach event to html element, but it doesn't work properly. I don't find any error, but it doesn't work.
Here is my code:
var imageDragOver = function imageDragOver(evt)
{
console.log('imageDragOver');
evt.stopPropagation();
evt.preventDefault();
}
var imageDrop = function imageDrop(evt)
{
console.log('imageDrop');
evt.stopPropagation();
evt.preventDefault();
}
document.addEventListener($('textarea'), imageDragOver, false);
document.addEventListener($('textarea'), imageDrop, false);
There is no any message in console log. What I do wrong? I don't look for an already made solutions.
To handle drop event on your area (text area or div) you need to do this:
var dropzone = document.getElementById('ta'); // paste your dropzone id here
dropzone.ondrop = function(e){
console.log('drop'); // for debugging reasons
e.preventDefault(); // stop default behaviour
readfiles(e.dataTransfer.files); // function to handle file(s) that was added to dropzone
};
Next you need to send this files to server and show it in the browser if you want.
function readfiles(files) {
var formData = new FormData(); // we initialise a new form that will be send to php
for (var i = 0; i < files.length; i++) { // if we have more that one file
previewImg(files[i]); // function to preview images
formData.append('file'+i, files[i]);
}
formData.append('moreInfo','myValuableValue');// you can append additional string info
$.ajax({
url: './path_to_file_handler.php',
type: 'POST',
data: formData,
async: true,
success: function (data) {
console.log(data);
},
cache: false,
contentType: false,
processData: false
});
}
function previewImg(file) {
var reader = new FileReader();
reader.onload = function (event) {
var image = new Image();
image.src = event.target.result; // set image source
image.width = 550; // a fake resize
document.getElementById('body').appendChild(image); // append image to body
};
reader.readAsDataURL(file);
}
Code for testing path_to_file_handler.php
<?php
print_r($_POST);
print_r($_FILES);
?>
Hope it will help somebody.
A simple way with jQuery UI, check out:
http://jqueryui.com/draggable/
http://jqueryui.com/droppable/
EDIT:
Duplicate of: Drag and drop desktop to browser HTML5 Javascript ?
Good luck! :-)
Related
I'm using SixLabors.ImageSharp to crop images with Javascript JQuery and all is working rigth but when i need to get the image cropped i don't know how can i get the image without refresh the page and without do a POST.
I'm using Tutexchange tutorial and they obtain the image by a POST method (and i dont wanna do it like that) i think about run a method and with Blazor get the file encoded base64 but when i do it i cant get the reader.result because is inside the onloadend event.
How can i get a image blob without a POST method and without save the image in a folder to read with Blazor?
I tried passing the onloadend reader.result with a method and await with a bucle while to return it when is done but value never is different than null and i tested if the cropper work with a console.log() and all is right with it:
function InitializeCroppie(div_width, div_height) {
basic = $('#main-cropper').croppie
({
enableExif: true,
url: '/images/ChooseImage.png',
viewport: { width: div_width, height: div_height },
boundary: { width: div_width, height: div_height },
showZoomer: false,
format: 'png' //'jpeg'|'png'|'webp'
});
//Reading the contents of the specified Blob or File
function readFile(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#main-cropper').croppie('bind', {
url: e.target.result
});
}
reader.readAsDataURL(input.files[0]);
}
}
// Change Event to Read file content from File input
$('#select').on('change', function () { readFile(this); });
}
var returnThisValue;
async function GetImageCroped() {
returnThisValue = null;
var blob = await basic.croppie('result', 'blob');
var reader = new FileReader();
if (blob != null) {
reader.readAsDataURL(blob);
reader.onloadend = function () {
SetValue(reader.result);
console.log(reader.result);
}
}
while (returnThisValue == null) {
//Waiting...
}
return returnThisValue;
}
function SetValue(value) {
returnThisValue = value;
}
function GetImageValue() {
return returnThisValue;
}
If is impossible without a POST method how can i receive it without reload the page.
EDIT:
I'm doing some test to know if is possible that js let blazor know when put the image in the localStorage to get it synchronic way with Blazor.
AFTER TEST: I tried to get the image with Blazored.LocalStorage and i cannot Chrome has a problem with "big data".
You can add a JavaScript listener event. It will trigger another event when updating the localstorage. It should be loaded when the page is initialized.
var orignalSetItem = localStorage.setItem;
localStorage.setItem = function (key, newValue) {
var setItemEvent = new Event("setItemEvent");
setItemEvent.key = key;
setItemEvent.newValue = newValue;
window.dispatchEvent(setItemEvent);
orignalSetItem.apply(this, arguments);
};
window.addEventListener("setItemEvent", function (e) {
if (e.key == 'image') {
var _this = localStorage.getItem("image")
if (_this != e.newValue) {
console.log(e.newValue)
//call method which sends this blob
} else {
console.log('key->');
console.log(e.newValue)
}
}
});
Trigger method.
$('#btnupload').on('click', function ()
{
basic.croppie('result', 'blob').then(function (blob)
{
localStorage.setItem('image', blob)
//...
});
});
I have a script to show a progress bar for when a user is uploading images. This upload form is within an open fancybox that I want to have closed once the images are finished uploading.
If I use a onclick event for when the user clicks the submit button to close the fancybox, it will not complete the image upload process.
Here is what I have for the progress bar. I'm wondering if there is a way to close fancybox once the progress bar gives the done message?
<script>
$(document).on('submit', 'form[profile-picture-data-remote]', function(e) {
e.preventDefault();
var fd = new FormData(this);
$.ajax({
url: $(this).attr('action'),
xhr: function() {
var xhr = new XMLHttpRequest();
var total = 0;
$.each(document.getElementById('profile-image-upload').files, function(i, file) {
total += file.size;
});
xhr.upload.addEventListener("progress", function(evt) {
var loaded = (evt.loaded / total).toFixed(2)*100;
$('#progress-container').css({
'display': 'block'
});
$('#progress').text('Uploading... ' + loaded + '%');
$('#progress').css({
'width': loaded+'%'
});
}, false);
return xhr;
},
type: 'post',
processData: false,
contentType: false,
data: fd,
success: function(data) {
var div = $('<div id="progress" class="uk-progress-bar" style="width: 100%;">Done!</div>')
$('#progress').replaceWith(div);
// ** IS THERE SOMETHING I CAN DO HERE TO CLOSE FANCYBOX NOW THAT THE IMAGE UPLOAD IS COMPLETE? **
}
});
});
</script>
The command to close fancybox is $.fancybox.close()
If the progress bar is in an IFrame within the fancybox, you'll need to use parent.$.fancybox.close()
Replacing your comment in the success method with the appropriate command should work.
I'm having some problems with the Dropzone.js. After I create a dropzone I want to change its values (for example the url) before sending the form via POST.
I already set the variable autoProcessQueue to false, so I can send the files when the form is sent.
Here is a test that I made but is not working...
var myDropzone = new Dropzone(me, {
url: uploadUrl
,maxFilesize: 10
,addRemoveLinks: true
,addDownloadLinks: true
,downloadFileUrl: downloadUrl
,autoProcessQueue: false
,init: function() {
var myDrop = this;
$("[id=btnSendMessage]").click(function(e){
// e.preventDefault();
url2 = '/file/upload/52175';
myDrop.url = url2;
myDrop.processQueue();
});
}
So, how can I change the url ? I dont know what to do here.
Thank you! :)
There is a page on the dropzone wiki that shows you how to do this. I'm typing it out here for posterity. You can take advantage of the processingfile event to set the upload url.
<form id="my-dropzone" action="/some-url" class="dropzone"></form>
<script>
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
this.options.url = "/some-other-url";
});
}
};
</script>
I am trying to upload an image using AJAX. I have the local URL of my image
and I want to pass that image as a file to the web service to upload.
Suppose i have the local file URL as : file:///accounts/1000/shared/camera/IMG_00000322.jpg
Now using AJAX I want to pass this to webservice,
What will be the best way to do this? I also want show the progress while uploading
Using php in server side.
uploadImage : function(myImageUrl,chatId){
var formData = new FormData();
formData.append("chatId", chatId);
formData.append("fileimage", myImageUrl);
$.ajax(
{
type:"POST",
url:"http://suresh.sp.in/butler/public/uploadimage/getimage",
contentType:"image/png",
dataType:"json",
data:formData,
success:function(uploaded){
console.info(uploaded.status);
},
error:function(error){
console.info(error);
}
});
}
I used that snippet on several of my websites, it handles Multiples files upload, drag and drop, and a progress bar.
HTML
You will need a container to drop your batch of files, in our case it will be #output, and a list of files.
JS
First we will push the dataTransfer to jQuery's event and bind the drop event.
$(document).ready(function(){
// We add the dataTransfer special property to our jQuery event
$.event.props.push("dataTransfer");
// We bind events for drag and drop
$('#output').bind({
"dragenter dragexit dragover" : do_nothing,
drop : drop
});
});
// stop event propagation
function do_nothing(evt){
evt.stopPropagation();
evt.preventDefault();
}
Then we build our update progress function
// Progress bar update function
function update_progress(evt,fic) {
var id_tmp=fic.size;
//id_tmp help us keep track of which file is uploaded
//right now it uses the filesize as an ID: script will break if 2 files have the
// same size
if (evt.lengthComputable) {
var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
if (percentLoaded <= 100) {
$('#'+id_tmp+' .percent').css('width', percentLoaded + '%');
$('#'+id_tmp+' .percent').html(percentLoaded + '%');
}
}
}
Last but not least our drop function
function drop(evt){
do_nothing(evt);
var files = evt.dataTransfer.files;
// Checking if there are files
if(files.length>0){
for(var i in files){
// if its really a file
if(files[i].size!=undefined) {
var fic=files[i];
// We add a progress listener
xhr = jQuery.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener('progress', function (e) {
update_progress(e,fic);
},false);
}
provider=function(){ return xhr; };
// We build our FormData object
var fd=new FormData;
fd.append('fic',fic);
// For each file we build and Ajax request
$.ajax({
url:'/path/to/save_fic.php',
type: 'POST',
data: fd,
xhr:provider,
processData:false,
contentType:false,
complete:function(data){
//on complete we set the progress to 100%
$('#'+data.responseText+' .percent').css('width', '100%');
$('#'+data.responseText+' .percent').html('100%');
}
});
// for each file we setup a progress bar
var id_tmp=fic.size;
$('#output').after('<div class="progress_bar loading" id="'+id_tmp+'"><div class="percent">0%</div></div>');
$('#output').addClass('output_on');
// We add our file to the list
$('#output-listing').append('<li>'+files[i].name+'</li>');
}
}
}
}
That method doesn't work in IE9 or below.
Hope it helped!
Source(in french)
Some infos on progress tracking using XMLHttpRequest
Some infos on the datatransfer prop
EDIT:
PHP
From the server side you can handle the files normally using $_FILES etc...
In order to set the progress to 100% in the complete function your php script must echo the filesize.
I have several canvases positioned over each other that merge into one as data URI. Everything works fine and I can get the composite image to show up on the page, but the other funcitonality I require is to create the URI and then share to facebook. I wanted to try to do this without sending to the server and do it all client side.
the code isn't necessary to the problem but if you want to see it
<ul class="button-group even-2">
<li><span id='merge-canvas' class="button expand">Save Image</span></li>
<li><span id='share-facebook' class="button expand facebook" >Share</span></li>
</ul>
with the javascript looking like this.
// DROPBOX AND FILE READER
function noopHandler(evt) {
evt.stopPropagation();
evt.preventDefault();
}
function drop(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files;
var count = files.length;
// Only call the handler if 1 or more files was dropped.
if (count > 0) {
}
handleFiles(files);
}
function handleFiles(files) {
var file = files[0];
document.getElementById("droplabel").innerHTML = "Processing " + file.name;
var reader = new FileReader();
// init the reader event handlers
reader.onloadend = handleReaderLoadEnd;
// begin the read operation
reader.readAsDataURL(file);
}
function handleReaderLoadEnd(evt) {
// basically clears and redraws the face canvas on load of the users image
document.getElementById("droplabel").innerHTML = "Picture Added Successfully!";
var $canvas = $('canvas');
ctx = $canvas[0].getContext('2d');
face = new Image();
face.onload = function() {
ctx.drawImage(face, 0, 0, 500, (face.height/face.width) * 500);
}
face.src = evt.target.result;
return face;
}
function initializeDropbox() {
var dropbox = document.getElementById("dropbox")
// adds different events for the dropbox and points to the relevant function
dropbox.addEventListener("dragenter", noopHandler, false);
dropbox.addEventListener("dragexit", noopHandler, false);
dropbox.addEventListener("dragover", noopHandler, false);
dropbox.addEventListener("drop", drop, false);
}
which produces a really really long data URI!
Any ideas to accomplish the share?
You can post an image via URL or multipart/form-data in the source parameter:
https://developers.facebook.com/docs/graph-api/reference/v2.1/user/photos
/* make the API call */
FB.api(
"/me/photos",
"POST",
{
"source": "{image-data}"
},
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);