FineUploader complete callback event fires multiple times - javascript

I'm using Fine Uploader as a jQuery plugin in UI mode and I have a drop down list of file types such as image, video, pdf, etc. I'm dynamically changing the allowedExtensions and acceptFiles when the drop down list changes by removing the Fine Uploader generated div and then recreating it like this:
$('.qq-uploader').remove();
$('#jquery-wrapped-fine-uploader').fineUploader({/* options go here... */});
The dynamic validation works great this way, but I am doing some custom things in the complete callback event such as displaying thumbnails. When the file is uploaded, it fires the complete event for every time the dropdown list had changed prior to the first upload.
My workaround for now is storing the uploaded file name in an array and skipping over the custom complete logic if it already exists in the array.
I don't understand why the complete callback event is firing multiple times since I'm only uploading one file. Is there an explanation for this and/or a way to prevent duplicate callbacks from firing?

There are a couple ways to achieve your goal here:
Remove the Fine Uploader container element from the DOM before re-initializing Fine Uploader. In your fiddle, you were removing an internal element used by Fine Uploader. This will never work. You need to destroy the instance, and the only way to do this when using the jQuery plug-in is to destroy the DOM element that houses the plug-in instance. After you remove the container element, you can then re-add it and re-init Fine Uploader.
Make use of the multiple upload buttons feature. Essentially, you would create an alternate upload button for each file type with appropriate validation settings and change the one that is displayed when the user changes the value of the <select>.

I'm adding one more line to Ray Nicholus's answer.
$('#jquery-wrapped-fine-uploader').off()
You also have an option to remove event handlers that were attached to $('#jquery-wrapped-fine-uploader')

Related

Executing external JS using innerHTML and appendChild

