I am currently using Filepond to upload images to an S3 bucket. This functionality works great on a computer or on iOS devices but refuses to work on Android devices and I'm having the time of my life figuring out the root cause. It should upload just fine across all devices. Has anyone experienced any issues similar to this on an Android device using Filepond? I've also attached below the relevant Filepond code. I don't see any issues with it, but of course, I may be missing something. If anyone could offer a pointer or any kind of advice it would be greatly appreciated or if I left anything out please let me know. Thanks!
JS
<!-- Load FilePond library -->
<script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.js"></script>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2#10"></script>
<!-- include FilePond jQuery adapter -->
<script src="https://unpkg.com/jquery-filepond/filepond.jquery.js"></script>
<script type="application/javascript">
let tags = [];
let folderOpen = false;
let currentTag = "Uncategorized";
let imageUploadUrl = "{{ url_for('testing_jobs.job_image_upload', id=job.id) }}";
// Page init code
$( document ).ready(() => {
// Select Fields
$(".select2").select2();
// Setup FilePond inputs
$.fn.filepond.registerPlugin(FilePondPluginImagePreview);
// Turn input element into a pond
$('.filepond').filepond();
// Set FilePond properties
$('.filepond').filepond('allowMultiple', true);
$('.filepond').filepond('instantUpload', true);
$('.filepond').filepond('server', {
url: imageUploadUrl,
process: {
onload: (res) => {
// Select the response field to use as a unique ID
let image = JSON.parse(res).image;
if (folderOpen) {
getJobImages(currentTag);
} else {
alert("Image added")
}
return image.id;
}
}
});
// Listen for addfile event
$('.filepond').on('FilePond:addfile', function(e) {
console.log('file added event', e);
// Set the current tag for the image
e.detail.file.setMetadata("tag",currentTag);
});
// Listen for processfile event
$('.filepond').on('FilePond:processfile', function(e) {
console.log('file process event', e);
setTimeout(() => {
e.detail.pond.removeFile();
}, 2000);
});
Html for submitting
<div class="card">
<div class="card-header">
<h4>Upload Images</h4>
</div>
<div class="card-body">
<input type="file" class="filepond">
</div>
</div>
The issue turned out to be the image attachments on my Android device. Set up some checks for checking the file types and now it all works.
Related
I want to create an app that shows different songs i've chosen, with react.js
The problem is that it doesn't work with local files. Path is ok (just checked in the DOM)
I've tried with relative path and absolute path but it is still the same.
I've tried a lot of things, such as importing react-sound, react-audio-player...
I've tried to directly import the mp3 file at the beginning of the file with "import song from "./songs/song.mp3" and it works, but it is useless as you have to add it manually if you want to add/delete songs.
When I press the play button, it always fails the promise and returns me the error :
DOMException: Failed to load because no supported source was found.
import React from "react";
const SongCard = (props) => {
const playAudio = () => {
const audio = new Audio(props.song.path)
const audioPromise = audio.play()
if (audioPromise !== undefined) {
audioPromise
.then(() => {
// autoplay started
console.log("works")
})
.catch((err) => {
// catch dom exception
console.info(err)
})
}
}
return (
<div className="songCard">
<div className="coverContainer">
<img src=""/>
</div>
<div className="infoContainer">
<div className="playPauseButton" onClick={playAudio}>►</div>
<div className="songTitle">{props.song.nom}</div>
</div>
</div>
);
};
export default SongCard;
Does anyone have an idea ?
Due to security issues, you won't be able to access local files programatically from JavaScript running in browser.
The only way you can get a hold of local files is by:
User selecting the file via a file <input>
User drag and dropping the files into your application
This way the user is explicitly giving you access to those files.
You can either design your application around those interactions, or
You can start a web server locally where it has access to your audio files and stream those to your app or upload the files to a cloud service.
you can do it by using this code:
const SongCard = (props) => {
const playAudio = () => {
let path = require("./" + props.song.path).default;
const audio = new Audio(path);
const audioPromise = audio.play();
if (audioPromise !== undefined) {
audioPromise
.then(() => {
// autoplay started
console.log("works");
})
.catch((err) => {
// catch dom exception
console.info(err);
});
}
};
return (
<div className="songCard">
<div className="coverContainer">
<img src="" />
</div>
<div className="infoContainer">
<div className="playPauseButton" onClick={playAudio}>
►
</div>
<div className="songTitle">{props.song.nom}</div>
</div>
</div>
);
};
export default SongCard;
it'll work if you change the "./" in the require to the relative path of the audio's dictionary, and send only the name of the audio file in the parent's props
I hope I was help you
We have an application running that currently works with both 3D and 2D files, and do not experience any issues when loading 3D files and DWG.
But when trying to load a PDF neither my "onItemLoadSuccess" or "onItemLoadFail" gets run
Autodesk.Viewing.Initializer(options, function onInitialized() {
// Select the container for the viewer
viewerApp = new Autodesk.Viewing.ViewingApplication(container);
// Load settings, i.e extension manager
viewerApp.registerViewer(viewerApp.k3D,
Autodesk.Viewing.Private.GuiViewer3D, { extensions: [ 'ExtensionManager'] });
// Select model to load defined by URN
viewerApp.loadDocument(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
}
function onDocumentLoadSuccess(doc) {
var viewables = viewerApp.bubble.search({ 'type': 'geometry' });
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
// Choose any of the avialble viewables
viewerApp.selectItem(viewables[0], onItemLoadSuccess, onItemLoadFail);
}
function onItemLoadSuccess(viewer, item) {
console.log('onItemLoadSuccess()!');
}
function onItemLoadFail(errorCode) {
console.error('onItemLoadFail() - errorCode:' + errorCode);
}
The PDF file will still open and load, so I am wondering if there might be a different way to run an onItemLoadSuccess function, or we have to do something a bit differently to ensure that our PDF's also gets loaded correctly.
Any help is highly appreciated!
Starting from Viewer v6.3 you can load PDF directly with Autodesk.PDF and pass in callbacks to loadModel like you do other models:
Autodesk.Viewing.Initializer(options, function() {
viewer.start()
viewer.loadExtension('Autodesk.PDF').then(function() {
viewer.loadModel('/path/to/pdf', { page: 1 }, onLoadSuccess, onLoadFail);
});
});
See release notes here: https://forge.autodesk.com/blog/viewer-release-notes-v-63
(Adding to Bryan's answer...)
I wrote a blog post about this. Take a look at the DEMO and sample code to help answer your question about 'onItemLoadSuccess / onItemLoadFail' events.
BLOG: https://forge.autodesk.com/blog/fast-pdf-viewingmarkup-inside-forge-viewer
DEMO: https://wallabyway.github.io/offline-pdf-markup/
Hope that helps!
I'm having this problem for some time ow and I can't seem to find a solution.
I'm using the latest html2canvas js plugin to take a screenshot of chart made with flotcharts and then submit the base64 screenshot via a hidden input. The problem is the div with the chart also has some images and html2canvas return a base64 string before the images are loaded. I can put a setTimeout on the submit untill they are loaded but apparently chrome opens the page where I submitted as a popup (which is really not ok cause our clients don't know how allow popups).
So this is what I tried but the images are not preloaded (because of the async nature of html2canvas)
function getPNGBase64forHtml($container) {
var imageString;
html2canvas($container, {
useCORS: true,
onrendered: function(canvas) {
imageString = canvas.toDataURL('image/png');
}
});
return imageString;
}
And also this (this works ok but it doesn't load the images in time):
function getPNGBase64forHtml($container) {
var h2canvas = html2canvas($container);
var queue = h2canvas.parse();
var canvas = h2canvas.render(queue);
return canvas.toDataURL('image/png');
}
So the problem is with waiting till the images are loaded in html2canvas then exeuting the rest of my stuff.
If anyone can please help, that would be very much appreciated, I bow to you kind sirs and madams! :)
Edit:
Here is the html of the part that I capture, this all is in a print-container div thats all. The arrow (only one is showed) in the timeline-prognose doesn't get captured cause it's a image, everything else does:
<div id="timeline-outer-container">
<div id="timeline-container" class="flot-container">
<div id="timeline-chart" class="flot-chart">
<canvas class="flot-base" width="888" height="335" ></canvas>
<div class="flot-text" >
<div class="flot-x-axis flot-x1-axis xAxis x1Axis">
<div class="flot-tick-label tickLabel" >Q1</div>
<div class="flot-tick-label tickLabel">Q2</div>
...
</div>
<div class="flot-y-axis flot-y1-axis yAxis y1Axis">
<div class="flot-tick-label tickLabel">75</div>
<div class="flot-tick-label tickLabel">100</div>
...
</div>
</div>
<canvas class="flot-overlay" width="888" height="335"></canvas>
<div class="axis-label xaxis">Zeitraum</div>
<div class="axis-label yaxis rotate-90">Anzahl</div>
<div id="zoom-out-button" class="timeline-zoom-button"><i class="fa fa-zoom-out"></i></div>
<div id="zoom-in-button" class="timeline-zoom-button"><i class="fa fa-zoom-in"></i></div>
<div id="zoom-default-button" class="timeline-zoom-button"><i class="fa fa-repeat"></i></div>
</div>
</div>
</div>
<div id="timeline-prognose">
<img id="timeline-arrow-up" class="timeline-arrows" src="/portal//images/arrows/up.png" alt="">
<img id="timeline-arrow-down" class="timeline-arrows" src="/portal//images/arrows/down.png" alt="">
</div>
So since you're using remotes images you can use the following fix doing some modifications in your script:
function getPNGBase64forHtml() {
var imageString;
html2canvas(document.body, {
useCORS: true,
logging : true, //Enable log (use Web Console for get Errors and Warnings)
proxy :"html2canvasproxy.php",
onrendered: function(canvas) {
var img = new Image();
img.onload = function() {
img.onload = null;
document.body.appendChild(img);
};
img.onerror = function() {
img.onerror = null;
if(window.console.log) {
window.console.log("Not loaded image from canvas.toDataURL");
} else {
alert("Not loaded image from canvas.toDataURL");
}
};
imageString = canvas.toDataURL('image/png');
}
});
return imageString;
}
If you are using php then the proxy setting must use the following script: html2canvas-php-proxy
Otherwise with .NET projects you can use these script resources:
html2canvas proxy with asp-classic - vb
html2canvas proxy with asp.net - csharp
If you decided to use local images this bug will not appear.
Hope it works for you, here is the original thread for this html2canvas bug https://github.com/niklasvh/html2canvas/issues/145
I'm needing help with an answer to a previous question
How to limit the number of dropzone.js files uploaded?
where there was a solution to use
Dropzone.options.myAwesomeDropzone = {
accept: function(file, done) {
console.log("uploaded");
done();
},
init: function() {
this.on("addedfile", function() {
if (this.files[1]!=null){
this.removeFile(this.files[0]);
}
});
}
};
But being a js numpty, I don't know where to put this. I assume that my form must have the id myAwesomeDropzone and that the code above needs to be slotted into the dropzone.js document, but where? if you could provide a 'after' and 'before' or replace answer please.
If someone could give me some pointer it'd be great.
My reputation is less than 50 so I couldn't comment on the original thread. If me posting this as a new thread is wrong, please admins don't just chastise me and close it, but move it or do whatever to allow people to provide help accrodingly.
Cheers
Andy
Your html form should be like below. Notice that the
class="dropzone"
and
id="my-dropzone"
The "my-dropzone" ID is important , DropZone takes this as "myDropzone" , ( hyphen removed and camelcased ). So when you refer to this id in DropZone.options , it should be "myDropzone". This is very important.
<div>
<form action="/file-upload" class="dropzone" id="my-dropzone" style="border:2px dotted #337ab7">
<div class="dz-message">
Drag n drop photos here or click to upload.
<br />
<span class="note">(The photos are uploaded to twitter only when the tweet is sent.)</span>
</div>
</form>
</div>
Your should link the css and js file in your html page like so
<script src="./js/dropzone.min.js"></script>
<link href="./css/dropzone.min.css" rel="stylesheet" type="text/css">
On the page load , you should init the dropzone configuration in your JS code for your page as below. I am restricting dropzone to accept only one file and its size should not exceed 5MB.
self.options.maxFilesize = 5; self.options.maxFiles = 1;
Dropzone.autoDiscover = false;
Dropzone.options.myDropzone = {
init: function() {
var self = this;
// config
self.options.addRemoveLinks = true;
self.options.autoProcessQueue = false;
self.options.maxFilesize = 5;
self.options.maxFiles = 1;
self.options.dictFileTooBig =
"Twitter do not allow files greater than 5MB.";
//New file added
self.on("addedfile", function(file) {
console.log('new file added ', file.path);
});
self.on("maxfilesexceeded", function(file) {
alert(
"Only one photo can be attached with the tweet."
);
});
}
};
Now when your page loads , you will see the form & get the drag n drop functionality in your div.
To access the files you can do like below in the javascript on some button click event.
// to get queued files
var myDropzone = Dropzone.forElement("#my-dropzone");
var files = myDropzone.getQueuedFiles();
I'm working on a simple application which is single page based (due to project restrictions) and has dynamic content. I understand the dynamic content alright but what I don't understand is how to set-up a script that changes the html of a div when the hash value in the URL changes.
I need a JavaScript script to work as such:
Url: http://foo.com/foo.html div contents: <h1>Hello World</h1>
Url: http://foo.com/foo.html#foo div contents: <h1>Foo</h1>
How would this work?
Please help! Thanks.
You can listen to the hashchange event:
$(window).on('hashchange',function(){
$('h1').text(location.hash.slice(1));
});
personally, I'd use sammy which gives you the flexibility to template the hashtag (add placeholders and be able to read them back). e.g.
<script src="/path/to/jquery.js"></script>
<script src="/path/to/sammy.js"></script>
<script>
$(function(){
// Use sammy to detect hash changes
$.sammy(function(){
// bind to #:page where :page can be some value
// we're expecting and can be retrieved with this.params
this.get('#:page',function(){
// load some page using ajax in to an simple container
$('#container').load('/partial/'+this.params['page']+'.html');
});
}).run();
});
</script>
Load foo.html
Load bar.html
An example can be found here: http://jsfiddle.net/KZknm/1/
Suppose we have list of items, each items has a hash tag as #id
const markup = `
<li>
<a class="results__link" href="#${recipe.recipe_id}">
<figure class="results__fig">
<img src="${recipe.image_url}" alt="${limitRecipeTitle(recipe.title)}">
</figure>
<div class="results__data">
<h4 class="results__name">${recipe.title}</h4>
<p class="results__author">${recipe.publisher}</p>
</div>
</a>
</li>
`;
Now when a user click on any of those list item or reload (http://localhost:8080/#47746) an item with hash tag, hash event will be fired. To recive the fired hash event we must register hash event listener in our app.js
//jquery:
['hashchange', 'load'].forEach(event => $(window).on(event, controlRecipe));
//js:
['hashchange', 'load'].forEach(event => window.addEventListener(event, controlRecipe));
catch the id in your controlRecipe function
const controlRecipe = async ()=>{
//jq
const id = $(window)..location.hash.replace('#','');
//js
const id = window.location.hash.replace('#','');
if(id){
//console.log(id);
state.recipe = new Recipe(id);
try {
await state.recipe.getRecipe();
state.recipe.calcTime();
state.recipe.calcServings();
console.log(state.recipe);
} catch (error) {
alert(error);
}
}
}