Preview appears but camera image not uploaded? - dropzone.js

I am using https://www.dropzone.dev/js/ to upload images with the following script:
This is working if I upload an image. However when I capture an image with my phone (and someone else has had the same problem) although I see the preview on my .dropzone area the image never uploads. I have browsed my phone and actually don't see the image I have taken so am wondering if that is the problem but has anyone else managed to get images from a camera (where they're not saved) to upload with this script? Am I missing something?
$(".dropzone").dropzone({
url: base_url+'url/save',
acceptedFiles: 'image/*',
autoProcessQueue: false,
addRemoveLinks: true,
autoDiscover: false,
uploadMultiple: false,
init: function() {
var dzClosure = this;
$('#button[name="saveBtn"]').off('click').on('click',function(e){
e.preventDefault();
e.stopPropagation();
dzClosure.processQueue();
// Reload existing layer/view on datatable
setTimeout(function(){
MyAssets.ajax.reload(); // see notes at top
},500);
$('.modal:visible').modal('hide');
});
// When sending the data add our actual form contents too - note the formdata.append is crucial
dzClosure.on('sending', function (data, xhr, formData) {
var extra = getForm($('.modal:visible'));
formData.append(key,extra[key]);
});
// On removing files - if they are already there remove them!
dzClosure.on('removedfile',function(file) {
var params = {
fileContents: JSON.stringify(file),
assetID: $('.modal:visible').find('input[name="assetID"]').val(),
};
$.post(base_url+'url/remove',params);
})
// Preload existing image
dzClosure.addCustomFile = function(){
var thisFileBit = this;
// This is getting the SOURCE clicked VIEW link ...
// But its not ready yet
setTimeout(function(){
if (typeof $('#asset'+$('.modal:visible').find('input[name="assetID"]').val()).data('contents') != 'undefined'){
var origAsset = JSON.parse(atob($('#asset'+$('.modal:visible').find('input[name="assetID"]').val()).data('contents')));
} else {
var origAsset = {};
}
var file = {
accepted: true,
status: Dropzone.QUEUED,
size: origAsset.FileSize,
upload: {},
};
// Push file to collection
thisFileBit.files.push(file);
// Emulate event to create interface
thisFileBit.emit("addedfile", file);
// Add thumbnail url
if (origAsset.PublicImagePath != '' && typeof origAsset.PublicImagePath != 'undefined'){
thisFileBit.emit("thumbnail", file, origAsset.PublicImagePath);
}
// Add status processing to file
thisFileBit.emit("processing", file);
// Add status success to file AND RUN EVENT success from response
thisFileBit.emit("success", file,{
status: "success"
},false);
// Add status complete to file
thisFileBit.emit("complete", file);
},200);
}
// Includes test file above
dzClosure.on('addedfile',function (){
setTimeout(function(){
$('.dz-size span').data('dz-size');
$('.dz-details').remove();
$('.dz-image img').each(function(){
$(this).wrap('');
})
},1000);
});
dzClosure.addCustomFile();
}
});

Related

Get file path in the ondata event

I'm using the ondata event to add data to the formData, but I need the relative file path in there (in case someone uploads a folder, so I can recreate the same structure on the server after upload, e.g /myFolder/fileploaded.jpg)
How does one get _relativePath in the ondata event ?
FilePond.setOptions({
server: {
url: 'http://192.168.0.100',
timeout: 7000,
process: {
url: './process',
ondata: (formData) => {
let fullPath = ''; // Need _relativePath here
formData.append('Hello', 'World');
return formData;
}
},
}
});
Never mind, I didn't see in the docs that there is a more advanced process function:
FilePond.setOptions({
server: {
process:(fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
// fieldName is the name of the input field
// file is the actual file object to send
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', 'url-to-api');
// Should call the progress method to update the progress to 100% before calling load
// Setting computable to false switches the loading indicator to infinite mode
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
// Should call the load method when done and pass the returned server file id
// this server file id is then used later on when reverting or restoring a file
// so your server knows which file to return without exposing that info to the client
request.onload = function() {
if (request.status >= 200 && request.status < 300) {
// the load method accepts either a string (id) or an object
load(request.responseText);
}
else {
// Can call the error method if something is wrong, should exit after
error('oh no');
}
};
request.send(formData);
// Should expose an abort method so the request can be cancelled
return {
abort: () => {
// This function is entered if the user has tapped the cancel button
request.abort();
// Let FilePond know the request has been cancelled
abort();
}
};
}
}
});

