How to display cancel button for failed uploads in fineuploader? - javascript

I am using fineuploader. Some upload may fail as user try to upload duplicate file.
I see a red color and the error message from server is shown.
I am not seeing any cancel OR Remove button that would allow the user to start fresh again by selecting a new file.
I was expecting fineuploader to show cancel button on failed files but it is not.
I can add onError callback then find the right row and show the cancel or other button by adding Remove button. That sound messy solution.
That cancel button would remove that file and let user select another file.
Can I add this capability by setting options in the settings?
var fileUploader = new qq.FineUploader({
element: $('#manual-fine-uploader')[0],
request: {
endpoint: 'upload/UploadFiles',
},
multiple: true,
autoUpload: false,
validation: {},
text: {uploadButton: '<i class="icon-plus icon-white"></i> Select File'},
callbacks: {
onSubmit: function (id, file) {//my custom code },
onCancel: function(id, file){ if(filesCount>=1) filesCount--;},
onComplete: function (id, fileName, responseJSON) {filesCount--;}
},
failedUploadTextDisplay: {
mode: 'custom',
maxChars: 40,
responseProperty: 'error',
enableTooltip: true
}
});
Thanks

Fine Uploader only displays a cancel button while a file is uploading (as well before uploads have started if you have set the autoUpload option to false). Showing a cancel button after the upload has completed seems like it would be a bit confusing to users, but I can see why you might want to display a "remove" button.
You can easily do this by adding the button to the file portion of your template. For example, your template might look similar to this:
<div class="qq-uploader-selector qq-uploader">
...
<ul class="qq-upload-list-selector qq-upload-list">
<li>
...
<button class="remove-button-selector" style="display:none">Remove</button>
</li>
</ul>
</div>
Then, add a click handler to purge the file from Fine Uploader's internals & the UI:
$('#manual-fine-uploader').on("click", ".remove-button-selector", function() {
var fileId = fileUploader.getId(this);
fileUploader.cancel(fileId);
});
Finally, in your onComplete handler, show the button if the upload has failed:
onComplete: function(id, name, response, xhr) {
var fileItemEl = fileUploader.getItemByFileId(id);
if (!response.success) {
$(fileItemEl).find(".remove-button-selector").show();
}
}
Additionally, since you are already using jQuery in your project, I strongly suggest you make use of the Fine Uploader jQuery plug-in. It will make your life a bit easier.

Related

Clear upload area in Vue2-Dropzone

I'm currently working on Laravel Vue SPA admin panel. And I've applied Vue2-Dropzone to upload images for the gallery section.
In this project the vue2-dropzone form opens on a bootstrap model.
My codes successfully uploads the images. When I close the model and reopen it to upload other images it shows the thumbnails of previously uploaded images.
Below is my code snippet:
import vue2Dropzone from "vue2-dropzone";
import "vue2-dropzone/dist/vue2Dropzone.min.css";
export default {
data() {
return {
dropzoneOptions: {
url: "/api/carousel",
maxFilesize: 10,
acceptedFiles: '.jpg, .jpeg',
dictDefaultMessage: "Click or Drag and Drop to upload",
headers: {
"X-CSRF-TOKEN": document.head.querySelector("[name=csrf-token]")
.content
}
}
};
},
methods: {
newModal() {
vue2Dropzone.removeAllFiles(true);
$("#addNew").modal("show");
}
},
components: {
vueDropzone: vue2Dropzone
}
};
With the above code I get the following error after clicking the add image button that opens the model to upload images:
app.js:84606 Uncaught TypeError: __WEBPACK_IMPORTED_MODULE_0_vue2_dropzone___default.a.removeAllFiles is not a function
at VueComponent.newModal (app.js:84606)
at invoker (app.js:54930)
at HTMLButtonElement.fn._withTask.fn._withTask (app.js:54729)
I want to clear the thumbnails of previously uploaded images from dropzone modal.
Can anyone help me out on this ?
Assume you have vue-dropzone with ref in template
<vue-dropzone ref="myVueDropzone" id="dropzone">
</vue-dropzone>
then you should use
this.$refs.myVueDropzone.removeAllFiles()
The removeAllFiles() is kind of a hack. It won't work for some cases.
For example, it will not 'reset' the Dropzones' options object. So if you want to do validations for diferent cases via the options object, it will not reset with the removeAllFiles() method.
The right way to reset the Dropzone (or any Vue object in that matter) is to set and change the :key attribute. Like this for example:
<vue-dropzone :key="`dropzone-${dynamicVariableOrJustSomeCounter}`">
</vue-dropzone>

Custom Summernote Button to create links with classes

So I'm thoroughly confused as how to make a custom SummerNote button which will allow me to either add classes to an already inserted HTML element (i.e. links) or even wrap selected text in something like:
<button class="btn btn-primary"> **selected text** </button>
From the Summernote Deep Dive it shows how to create a custom button that inserts static text and I understand how to implement it. However, I can't seem to figure out how to make it dynamic for whatever text is selected. I've tried replacing the 'text' part of the example after context.invoke call but it doesn't convert the text to html, it just prints it.
The need is for creating links as buttons. Ideally I'd wish to access the Insert Link dialog already built into SummerNote to make buttons that will insert links with predefined classes but I'm not sure how complicated that would be.
Does anyone have any suggestions?
var bsButton = function (context) {
var ui = $.summernote.ui;
// create button
var button = ui.button({
contents: 'Btn',
tooltip: 'Create Button',
click: function () {
// invoke insertText method with 'hello' on editor module.
context.invoke('editor.insertText', '<button class="btn btn-primary"></button>');
}
});
return button.render(); // return button as jquery object
}
I've reviewed a ton of different posts but I haven't gotten much further than the example for what I'm trying to accomplish. Thanks in advance to anyone who takes the time to help.
As I was doing more research I stumbled upon Summernote's 'Awesome Summernote' GitHub page which led me to a plugin, summernote-addclass. While this doesn't necessarily answer the heart of the question (i.e. achieving this same thing without a plugin) but it does exactly what I need to do. Maybe this will help someone else in the future. Enjoy!
By using jQuery in summernote callback method onInit I have added custom class for custom button
Here is my custom button code:
var AddPage = function(context) {
var ui = $.summernote.ui;
var button = ui.button({
contents: '<i class="fa fa-plus"/> Add Page',
tooltip: "Set a New Page",
class: "btn-primary",
click: function() {
addPage();
}
});
return button.render();
};
And i use callback methods to add custom class btn-primary to the button
$("#editor").summernote({
airMode: false,
dialogsInBody: false,
toolbar: [["mybutton", ["customButton"]],
buttons: {
customButton: AddPage
},
callbacks: {
onInit: function(e) {
var o = e.toolbar[0];
jQuery(o)
.find("button:first")
.addClass("btn-primary");
}
}
});
});
I think this may be helpful for anyone, even if this is not gud answer.

