FineUploader uploads the same file multiple times at the same time - fine-uploader

Say I want to upload several files at once, which is something I can do when setting the multiple option to true:
var myUploader = new qq.FineUploader({
element: $('#test')[0],
multiple: true,
request: { endpoint: 'path/to/master/server/php/' },
autoUpload: false,
});
Now, let's say I have a button that will allow me to select the files I want to upload. If I click said button and select, say, test.txt file, test.txt will be added to the list of files that will be uploaded. So far so good. Now, my problem is that, if I click the button again, and select test.txt file again, it will be added to the list even though it's already in the list.
Is there any way to prevent FineUploader from letting me do this?
Thanks in advance

I'd be careful declaring a file a duplicate simply based on the name. You should also take size into account, at least. Although, this is not possible in IE9 and older since we can't determine file size client-side in those browsers. Just for the purposes of simplicity, let's use the file name exclusively...
One way is to maintain an array of file names submitted to the uploader. You can add to this list in your an onSubmitted handler. The, you can contribute an onValidate handler that will reject the file if it already exists in the array. Your code would look something like this:
var filenames = [];
var myUploader = new qq.FineUploader({
element: $('#test')[0],
multiple: true,
request: { endpoint: 'path/to/master/server/php/' },
autoUpload: false,
callbacks: {
onSubmitted: function(id, name) {
filenames.push(name);
},
onValidate: function(fileData) {
return qq.indexOf(filenames, fileData.name) < 0;
}
}
});
Also, just for kicks, why not just use Fine Uploader's jQuery plug-in, since you seems to already be using jQuery in your project? The above example is rewritten using the jQuery plug-in below:
var filenames = [];
$('#test').fineUploader({
multiple: true,
request: { endpoint: 'path/to/master/server/php/' },
autoUpload: false
})
.on("submitted", function(event, id, name) {
filenames.push(name);
})
.on("validate", function(event, fileData) {
return $.inArray(fileData.name, filenames) < 0;
});

Related

Ideal way to ajax load a view in Drupal 8 with contextual filters

I have a taxonomy called category.
I have a menu with links to each of these taxonomy items.
The Taxonomy page for each of these items has that menu and also contains a view which uses a contextual filter from the URL to filter the content of the view to content with that taxonomy term.
I wanted to Ajax load the view content when one of these menu items is clicked.
I've been able to achieve the desired result by enabling ajax on the view and using the following JavaScript.
(function ($) {
Drupal.behaviors.course_browser = {
attach: function (context, settings) {
// should only be one menu, but guard against 0, and avoid the if statement.
context.querySelectorAll(".menu--categories").forEach((menu) => {
// for each link in the menu
menu.querySelectorAll(".nav-link").forEach((link) => {
// on click
link.addEventListener("click", (event) => {
event.preventDefault();
// fetch the taxonomy term id from menu link
let tid = event.target.dataset.drupalLinkSystemPath.replace(
"taxonomy/term/",
""
);
// make the ajax call
$.ajax({
url: "/views/ajax",
type: "post",
data: {
view_name: "course_browser",
view_display_id: "block_1",
view_args: tid,
},
success: (response) => {
response.forEach((action) => {
// the response contains a number of commands; I'm not sure
if (
action.command === "insert" &&
action.method === "replaceWith"
) {
let viewElement = document.querySelector(VIEW_SELECTOR);
// update the html of the course browser
viewElement.innerHTML = action.data;
// update the url in the browser
window.history.pushState("", "", event.target.href);
// seperate function to adjust my page title
updatePageTitle(event.target.textContent);
// call drupal behaviours passing context to ensure all the other js code gets a chance to manipulate the new content
Drupal.attachBehaviors(viewElement);
}
});
},
error: function (data) {
console("An error occured fetching the course browser");
},
});
});
});
});
},
};
})(jQuery);
I'm looking for feedback on my approach here; my main concern at the moment is the way I handle the response. When I look at the response I receive something like that shown below:
0: {command: "settings", settings: {…}, merge: true}
1: {command: "add_css", data: "<link rel="stylesheet" media="all" href="/core/modules/views/css/views.module.css?qcog4i" />↵"}
2: {command: "insert", method: "append", selector: "body", data: "<script src="/core/assets/vendor/jquery/jquery.min…/js/modules/views/ajax_view.js?qcog4i"></script>↵", settings: null}
3: {command: "insert", method: "replaceWith", selector: ".js-view-dom-id-", data: "The HTML"}
As you can see, I'm manually handling the response by cherry picking the part I want and replacing the HTML of view. Based on what I've seen around Drupal, I think there should be something I can pass this response to that handles it automatically. When I look at the window object of the browser, I can see Drupal.AjaxCommands which looks like it was designed to handle this, but I'm not sure how I should be using this.
I also note that in the case I can simply pass this response to something to have those AjaxCommands executed, the selector ".js-view-dom-id-" isn't right. So I could tweak the response before I pass it, or if someone knows a way to adjust the ajax request to perhaps get the right selector, that would be ideal.
Sorry if this info is readily available somewhere...there are quiet a few resources around related to Drupal and Ajax but I haven't been able to find examples of exactly what I'm doing here, the circumstances always seem to differ enough that I can't use them.
Thanks for any help.