kendo Image browser delete

I have implemented kendo editor within it i have implemented kendo image browser.
I have implemented it the way it is guided in documentation with same backend controller.
I have implemented kendo confirmation box for other functionality too. I want kendo alert instead of javascript alert for confirmation when one delete image. so I have capture the delete event and using event.stopPropagation I manage stop the default delete behaviour and implemented kendo confirm box. on its ok button i have called backend destroy method of controller to delete image using ajax.
Fortunately it is successfully deleted from backend but from view side that is in image browser thumbnail it is not deleting, after refreshing the it goes from view side or remove from thumbnail . I have also try to manually delete the respective li it got deleted but as soon as I upload some new image that deleted li also comes up with deleted image although it has been deleted from backend.
Here is the code how I implemented image browser:
function createEditor(id)
{
//Kendo Editor for content
$(id).kendoEditor({
encoded: false,
tools: [
"bold",
"italic",
"underline",
"strikethrough",
],
imageBrowser: {
transport: {
read: "/ImageBrowser/Read",
destroy: {
url: '/ImageBrowser/Destroy',
type: "POST"
},
create: {
url: '/ImageBrowser/Create',
type: "POST"
},
thumbnailUrl: '/ImageBrowser/Thumbnail',
uploadUrl: '/ImageBrowser/Upload',
imageUrl: "../Content/article/" + userId + "/{0}"
},
}
});
//On click of imagebrowser icon of editor
$(".k-i-image").click(function () {
setTimeout(function () {
// Attach a select handler to the Upload embedded in the ImageBrowser.
$(".k-imagebrowser .k-upload").find("input").data("kendoUpload").bind("select",
function (e) {
// Prevent the event if the selected file is not of specified extension.
if (e.files[0].extension.toLowerCase() != ".jpg" && e.files[0].extension.toLowerCase() != ".jpeg" && e.files[0].extension.toLowerCase() != ".png" && e.files[0].extension.toLowerCase() != ".gif") {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "The file extension is not *.png,*.gif,*.jpg,*.jpeg.",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
var s = e.files[0].size / Math.pow(1000, 2);
//Size validation
if (s > 5) {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "File size should not be more than 5 MB",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
$('.k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable').children('li').each(function (index, value) {
// Prevent the event if the selected file is already exist.
if ($(this).children("strong").html() == e.files[0].name) {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "A file with name already exists in the current directory",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
});
});
//Delete image from image browser
$(".k-toolbar-wrap>.k-button-icon").click(function (event) {
var type;
var name;
if ($(this).children().hasClass("k-i-close")) {
//alert();
//event.preventDefault();
event.stopPropagation();
var path = "";
var img;
$('.k-breadcrumbs-wrap').children('a').each(function (index, value) {
if ($(this).hasClass("k-link")) {
path = path + $(this).text() + "/";
}
});
$('.k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable').children('li').each(function (index, value) {
if ($(this).hasClass("k-tile k-state-selected")) {
img = $(this).attr("data-uid");
type = $(this).attr("data-type");
name = $(this).children("strong").html();
}
});
//alert(path);
window.OpenDeleteConfirm("Are you sure you want to delete this record?").then(function (e) {
$.ajax({
type: 'POST',
url: "/ImageBrowser/Destroy",
data: { "path": path, "type": type, "name": name },
success: function (response) {
//$(".k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable>.k-tile.k-state-selected").remove();
}
});
}, function () {
// window.myalert("You chose to Cancel action.");
});
}
else {
}
});
//End
});
});
}```
In short, kendoEditor has an internal ImageBrowser that has an internal ListView with the files that keeps the list of files in its dataSource, that it creates from your transport configuration. Your ajax call doesn't tell that dataSource that an item should be removed.
Since it's a poorly documented component of Kendo Professional, I suggest you file a ticket with Telerik.

Unable to download file with CasperJS

I am trying to download a file with CasperJS. If using browser, the download begins when user clicks a button and the response headers look like this:
I have tried these two methods with no luck:
1) https://stackoverflow.com/a/26334034
With this approach, the code block inside the if-statement is never executed. If I remove the condition, a bunch of resources are being saved, such as css files and so on. So the event listener is working, but for some reason not triggering when I use CasperJs click function to click the button that should start the download.
2) https://stackoverflow.com/a/30122021/692695
File.csv is saved but it's the web sites sourcecode, not the csv-file I get when I click the button on the website.
All of my code:
'use strict';
var utils = require('utils');
var casper = require('casper').create({
//verbose: true,
//logLevel: "debug",
clientScripts: ["node_modules/jquery/dist/jquery.min.js"]
});
function writeHtml(filename) {
var fs = require('fs');
var content = casper.getHTML();
fs.write(filename, content, 'w');
}
function getUrl() {
var url;
url = $('.tableofcontent_link:contains("Väestö työmarkkina-aseman, sukupuolen ja iän mukaan")').parent().attr('href');
return url;
}
casper.selectOptionByValue = function(selector, valueToMatch){
this.evaluate(function(selector, valueToMatch){
var select = document.querySelector(selector),
found = false;
Array.prototype.forEach.call(select.children, function(opt, i){
if (!found && opt.value.indexOf(valueToMatch) !== -1) {
select.selectedIndex = i;
found = true;
}
});
// dispatch change event in case there is some kind of validation
var evt = document.createEvent("UIEvents"); // or "HTMLEvents"
evt.initUIEvent("change", true, true);
select.dispatchEvent(evt);
}, selector, valueToMatch);
};
var link;
var url = 'http://pxnet2.stat.fi/PXWeb/pxweb/fi/StatFin/StatFin__tym__tyti/?table';
casper.start(url);
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)');
casper.then(function () {
this.echo("Now at: " + this.getCurrentUrl());
link = 'http://pxnet2.stat.fi' + casper.evaluate(getUrl);
});
casper.then(function () {
this.open(link);
});
casper.then(function() {
this.echo("Now at: " + this.getCurrentUrl());
// Select all data for each item
casper.click('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_VariableSelectorValueSelectRepeater_ctl01_VariableValueSelect_VariableValueSelect_SelectAllButton');
casper.click('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_VariableSelectorValueSelectRepeater_ctl02_VariableValueSelect_VariableValueSelect_SelectAllButton');
casper.click('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_VariableSelectorValueSelectRepeater_ctl03_VariableValueSelect_VariableValueSelect_SelectAllButton');
casper.click('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_VariableSelectorValueSelectRepeater_ctl04_VariableValueSelect_VariableValueSelect_SelectAllButton');
casper.click('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_VariableSelectorValueSelectRepeater_ctl05_VariableValueSelect_VariableValueSelect_SelectAllButton');
});
casper.then(function() {
// casper.selectOptionByValue('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_OutputFormats_OutputFormats_OutputFormatDropDownList',
// 'FileTypeExcelX');
// Select the format of the file from the select option list at the bottom
casper.selectOptionByValue('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_OutputFormats_OutputFormats_OutputFormatDropDownList',
'FileTypeCsvWithHeadingAndSemiColon');
});
casper.then(function () {
// just for debugging
writeHtml('page1.html');
});
casper.then(function() {
//casper.click('#ctl00_ContentPlaceHolderMain_VariableSelector1_VariableSelector1_ButtonViewTable');
});
casper.then(function() {
// FIRST ATTEMPT TO LOAD THE DATA TO a file called file.csv
var formData = casper.evaluate(function(){
return $('form#aspnetForm').serialize();
});
//this.echo("Params: " + formData);
var targetFile = 'file.csv';
casper.download(link, targetFile, 'POST', formData);
});
casper.then(function () {
// just for debugging
writeHtml('page2.html');
});
// SECCOND ATTEMPT TO LOAD THE DATA TO a file called stats.csv
casper.on('resource.received', function (resource) {
if ((resource.url.indexOf('tyti_001') !== -1) ) {
this.echo(resource.url);
var file;
file = "stats.csv";
try {
this.echo("Attempting to download file " + file);
var fs = require('fs');
casper.download(resource.url, fs.workingDirectory + '/' + file);
} catch (e) {
this.echo(e);
}
}
});
casper.run(function () {
this.echo('End').exit();
});
And my package.json:
{
"scripts": {
"test": "dotest"
},
"pre-commit": ["test"],
"dependencies": {
"jquery": "^3.3.1"
},
"devDependencies": {
"pre-commit": "^1.2.2"
}
}
Explanation of the code:
First visit this page: http://pxnet2.stat.fi/PXWeb/pxweb/fi/StatFin/StatFin__tym__tyti/statfin_tyti_pxt_001.px/?rxid=bd4d5dc1-358d-407e-ae47-13266b79bfd0
There, dynamically pick a specified link and move there.
Select all data by clicking the V-shapen icon (look at the attached screenshot) and then select the format of the file.
I've faced this issue earlier with all versions except phantomjs 2.0.0. I also tried the solutions you shared from SO a year ago and they didn't work as well.
I'm going to assume you're using a phantomjs version other than 2.0.0.
Here's the link to download it
https://bitbucket.org/ariya/phantomjs/downloads/
With it, you will have access to onFileDownload method which you can override and use like below
casper.page.onFileDownload = function(status){
console.log('onFileDownload(' + status + ')');
return "newfile.csv";
};
onFileDownload will be called whenever a file is downloaded as a result of clicking a button (ajax) or as a result of sequential get/post requests.
All you have to do is, trigger the click on the button/link that will initiate download.
Note : My solution is assuming that everything else (site is not blocking phantomjs and your request headers/cookies are as expected)

Dropzone createThumbnailFromUrl() issue

I need to add pre-existing image files to dropzone by using Laravel 5.4. This is why I use createThumbnailFromUrl() function. But it does not generate images properly. Instead it shows them in blank way. I used that link (jsfiddle) for that purpose. I googled a lot, tried several ways, but it did not help:
Below is my code:
<script type="text/javascript" src='{{asset("js/dropzone/min/dropzone.min.js")}}'></script>
<script type="text/javascript">
Dropzone.options.addImages = {
paramName: "file", // The name that will be used to transfer the file
addRemoveLinks: true,
// The setting up of the dropzone
init:function() {
// Add server images
var myDropzone = this;
var existingFiles = [
{ name: "Filename 1.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 2.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 3.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 4.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 5.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' }
];
for (i = 0; i < existingFiles.length; i++) {
// alert(existingFiles[i].imageUrl);
myDropzone.emit("addedfile",existingFiles[i]);
myDropzone.files.push(existingFiles[i]);
myDropzone.createThumbnailFromUrl(existingFiles[i], existingFiles[i].imageUrl, function() {
myDropzone.emit("complete", existingFiles[i]);
}, "anonymous");
}
},
};
</script>
Here is the result :( :
P.S: Any kind of help would be appreciated.
had the same issue with dropzone 5.3
this fixed it for me
let mockFile = { name: "Loaded File", dataURL: relURL };
dropzoneInst.files.push(mockFile);
dropzoneInst.emit("addedfile", mockFile);
dropzoneInst.createThumbnailFromUrl(mockFile,
dropzoneInst.options.thumbnailWidth,
dropzoneInst.options.thumbnailHeight,
dropzoneInst.options.thumbnailMethod, true, function (thumbnail)
{
dropzoneInst.emit('thumbnail', mockFile, thumbnail);
});
dropzoneInst.emit('complete', mockFile);
I am attaching for reference my solution, based on many previous answers, but mostly on Raphael Eckmayer. This is how it is done to make it work well with Django 3.0.5 and dropzone.js 5.7.0. Maybe it is not the best solution, but it works.
I am sending my current images from Django view using new template tag json_script that packs my list of files prepared in Django into JSON. Basically in my template I have this:
{{ images|json_script:"images" }}
Then I process this in my script. Here is entire script from my site, hope that will help someone.
EDIT:
I had an issue with this code that if I add new pictures to the dropzone together with the old one from database I got this form submitted twice. In first pass I get pictures from dropzone.js, but also all fields since I am copying them from the form. And then, on second pass, I am submitting form again but now without pictures. My view actually was handling this well and storing data, but when I started to write down how to handle removed pictures on form edit I had issue with this, so I decided to handle this differently. Please note that code is now changed and instead of submitting form twice I am sending entire form and pictures with dropzone, but after successmultiple I am just redirecting to other page. Everything is updated and stored then. So the change is in the successmultiple part.
<script type="text/javascript">
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Dropzone.autoDiscover = false;
var first_time = true;
var old_images = JSON.parse(document.getElementById('images').textContent)
var myDropzoneX = new Dropzone("div#mydropzone", {
autoProcessQueue: false,
url: "{% url 'site_report_edit' report_id=1 %}",
addRemoveLinks: true,
thumbnailWidth: 400,
thumbnailHeight: 400,
uploadMultiple: true,
parallelUploads: 12,
init: function() {
var myDropzone = this;
var addButton = document.getElementById("submit-btn");
if (old_images) {
console.log(old_images);
for (x in old_images) {
var mockFile = {
name: old_images[x].name,
size: old_images[x].size,
kind: 'image',
dataURL: old_images[x].urlich,
accepted: true
}
myDropzone.files.push(mockFile);
myDropzone.emit('addedfile', mockFile);
createThumbnail(mockFile);
console.log(old_images[x].name, old_images[x].urlich);
}
function createThumbnail(temp) {
myDropzone.createThumbnailFromUrl(temp,
myDropzone.options.thumbnailWidth,
myDropzone.options.thumbnailHeight,
myDropzone.options.thumbnailMethod, true, function (thumbnail) {
myDropzone.emit('thumbnail', temp, thumbnail);
myDropzone.emit("complete", temp);
});
}
myDropzone._updateMaxFilesReachedClass();
}
addButton.addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
document.getElementById("dropzone-form").submit();
}
});
this.on("successmultiple", function (files, response) {
setTimeout(function (){
{#document.getElementById("dropzone-form").submit();#}
window.location.href = "/admin/report/{{ report_id }}";
}, 1000);
});
},
sending: function (file, xhr, formData) {
var formEl = document.getElementById("dropzone-form");
if (first_time) {
for (var i=0; i<formEl.elements.length; i++){
formData.append(formEl.elements[i].name, formEl.elements[i].value)
first_time = false;
}
}
formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
formData.append("image", file.name);
}
});
</script>
Please note that there are some comments and some writing to console.log, but you can obviously get rid of this.
I had the same problem. Use these files:
https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.js
https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.css
It worked for me.
I know it's a bit late, however I was facing the same issue. The problem I was having was a race condition where only the last thumbnail was loaded and the others were stuck before completing, because i changed before createThumbnailFromUrl was getting it's data. Putting the call inside function did the trick for me:
for (var i = 0; i < images.length; i++) {
var temp = { name: images[i], dataURL: images[i] };
myDropzone.files.push(temp);
myDropzone.emit("addedfile", temp);
createThumbnail(temp);
}
function createThumbnail(temp) {
myDropzone.createThumbnailFromUrl(temp,
myDropzone.options.thumbnailWidth,
myDropzone.options.thumbnailHeight,
myDropzone.options.thumbnailMethod, true, function (thumbnail) {
myDropzone.emit('thumbnail', temp, thumbnail);
myDropzone.emit("complete", temp);
});
}
My answer is inspired by BLitande's, which helped me getting it to kind of work in the first place.

Preload ajax loaded content

On my site I use one core/frame PHP file. If user hit one of my link (like contact, our about..etc..) the content loaded via ajax. I use the following snippet to achieve this:
var AjaxContent = function(){
var container_div = '';
var content_div = '';
return {
getContent : function(url){
$(container_div).animate({opacity:0},
function(){ // the callback, loads the content with ajax
$(container_div).load(url, //only loads the selected portion
function(){
$(container_div).animate({opacity:1});
}
);
});
},
ajaxify_links: function(elements){
$(elements).click(function(){
AjaxContent.getContent(this.href);
return false;
});
},
init: function(params){
container_div = params.containerDiv;
content_div = params.contentDiv;
return this;
}
}
}();
I need help how to integrate a preloading, so if visitors hit one of my link (for example the gallery menu) will see a little loading image, because now they see the big white nothing for long - long seconds.
Add loading image beforing ajax call and after you get response from server simply replace that image with data like the one below
function(){ // the callback, loads the content with ajax
$(container_div).html("<img src='loading.gif' />");//add image before ajax call
$(container_div).load(url, //only loads the selected portion
function(){
$(container_div).html(data);//replace image with server response data
$(container_div).animate({opacity:1});
}
Try this
var AjaxContent = function(){
var container_div = '';
var content_div = '';
return {
getContent : function(url){
$(container_div).html('Loading...'); //replace with your loading img html code
$(container_div).load(url, //only loads the selected portion
function(){
$(container_div).css({opacity:0});
$(container_div).animate({opacity:1});
});
},
ajaxify_links: function(elements){
$(elements).click(function(){
AjaxContent.getContent(this.href);
return false;
});
},
init: function(params){
container_div = params.containerDiv;
content_div = params.contentDiv;
return this;
}
}
}();

Resources