filepicker-rails w/signup form: button to `remove` the file in Filepicker

In my Rails 3.2 app I am using Filepicker through the filepicker-rails gem to allow users to upload a profile photo on the signup form. In the f.filepicker_field I am using the onchange option to call an onImageUpload() function that gets information about the newly uploaded image from the automatically-generated event.fpfile and disables the Filepicker browse button:
function onImageUpload() {
file = event.fpfile
img = $("<img>").prop("src", file.url).css({
width: '160px',
height: '160px',
});
$("#profile_photo_preview").append(img);
$(".filepicker-button").toggleClass("disabled");
};
I read about the event.fpfile at the Filepicker docs section on Widgets. In the form I also have a link that, when clicked, removes the recently updated image from the DOM and re-enables the Filepicker button:
:javascript
$(document).ready(function() {
$("#picture-remover").click(function() {
$("#profile_photo_preview").html("");
if ( $(".filepicker-button").hasClass("disabled") ) {
$(".filepicker-button").toggleClass("disabled");
};
});
});
...
...
= link_to "Remove Picture", id: "picture-remover"
This all seems to work pretty well. The only problem is that if a user removes the first picture and then uses the Filepicker browser to upload another, the original picture is still being saved in my Filepicker account.
I'd like to have my "Remove Picture" link remove the picture not only from the DOM, but also from my Filepicker account altogether. The Filepicker docs have a section on removing/deleting files here but I don't really understand the example code or how to implement it for myself. I'm particularly confused about the relationship between the InkBlob that is mentioned for removing a file and the event.fpfile object that I'm using to display a thumbnail preview.
So far I've tried adding the following line to my "Remove Picture" link but nothing happens:
:javascript
$(document).ready(function() {
$("#picture-remover").click(function() {
$("#profile_photo_preview").html("");
if ( $(".filepicker-button").hasClass("disabled") ) {
$(".filepicker-button").toggleClass("disabled");
};
filepicker.remove(InkBlob); #added this line
});
});
Many thanks to anyone who can point me in the right direction!
InkBlob and event.fpfile objects have the same role and the same attributes.
In your example you can pass event.fpfile object to remove function.
var file = event.fpfile;
filepicker.remove(
file,
function(){
console.log("Removed");
}
);
Generally to remove filepicker file you only need it's url.
So this code also works fine:
var someObject = {url: 'https://www.filepicker.io/api/file/xaXphhT9R0GB1tPYUQAr'};
filepicker.remove(
someObject,
function(){
console.log("Removed");
}
);

File uploads: Percentage completed progress bar