FineUploader Pause if PDF

I would like to pause fineuploader if the document dropped is a pdf to give the end user some options before continuing. I cannot figure out how to get the pause to trigger. I am getting [Fine Uploader 5.3.2] Ignoring pause for file ID 0 (DEVELOPMENT.PDF). Not in progress.
My code below.
var uploader = new qq.s3.FineUploader({
debug: true,
element: document.getElementById('fine-uploader'),
request: {
endpoint: 'bucketname.s3.amazonaws.com',
accessKey: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' //zone-user key id
},
signature: {
endpoint: "/assets/plugins/fine-uploader/signature/endpoint.php"
},
debug:true,
cors: {expected: true},
chunking: {enabled: true},
resume: {enabled: true},
deleteFile:{enabled:false},
validation: {
itemLimit: 5,
sizeLimit: 15000000
},
uploadSuccess:{
//endpoint:"/assets/plugins/fine-uploader/signature/endpoint.php?success"
},
callbacks: {
onSubmitted: function(id, name) {
var fileName = name;
var fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1).toUpperCase();
if(fileExtension==='PDF'){
alert('it IS pdf... now what?');
jQuery('#confirmPDFHandler').modal();
uploader.pauseUpload(id); //not pausing here
}else{
alert('its not a pdf... go!');
uploader.continueUpload(id);
}
},
onError: function(id, name, errorReason, xhrOrXdr) {
//alert(qq.format("Error on file number {} - {}. Reason: {}", id, name, errorReason));
},
onUpload: function(id, name, isError,responseJSON) {
var obj = JSON.stringify(responseJSON);
//alert(name + 'is in progress');
},
onComplete: function(id,fileId,responseJSON){
var newfilename=uploader.getKey(id);
}
},
retry: {enableAuto: false}
});
If the user drops a pdf in the uploader, we will give them an option to simply upload (continue as usual) or split the file (pause or stop the upload and run our separate custom code to begin the pdf split option pulling one document into multiple documents then passing those to an uploader)
Sounds like you want to potentially cancel the upload, or proceed. In that case, you should ask the user for input inside of an onSubmit or onValidate event handler. Your handler should return a Promise and either resolve the promise to allow the file to go through, or reject it to cancel the file submission. For example:
onSubmit: function(id) {
return new Promise(function(resolve, reject) {
// popup modal
// when user responds...
// ...call resolve() if they want to upload the file
// ...or reject() if they want to cancel the file
});
}
Fine Uploader has a very small "promise" implementation bundled with the library. It's non-standard, so you may be better off finding a standard A+ implementation instead.

Fancytree Lazyload: Make Ajax call each time it expands

I have a tree folder structure that I am displaying in a webpage using Fancytree and using the lazyLoad option to display the contents of the folder ondemand. This works fine for the first time, but if there are no items under a folder and when expanded, since there are no items, the icon to expand/collapse disappears. When i create some folders in at empty folder, I dont have a way to fire an ajax call again to display the new contents. Any idea how this can be achieved?
$("#officialTreeView").fancytree({
extensions: ["table"],
aria: true,
source: {
url: "myurl/jsonoutput",
data: {key: "1" },
cache: false
},
lazyLoad: function(event,data) {
var node = data.node;
//data.node.load(true);
// Issue an ajax request to load child nodes
data.result = { cache:false, url: "myurl/jsonoutput", data: {key: node.key } }
},
renderColumns: function(event, data) {
var node = data.node,
$tdList = $(node.tr).find(">td");
//console.log(node);
$tdList.eq(1).text(node.data.childcount);
}
});
You can call node.resetLazy() or node.load(true) (for example when a node is collapsed).
See http://wwwendt.de/tech/fancytree/doc/jsdoc/FancytreeNode.html for a complete list of methods.
i.e just add an event handler for collapse to your config
collapse: function(event, data){
data.node.resetLazy();
},