I've been playing around with the Material Design Lite library that Google just launched a few days ago, but have some questions, specifically on how to initiate (or execute?) external JS when the HTML changes using innerHTML and appendChild.
See the first example here. As you can see, the HTML for the menu is already within the HTML file when it is first loaded so the menu works fine.
But in this example, the HTML of the document is modified using JS. However, the menu does not work anymore because the script is not executing, I think.
How can I resolve this issue? What's a better way to achieve this result? I'm a newbie when it comes to JavaScript.
You will need to attach the proper event listener from the library. With this change (adding componentHandler.upgradeAllRegistered(); after appending the item) it should work:
document.body.appendChild(menu);
componentHandler.upgradeAllRegistered();
When the menu button is inserted dynamically (when the user clicks), it doesn't get assigned the event listeners to show the menu. I'm guessing that the material design library parses the HTML when it (the library) gets loaded (since you're loading it at the bottom of your HTML document). Since it's already loaded by the time the user clicks, it doesn't check the new element that has been inserted and can't assign it the event listeners.
If this is the case, you'll need to find a way to get the library to recognize your new button.

Populate HTML dropdown onclick

I have a page which contains multiple HTML select dropdowns, and requires population onclick of the element. This population is done using an AJAX call in the click event listener of the select elements.
The reason for this is that performance and load are very crucial, and therefore they cannot be populated on page load.
Also, the design must use the native HTML select element.
I have created a jsFiddle demo to show the issue. When you click on the select the items are populated, and the width of the select increases as a result.
However the select only displays the initial option (prior to AJAX population).
------ View Demo ------
Demo uses setTimeout() of 50 milliseconds to emulate an AJAX response time.
How can I get this to populate onclick, and display correctly?
Is there a way of opening the select on callback of the popualation response?
EDIT: Alternatively, is there a jQuery plugin dropdown, which uses the browser's native theme for styling?
What I've tried so far
Populating the select on hover, however a quick user can open the select before the options have loaded. Also, if a user was to scroll all the way down the page, and over every select, this would cause a lot of unnecessary AJAX calls.
Changing the event listener to focus instead of click (as #AndyPerlitch suggested). However, this wouldn't work if the AJAX request took only 50 milliseconds to respond. (See Demo)
Changing the event listener to mousedown has the same effect as focus
UPDATE: This is not an issue in FireFox. select opens, then loads new items and displays them, all while in an open state.
Change the event to listen for from click to focus
Personally I would opt for a different approach completely, but it depends on you needs. Here I am assuming that the drop down will "almost definitely" be clicked (and thus loaded) at some point by the user.
With that in mind I would be tempted to populate the select lists using ajax as soon as the page is loaded. This has the benefit of being able to load the page quick (as there is still no "page load" list collecting) but it also means the ajax will most likely be complete before the user works out that they need to use the select list. I would even go an extra step and have temporary loading icons in place of the selected while the ajax is working it's magic (or disable them!) in case the ajax is having a slow day and the user is fast like superman.
of course, this all depends on how "set in stone" your requirement is to do the ajax load upon user interaction with the drop down element
or maybe this might prove some use?
The select will always display as it was before the click event started. You will therefore see only the initial option because you do the AJAX population after the click event started.
This may be a compromise for you but try to AJAX-populate before the click event. This may be:
-on hover, as you have done already (user has to scroll for the click anyway)
-an extra click for your users on an element neighbouring the select
Hide the drop down list and have something else in its place for the user to click on to trigger loading the drop down and displaying it.

Valum's Ajax file uploader - bind to all elements of a given class

I'm trying to use Valum's file upload script ( http://valums.com/ajax-upload/ ) to allow the creation of links that allow file uploads.
I'm using the jQuery library.
It's simple to get one link on a page to work using the standard documentation, but now I want to be able to catch all links of a given class rather than statically assigning to a given element.
Futhermore my site uses Ajax pageloads so I need to be able to somehow assign the uploader to new Ajax loaded content.
The envisaged use is to allow creating a link like this in an Ajax loaded page and have it trigger the uploader:
Upload a file
My first thought is to use the jQuery live() method to try bind the class, but I can't find a suitable event to trigger on.
Has anybody had experience with this sort of issue?
No, it's not so easy with <input type="file">, unfortunately. Because of some security issues, IE (even IE9!) just doesn't let you sumbit the form with this element "fiddled" - when 'click', 'change' or any other event is raised on it artificially.
So this plugin works different. Instead of creating an event handler that 'reroutes' user clicks to some fileinput element created on the fly, the wrapper structure is created around the link given as its target - and fileinput is inserted right there, being hidden enough for a user to not see it - but enough for a browser to register clicks on it (check this method in the source code and this article for details).
The bottom line is, you can't use event handling delegation here: the only sensible way is wrapping the newly-created elements with that plugin as well.

How can I call a jQuery function when an image changes?

I have a page with images and text.
A user can upload an image through a modal window. I use .js.erb to replace the image on the page with the one the user uploaded.
$('#mailing_body').contents().find("[data-edit-img='<%=escape_javascript(#user_image.location)%>']").attr('src', '<%=escape_javascript(#user_image.image.url(:medium))%>');
Now I want to a jquery function to fire when the image on the page changes.
I tried the following in my js file:
$("#mailing_body").contents().find("[data-edit-img='header']").live('change',function(){
alert('change');
});
But it does not work. What am I doing wrong?
I am using Ruby 1.9, Rails 3.2.2 jquery1.7.2
jQueries Change only works on INPUT elements, unfortunately.
What you will have to to is create an event handler and fire a trigger.
When ever the upload is finished or whenever you expect the image to change you can use jQueries event and trigger system
$('#foo').bind('customEvent', function() {
alert($(this).text());
});
$('#foo').trigger('customEvent');
Change is a an event that get trigger on input element only when their value as change. It doesn't get triggered if an attribute get changed. What you want is something that watch for attribute changes. Here is a link that explains how to achieve such things, basically it's just using a timeout to check periodically that the attribute has changed.
http://darcyclarke.me/development/detect-attribute-changes-with-jquery/
In IE you can use propertychange which will get triggered on those changes but that's IE only.

Problems getting .selectedIndex to work with select boxes in JQuery Mobile framework

I have a series of select dropboxes setup, with content that dynamically updates depending upon the preceeding selection. It works fine selecting in series.
When I try to go back to the top and start again, even though I have attempted to reset all children using
my_select.selectedIndex = 0;
The child select boxes remain unchanged. I had thought it was a Javascript error, but found the JSFiddle example actually worked, but my code within JQuery mobile does not work - leading me to believe it is a JQuery Mobile related issue
You can see a JSFiddle example at http://jsfiddle.net/vinomarky/xfcdF/
Steps to replicate:
Select 'Casing' from Type
Select 5 from OD
Change Type to Tubing
The JSFiddle example behaves as it should - resetting children to "-", while my 'live' JQuery Mobile example does not
Any ideas as to why?
You're manipulating the DOM behind jQuery Mobile's back but never telling jQuery Mobile that anything has changed.
You need to call the refresh method after you change the underlying <select>:
refresh update the custom select
This is used to update the custom select to reflect the native select element's value.If the number of options in the select are different than the number of items in the custom menu, it'll rebuild the custom menu.
So you need to add things like this:
$('#od').selectmenu('refresh');
at the bottom of your change handlers. The element to refresh does, of course, depend on which change handler you're in.
Demo: http://jsfiddle.net/ambiguous/n3VXe/
Your fiddle worked fine because it didn't use jQuery Mobile at all.
Also, you shouldn't be using onchange attributes in 2012, you're loading jQuery so you should use it to bind handlers to the events you're interested in. You might want to replace all your direct DOM manipulation with jQuery as well.

Categories

Resources