I'm trying to add a 'percentage completed so far' progress bar to avatar uploads in BuddyPress. The aim is to stop users navigating away from the page before the upload is completed.
The upload process is handled in BuddyPress by bp_core_avatar_handle_upload() in file bp-core/bp-core-avatars.php. The function starts off by checking that the file has been uploaded properly using bp_core_check_avatar_upload(). It then checks that the file size is within limits, and that it has an accepted file extension (jpg, gif, png). If everything checks out, the user is allowed to crop the image (uses Jcrop) and then the image is moved to its real location.
The actual upload is handled by the WordPress function wp_handle_upload.
How can I create a 'percentage completed' progress bar and display it when the file is uploading?
I'm not familiar with BuddyPress, but all upload handlers (including the HTML5 XHR one that androbin outlined) will have a file progress hook point that you can bind to.
I've used uploadify, uploadifive and swfupload, and they can all interact with the same progress function handler in order to acheive the same progress bar result.
// SWFUpload
$elem.bind('uploadProgress', function(event, file, bytesLoaded) { fnProgress(file, bytesLoaded); })
// Uploadify
$elem.uploadify({ onUploadProgress: function (file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) { fnProgress(file, bytesUploaded); });
// Uploadfive
$elem.uploadifive({ onProgress: function(file, e) { fn.onProgress(file, e.loaded); });
Uploadifive, being an HTML5 based uploader, simply binds to the XHR 'progress' event, so all these properties will be available to any HTML5 uploader.
As for the actual progress bar code..
HTML:
<div class='progressWrapper' style='float: left; width: 100%'>
<div class='progress' style='float: left; width: 0%; color: red'></div>
<div class='progressText' style='float: left;></div>
</div>
JS:
var fnProgress = function(file, bytes) {
var percentage = (bytesLoaded / file.size) * 100;
// Update DOM
$('.progress').css({ 'width': percentage + '%' });
$('.progressText').html(Math.round(percentage + "%");
}
You should use an XHR object. I don't now if it helps you, but I have a simple XHR uploader written.
HTML:
<form id="uploader" enctype="multipart/form-data" action="uploadimage.php" method="post">
<input type="file" id="file" name="file[]" multiple="multiple" accept="image/jpeg" /><br/>
<input type="submit" value="Upload" />
<div class="list" style="background-color:#000;color:#FFF;padding:5px;display:none;border-radius:5px;">
</div>
</form>
JS:
$("#uploader").submit(function(){
$('#uploader .list').fadeIn(100).css("width","0px");
var data = new FormData();
// if you want to append any other data: data.append("ID","");
$.each($('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
$.ajax({
url: 'uploadimage.php',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
xhr: function() { // custom xhr
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
}
return myXhr;
},
success: function(data2){
$('#uploader .list').css({
"width":"200px",
"text-align":"center",
"margin":"10px 0 10px 0"
}).html("DONE!").delay(2000).fadeOut(500);
if (data2 == "ERROR_FILESIZE"){
return alert("Choose another file");
}
else{ /*change location*/ }
});
return false;
});
In this case I uploaded the file with uploadimage.php and if it printed: "ERROR_FILESIZE" then it alerted the error.
I think that before you worry about the client-side of things you should be aware of the server-side requirements to actually be able to accomplish this.
For PHP you need to have the session.upload_progress enabled unless the wp_handle_upload() function uses something different, so I'm here just guessing, but chances are they do use the regular PHP session stuff hence it needs to be enabled.
If you look at the comments for the given link many users say that progress state does not work under certain environments such as PHP on FastCGI which is what you'll get in shared hosting environments most of the time.
Now many people here are telling you to use the XHR uploader but the problem is that they are giving you an example of a custom upload.php script or something like that to send the data, but you are using a wordpress plugin which you don't control (kinda)
So considering that the wp_handle_upload() does not actually works in an AJAX way then you would have to hook an event when the file upload form submit button is clicked and set a timer in JS which calls some URL where you pass the form data like an ID, and then query the session with that ID to check the progress of the file:
$_SESSION["upload_id"]["content_length"]
$_SESSION["upload_id"]["bytes_processed"]
With that data you can calculate how much has been transfered. You could set the JS timer to be called like each second but if the files they are uploading are not very large (say, larger than 1mb) and they have a good connection then there won't be much progress to be notified.
Check this link for a step by step example on how to work with this session upload data.
You need to inject the progress bar.
I think the only way is to over-ride the function bp_core_avatar_handle_upload using the filter hook apply_filters( 'bp_core_pre_avatar_handle_upload' etc. )
You'll end up duplicating most of the function but you should be able to add your progress bar code.
If you get this working, you should submit it as an enhancement ticket; it's a good idea.

dropzone autoProcessQueue not getting picked up

I am using dropzone on my page to upload images, but for some reason it is not picking up the option "autoProcessQueue"
I pasted this exact code in my page and it still uploads as soon as i select the image from this tutorial: https://github.com/enyo/dropzone/wiki/Upload-all-files-with-a-button
Dropzone.options.myDropzone = {
// Prevents Dropzone from uploading dropped files immediately
autoProcessQueue: false,
init: function() {
var submitButton = document.querySelector("#submit-all")
myDropzone = this; // closure
submitButton.addEventListener("click", function() {
myDropzone.processQueue(); // Tell Dropzone to process all queued files.
});
// You might want to show the submit button only when
// files are dropped here:
this.on("addedfile", function() {
// Show submit button here and/or inform user to click it.
});
}
};
I had the same issue, and it turned out that I was using an outdated version of Dropzone. The autoProcessQueue feature was only added in v3.6.0, so make sure you use at least that.
You have to look into ur code that u have made
autoProcessQueue: false,
make it true
autoProcessQueue: true,
and also check this parameter's value in your dropzone.js
and change it there also, It will definitely work..

Categories