Understanding the "file added" callback - blueimp

In the following example: https://github.com/blueimp/jQuery-File-Upload/blob/master/basic-plus.html
We can find the following callback:
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#files');
$.each(data.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
I tried to replicate that code, but can't understand why is there an "each" inside that function, as the callback will be executed once per each uploaded file (so if I'm uploading 3 files at the same time, the callback will be executed 3 times).
So, why is there a need for an "each" loop here? It seems to me that it'll always loop through one element: the uploaded file.
Please help, I'm desperate :(

I think Each loop inside that function is used to append buttons and each file related content Example filename etc....
if you notice the uploadButton has some appended buttonds and click events.

Related

vue-dropzone totaluploadprogress does not work properly

I 'm using https://rowanwins.github.io/vue-dropzone/docs/dist Vue2-Dropzone to work on uploading file.
Everything works fine except calculation of total-upload-progress value goes to 100% and then start from 0% on every file uploads.
I have tried to fix it with
this.$refs.myVueDropzone.updateTotalUploadProgress() adding on file
added event
. But does not work as expected. Any solution would be highly appreciated.
An old question, but facing the same issue I was forced to find a solution and here it is for everyone interested. I apologize for the long property names :-)
I'm listening to the following 2 events of the vue2-dropzone: vdropzone-upload-progress and vdropzone-file-added
<div v-html="'Progress: '+ uploadProgress"></div>
<dropzone id="upload_dropzone" ref="upload_dropzone" :options="dropzoneOptions"
#vdropzone-success="dropzoneOnSuccess"
#vdropzone-upload-progress="dropzoneUploadProgress"
#vdropzone-file-added="dropzoneFileAdded"></dropzone>
I have 3 additional properties in my data object:
data: ()=>{
....
dropzoneTotalFilesize:0,
dropzoneUploadedFilesize:0,
dropzoneCurrentUpload:0
}
},
I got one computed property:
computed:{
uploadProgress(){
return Math.round((this.dropzoneUploadedFilesize + this.dropzoneCurrentUpload) / this.dropzoneTotalFilesize * 100);
}
},
And then my event listeners, that are called in my template above
methods:{
dropzoneFileAdded(file){
this.dropzoneTotalFilesize += file.size;
},
dropzoneUploadProgress(file, totalBytes, totalBytesSent){
this.dropzoneCurrentUpload = totalBytesSent; // write totalBytes to dropzoneCurrentUpload
if(file.size <= totalBytesSent){
this.dropzoneCurrentUpload = 0; // reset current upload bytes counter
this.dropzoneUploadedFilesize += totalBytesSent; // add finished file to total upload
},
.........
},
Maybe it's possible to accomplish the same with abit less code, but this def works for single file upload as well as for multiple file upload.
I hope I could help someone with this, and help to keep VueJS competetive

dragAndDrop using webdriverio

I have tried every single thing to perform dragAndDrop using webdriverio but nothing works. I have also posted a question in the webdriverio gitter but no response. below posted code is one of the ways I tried and its supposed to work but it just doesn't!
` await this.driver.moveToObject(source);
await sleep(2000);
await this.driver.buttonDown(0);
await sleep(2000);
await this.driver.moveToObject(destination);
await sleep(2000);
await this.driver.buttonUp(0);`
I'm not sure what properties are on the source and destination objects you are using but here is an example of how I was able to get it to work using the same commands you are trying.
In my example I have a table with columns that can be re-ordered by dragging and dropping them wherever I want them to be. First I get the two column headers I want to switch
let docIdHeader = browser.element('div[colid="documentid1"]');
let pageCountHeader = browser.element('div[colid="_PAGE_COUNT1"]');
If I log these objects out to the console I can see the properties stored in them.
> docIdHeader
{ sessionId: 'e35ae3e81f1bcf95bbc09f120bfb36ae',
value:
{ ELEMENT: '0.3568346822568915-1',
'element-6066-11e4-a52e-4f735466cecf': '0.3568346822568915-1' },
selector: 'div[colid="documentid1"]',
_status: 0 }
> pageCountHeader
{ sessionId: 'e35ae3e81f1bcf95bbc09f120bfb36ae',
value:
{ ELEMENT: '0.3568346822568915-2',
'element-6066-11e4-a52e-4f735466cecf': '0.3568346822568915-2' },
selector: 'div[colid="_PAGE_COUNT1"]',
_status: 0 }
Now using the same technique you are using and the selector property off of these objects I can get it to work in two ways.
browser.dragAndDrop(docIdHeader.selector, pageCountHeader.selector);
Or
browser.moveToObject(docIdHeader.selector)
browser.buttonDown(0)
browser.moveToObject(pageCountHeader.selector)
browser.buttonUp(0)
I ran this in the REPL interface so I know it works as I could see each step being executed after I sent the commands. If you are not familiar with how to use the REPL I highly recommend learning. You can play around with commands in the console until you figure something out and then add those commands to your tests.
Also, as I stated in my comments above. dragAndDrop() and moveToObject() are going to be deprecated soon and you will likely see a lot of warnings about it when you use these. The correct way to implement a drag and drop action going forward is to use browser.actions(). Unfortunately, I don't have an example of how to do it that way as I haven't played with it yet. If no one provides an example by tonight I will try to get one together for you.
Even I faced this issue wherein the cursor doesn't move to the destination object after buttonDown and using moveToObject twice worked for me.
await this.driver.moveToObject(source);
await this.driver.buttonDown(0);
await this.driver.moveToObject(destination);
await this.driver.moveToObject(destination);
await this.driver.buttonUp(0);

blueimp file upload. How to clean existing filelist

I have goggled a lot, but have not found a solution for my issue. The author of the widget references to the last answer of FAQ, but the FAQ does not have the answer or I cannot find it. I suppose it was updated since that time. Other fellows who faced the same issue and asked the same question just gone and did not provide any solution.
Anyway, in my case I have a table with button Pictures:
When a user clicks one of pictures button, modal dialog is shown. The user now can manage pictures for the chosen row. He can upload, delete pictures and so on. When the user opens the dialog for second row in the table he should see pictures for the second row only. It tells me that I have to clean the list of uploaded files every time user hits Pictures button to see the dialog. He will receive list of pictures which corresponds to chosen row from the server. Unfortunately, when I retrieve the list for the chosen row, the received files are added to the existing list.
Could you tell me how I can clean the list or reset the widget without removing files on the server side?
UPDATE I have used the following piece of code as a temporary solution.
jQuery.ajax({
url: "<YOUR URL HERE>",
dataType: 'json',
context: $('#fileupload')[0]
}).done(function (result) {
jQuery("#fileupload").find(".files").empty(); //this line solves the issue
jQuery(this).fileupload('option', 'done').call(this, null, { result: result });
});
Thank you.
i was also trying for one hour to get my upload work ;)
here is, how i solved this problem:
$('#html5FileInput').fileupload({
....
add: function (e, data) {
$.each(data.files, function (index, file) {
var newFileDiv = $(newfileDiv(file.name));
$('#fsUploadProgressHtml5').append(newFileDiv);
newFileDiv.find('a').bind('click', function (event) {
event.preventDefault();
var uploadFilesBox = $("#fsUploadProgressHtml5");
var remDiv = $(document.getElementById("fileDiv_" + event.data.filename));
removeFileFromArray(event.data.filename);
remDiv.remove();
data.files.length = 0;
...
});
data.context = newFileDiv;
});
...
)};
as you can see i create inside the add-event my file-dataset with 'newfileDiv(file.name)'. this creates a div with all information about the file (name, size, ...) and an ankor that exists for deleting the file from the list. on this ankor i bind a click-event in which i have the delete implementation.
hope this helps!
I know this isn't the most elegant solution, but I needed a very quick and dirty...so here's what I did (using jQuery).
//manually trigger the cancel button for all files...removes anything that isn't uploaded yet
$('.fileupload-buttonbar .cancel').first().trigger('click');
//check the checkbox that selects all files
if(!$('.fileupload-buttonbar .toggle').first().checked) {
$('.fileupload-buttonbar .toggle').first().trigger('click');
}
//manually trigger the delete button for all files
$('.fileupload-buttonbar .delete').first().trigger('click');
I know this isn't the best way. I know it isn't elegant...but it works for me and removes everything from the plugin.
If you have added file names or anything else from the plugin to any local arrays or objects, you'll need to clean those up manually (I have several handlers that fire on fileuploadadded, fileuploadsent, fileuploadcomplete, fileuploadfailed, and 'fileuploaddestroyed` events).
protected function get_file_objects($iteration_method = 'get_file_object') {
$upload_dir = $this->get_upload_path();
if (!is_dir($upload_dir)) {
return array();
}
return array_values(array_filter(array_map(
array($this, $iteration_method)
//scandir($upload_dir)
//File listing closed by Doss
)));
}
there is a scandir function responsible for listing the files. just uncomment it like i have done above and your problem is solved. it can be found in the UploadHandler.php file.

For loop in coffeescript

I am working on rails3.2 and using coffeescript
In my coffeescript i have a for loop and for each , i am executing a API call to fetch results and appending the results to the respective dom
like
for ajaxLink in _ajaxRenderLinks
_template = $(ajaxLink).attr('data-link-template')
apiURL = $(ajaxLink).attr('data-link-url')
console.log($(ajaxLink))
Myapp.API.execute(apiURL, 'get', {}, (data) ->
console.log($(ajaxLink))
if data isnt "" or data isnt undefined
console.log($(ajaxLink))
$(ajaxLink).empty()
$(ajaxLink).append($(HandlebarsTemplates[Myapp.TemplateRoutes.path(_template)](data))))
In the above code, i have two links (one is a link and another is a ul link)
ajaxRenderLinks has these a and ul which has its template to render and the url to fetch the results.
The first console.log prints the first link a and then runs the API call for it and then runs the APi call for it
and then it prints the second link ul and runs the API CALl for it . And finally it tries to append the last result with the second link and not doing the appending for each link, since it ajaxLink inside if data isnt "" or data isnt undefined prints only the second link and not prints the first link and then second link
How to resolve this
Looks like a classic "variable closure in a loop" situation. Because the execute function is asynchronous, it references ajaxLink, which changes as the loop loops. So when execute's callback is invoked, ajaxLink might be something else than what it was when execute itself was invoked.
Try this
for ajaxLink in _ajaxRenderLinks
do (ajaxLink) -> # wrap in an immediately-invoked function
ajaxLink = $(ajaxLink) # save this rather than calling $(...) again and again
_template = ajaxLink.attr('data-link-template')
apiURL = ajaxLink.attr('data-link-url')
Myapp.API.execute(apiURL, 'get', {}, (data) ->
if data? and data isnt ""
ajaxLink.empty().append($(HandlebarsTemplates[Myapp.TemplateRoutes.path(_template)](data))))

JQuery Tab function not firing via JQuery templates

Hi I'm using JQuery tabs http://jqueryui.com/demos/tabs/ with search results being returned from my server with each row potentially having its own tabs depending on the search results. If the user clicks on the sorting options then the search results change including the tabs within each row returned which may or may not have tabs. In the example above you can see there are 2 records returned and the top record has tabs called Other Videos.
I have been successfully able to retrieve the resultset back from the server and the template is bulding correctly, however i cannot get the .tabs() function to fire? Does anyone have any experience with using tabs and know how I can get my tabs() function to fire?
Here is the code I use to dynamically load the template after the json result set is returned:
$(".searchBox").fadeOut("fast", function () {
$(this).html("").fadeIn("fast", function () {
$("#searchTemplate").tmpl(json.Data.SearchResults.Results).appendTo(".searchBox").fadeIn("fast");
});
});
And here is a for loop that I use to iterate over the results after the template has been loaded with the new html tabs created to try and get the .tabs() function to fire:
for(var i=0;i<json.Data.SearchResults.Results.length;i++){
if (json.Data.SearchResults.Results[i].OtherVideos.length || json.Data.SearchResults.Results[i].VideoFriends.FriendCount > 0)
{
$(document).find("div[id='tabs"+json.Data.SearchResults.Results[i].Counter+"']").tabs();
if ($(document).find("div[id='tabs"+json.Data.SearchResults.Results[i].Counter+"']").length > 0)
alert("it exists");
else
alert("it dont");
}
}
Suffice to say the alert box "it exists" appears successfully so it is finding the dynamically created html tab that the template generated however the tab itself is not being initialized by the statement:
$(document).find("div[id='tabs"+json.Data.SearchResults.Results[i].Counter+"']").tabs();
Does anybody know the reason why or what I'm missing here to get my .tabs() function to fire ...
I've examined the dynamic content and double checked the html code using firebug inspector and everything is according to how it should be the id's are correct, the #id's are there and so on, so my only conclusion is that the .tabs() function is not firing. Is this a limitation on the JQuery tabs itself? Can it not perform this type of "live" loading capability? Is there a callback function I should be using as part of loading the template itself?
Here is a picture of what is being returned after the call to the server without the tabs working:
Okay I fixed the problem, and thought I'd better give my answer for those of you who suffer a similar problem.
I should have placed my for loop inside of the same callback function as the tmpl call e.g:
$(".searchBox").fadeOut("fast", function () {
$(this).html("").fadeIn("fast", function () {
$("#searchTemplate").tmpl(json.Data.SearchResults.Results).appendTo(".searchBox").fadeIn("fast");
// For loop should go here!
});
});
I had the for loop after this block of code and the tabs() function essentially was not referencing the newly created tabs at all.