Valums Ajax Upload with Codeigniter: Get Parameters!

How do I use paramaters with Valums Uploader and Codeigniter?
With Valums the parameters are set like so:
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '/server-side.upload',
// additional data to send, name-value pairs
params: {
param1: 'value1',
param2: 'value2'
}
});
or using
uploader.setParams({
anotherParam: 'value'
});
if you want it to be aware of the state of your app/
subD="/Pic"
function selectGaleryName()
{
subD=subD+"/3"
alert(subD) // /Pic/3
}
var uploader = new qq.FileUploader({
element: document.getElementById('UploadFile'),
action: 'http://localhost/Farainform/manager/upload.php'
// additional data to send, name-value pairs
onComplete: function(id, fileName, responseJSON){
selectGaleryName();
uploader.setParams({
subDirectory : subD
});
},
});
if you want to set an id and a description for an image you can set these in javascript and then send these. So something like (im using jQuery here):
var description = $('#input_description').val(); //This can be an input
var id = $('#input_description').att('id');
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '/server-side.upload',
// additional data to send, name-value pairs
params: {
description: description,
id: id
}
});
Note I havent tested this code and its for demonstration purposes.
$_GET was always destroyed in the 1.7.3 branch but upgrade to the new CodeIgniter Reactor 2.0 and you'll find that GET strings work out of the box.
When upgraded, use this syntax:
$this->input->get('value1');
I don't know why it is not documented on Valums page, but apparently parameters should be sent not like this
params: {
param1: 'value1',
param2: 'value2'}
But like this
data: {param1: 'value1',
param2: 'value2'}
On server side you could get them with $_REQUEST['param1'];
You have to use PHP's input stream in order to obtain the data.
$fp = fopen('php://input', 'r');
Then read the data as you normally would with a regular file using fread(). Refer to valum's server side code located in server/php.php within the download.
Two related issues that I ran into that might help someone out:
1) var uploader causes issues - try using something like ajaxuploader instead
2) the documented setParams is incorrect for the latest release - it should be setData
The end result should be something like this:
var ajaxuploader = new AjaxUpload(button, {
action: 'your-server-script.php',
name: 'myfile',
onSubmit : function(file, ext){
ajaxuploader.setData({
somevar : 'somevalue',
anothervar : 'anothervalue'
});
)};

Ajax Upload using valums ajax upload plugin inside a form

i just came across this ajax upload plugin and i wish to use it inside a form as shown in the demo page example 3. For some reason i am not able to make it work. I am not sure what parameters come into the function. For example here is my sample code.
$(document).ready(function(){
var upload = new AjaxUpload('property_i',
{
action: 'submitproperty.php',
autoSubmit: false,
onSubmit : function(file , extension){
return false;
}
});
var upload_data = upload.setData({
'propertytype':'propertytype'
});
});
Now the ID used in the AjaxUpload function should be ID of the or of the Entire form. Also how do i use setData method. Any suggestions or links will be very helpful. Thanks
I got it to work with the following code:
new AjaxUpload('#uploader_button', {
action: 'filename.ashx',
autoSubmit: true,
onSubmit: function(file, ext) {
// --- stuff here
// --- add postdata parameters
this.setData({ id: 1, title: docTitle.val() });
},
onComplete: function(file, response) {
// --- stuff here too
}
});
it doesn't utilize the var but instead adds the custom data params in the onSubmit block. The only other difference is that I haven't wrapped the parameter key in quotes as it seems to serialize correctly. And I'm not using autoSubmit: false , but instead it's true...
The only way I could get this to work with autoSubmit: false is to add this outside any function:
var uploader;
var uploadFile;
then in the AjaxUpload(...
onChange: function(file, response){
uploader = this;
uploadFile = file;
},
then in the function to do the upload:
uploader.setData({session: session});
uploader.submit();
Hope this helps
I'm using uploadify and very useful.
http://www.uploadify.com/

Resources