fileupload Jquery doesn't work dynamically - javascript

I use this file-upload script: http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/
There is this in it:
$('#upload').fileupload({
My Problem is, that i load the content dynamically, so I think I need something like this (because I know this problem from the .click() function):
$(document).on('fileupload', '#upload', function () {
But this doesn't work. Can anyone help me, how to get this function called when the content with the form with id="upload" is loaded dynamically?
Would be great!

Your issue is probably because you're initializing $('#upload').fileupload() in document.ready().
You should initialize the element as file upload (execute $('#upload').fileupload()) after you dynamically load the content.
Since you're loading the content via ajax on button click (according to comments), you code should be along the following:
$(":button").click(function(){
$.ajax("url",{
success: function (data){
//code for injecting the element into DOM
$('#upload').fileupload(); // initialize it as file upload
}
});
});

You are almost right about the "I need something like this" part - the issue with your attempt at
$(document).on('fileupload', '#upload', function () {
is that 'fileupload' is not an event which is what .on() is expecting and that's why it worked for you with the 'click' case and not here.
You should include the assets/js/script.js to your page after the $('#upload') element is dynamically loaded so that all the content the script needs exists before it is executed. For that take a look at jQuery.getScript() or a simple dom approach and use it after the code which gets your elements added to the dom.

Use this function
$(function () {
var options = {
beforeSubmit: function (formData, jqForm, options) { }, // pre-submit callback
success: function (responseText, statusText, xhr, form) { } // post-submit callback
};
// bind form using 'ajaxForm'
$('#uploadForm').ajaxForm(options);
});

Related

javascript events not working with dynamic content added with json

I'm stuck with a situation where my DOM elements are generated dynamically based on $.getJSON and Javascript functions for this elements are not working. I'll post some general idea on my code because I'm looking just an direction of what should I do in this situation.
site.js contains general features like
$(document).ready(function() {
$('.element').on('click', function() {
$(this).toggleClass('active');
});
$(".slider").slider({
// some slider UI code...
});
});
After that:
$.getJSON('json/questions.json', function (data) {
// generating some DOM elements...
});
I have also tried to wrap all site.js content into function refresh_scripts() and call it after $.getJSON() but nothing seems to be working.
Firstly you need to use a delegated event handler to catch events on dynamically appended elements. Then you can call the .slider() method again within the success handler function to instantiate the plugin on the newly appended content. Try this:
$(document).ready(function(){
$('#parentElement').on('click', '.element', function() {
$(this).toggleClass('active');
});
var sliderOptions = { /* slider options here */ };
$(".slider").slider(sliderOptions);
$.getJSON('json/questions.json', function(data) {
// generating some DOM elements...
$('#parentElement .slider').slider(sliderOptions);
});
});
Instead of calling on directly on the element, call it on a parent that isn't dynamically added and then use the optional selector parameter to narrow it to the element.
$('.parent').on('click', '.element', () => {
// do something
});
The difference between this and:
$('.element').on('click', () => {});
is with $('.element').on(), you're only applying the listener to the elements that are currently in that set. If it's added after, it won't be there.
Applying it to $(.parent), that parent is always there, and will then filter it to all of it's children, regardless when they're added.
the easiest way is to add this after you add/generate your DOM
$('script[src="site.js"]').remove();
$('head').append('<script src="site.js"></script>');
of course your js function that generates DOM needs to be on another file than your site.js

jQuery trigger click not working from AJAX success

When I click submit on a form, it makes an AJAX call. If the return value is success I want to open a file upload browser to upload a file from the system. For this I am using the trigger click from jQuery on success message. But it is not working. Below is the code for the AJAX call.
$.ajax({
url: AppManager.defaults.contextPath,
data: colMap,
contentType: 'application/json',
type: 'POST',
success: function(data) {
if (data.result == 'Success') {
$('#continue-upload-input-box').trigger('click');
} else {
self.popupView.closePopup();
notify.popup('Error Uploading').error(self.uploadFailureMessage);
}
},
error: function(error) {
console.log(error);
}
});
This is where the code for file upload is written:
change: function($view) {
var self = this;
$('<form id="custom-upload" class="input-form-container" enctype="multipart/form-data"></form>').appendTo($view.find('.btn-wrap'));
$view.find('.input-form-container').after('<input name="excelFile" type="file" id="continue-upload-input-box" style="display:none;">');
$view.find('#continue-upload-input-box').off('change').on('change', function(event) {
if (event.target.files.length === 1) {
self.uploadCustomTemplate(new FormData($('#custom-upload')[0]));
self.popupView.closePopup();
}
});
}
What could be an issue in the above code?
you need to action a dom click event, not a jQuery click event.
try:-
$('#continue-upload-input-box').get(0).click();
use
$(document).trigger
insted of
$('#continue-upload-input-box').trigger('click');
if you use document then it will execute your trigger event . if your id is not in DOM when you trigger click it will not execute so you have to load DOM again
Use on method for calling event.refer following link:
http://api.jquery.com/on/
first make sure your 'data.result' value 'Success' is in correct format or which value it will return then use this
$("#continue-upload-input-box").trigger("click");
i think your code is proper but it's all depends on your other jquery code
.trigger is more or less like a click.
to trigger some action/event the element or object must be in DOM before your trigger the event.
So if you load the form from JS and then append it in DOM the your function that allow the uploader to show must be in .load function OR its better that you append it in DOM before the ajax fires.
http://api.jquery.com/trigger/
Use $('#continue-upload-input-box').click();. That should be sufficient.

JQuery event handler when select element is loaded

Is there an event handler to use in JQuery when a DOM select element has finished loading?
This is what I want to achieve. It is working with other events except 'load'.
This piece of code is loaded in the head.
$(document).on('load', 'select', function(){
var currentSelectVal = $(this).val();
alert(currentSelectVal);
} );
The question was badly formed earlier. I need to attach the event handler to all select elements, both present when the document is loaded and dynamically created later.
They are loaded from a JQuery Post to a php-page. Similar to this:
$.post("./user_functions.php",
{reason: "get_users", userID: uID})
.done(function(data) { $("#userSelector").html(data);
});
I think we're all confused. But a quick break down of your options.
After an update made to the Question, it looks like the answer you might seek is my last example. Please consider all other information as well though, as it might help you determine a better process for your "End Goal".
First, You have the DOM Load event as pointed out in another answer. This will trigger when the page is finished loading and should always be your first call in HEAD JavaScript. to learn more, please see this API Documentation.
Example
$(document).ready(function () {
alert($('select').val());
})
/* |OR| */
$(function() {
alert($('select').val());
})
Then you have Events you can attach to the Select Element, such as "change", "keyup", "keydown", etc... The usual event bindings are on "change" and "keyup" as these 2 are the most common end events taking action in which the user expects "change". To learn more please read about jQuery's .delegate() (out-dated ver 1.6 and below only), .on(), .change(), and .keyup().
Example
$(document).on('change keyup', 'select', function(e) {
var currentSelectVal = $(this).val();
alert(currentSelectVal);
})
Now delegating the change event to the document is not "necessary", however, it can really save headache down the road. Delegating allow future Elements (stuff not loaded on DOM Load event), that meet the Selector qualifications (exp. 'select', '#elementID', or '.element-class') to automatically have these event methods assigned to them.
However, if you know this is not going to be an issue, then you can use event names as jQuery Element Object Methods with a little shorter code.
Example
$('select').change(function(e) {
var currentSelectVal = $(this).val();
alert(currentSelectVal);
})
On a final note, there is also the "success" and "complete" events that take place during some Ajax call. All jQuery Ajax methods have these 2 events in one way or another. These events allow you to perform action after the Ajax call is complete.
For example, if you wanted to get the value of a select box AFTER and Ajax call was made.
Example
$.ajax({
url: 'http://www.mysite.com/ajax.php',
succuess: function(data) {
alert($("select#MyID").val());
}
})
/* |OR| */
$.post("example.php", function() { alert("success"); })
.done(function() { alert($("select#MyID").val()); })
/* |OR| */
$("#element").load("example.php", function(response, status, xhr) {
alert($("select#MyID").val());
});
More reading:
.ajax()
.get()
.load()
.post()
Something else to keep in mind, all jQuery Ajax methods (like .get, .post) are just shorthand versions of $.ajax({ /* options|callbacks */ })!
Why dont you just use:
$(document).ready(function () {
//Loaded...
});
Or am I missing something?
For your dynamic selects you can put the alert in the callback.
In your .post() callback function, try this:
.done(function(data) {
data = $(data);
alert(data.find("select").val());
});
Ok, correct me if I understand this wrong. So you want to do something with the selects when the document is loaded and also after you get some fresh data via an ajax call. Here is how you could accomplish this.
First do it when the document loads, so,
<script>
//This is the function that does what you want to do with the select lists
function alterSelects(){
//Your code here
}
$(function(){
$("select").each(function(){
alterSelects();
});
});
</script>
Now everytime you have an ajax request the ajaxSend and ajaxComplete functions are called. So, add this after the above:
$(document).ajaxSend(function () {
}).ajaxComplete(function () {
alterSelects();
});
The above code will fire as soon as the request is complete. But I think you probably want to do it after you do something with the results you get back from the ajax call. You'll have to do it in your $.post like this:
$.post("yourLink", "parameters to send", function(result){
// Do your stuff here
alterSelects();
});
Do you want all Selects to be checked when the User-Select is loaded, or just the User-Select?...
$.post("./user_functions.php", {reason: "get_users", userID: uID}).done(function(data) {
$("#userSelector").html(data);
//Then this:
var currentSelectVal = $("#userSelector").val();
alert(currentSelectVal);
});
If your select elements are dynamically loaded, why not add the event handler after you process the response?
e.g. for ajax
$.ajax({
...
success: function(response) {
//do stuff
//add the select elements from response to the DOM
//addMyEventHandlerForNewSelect();
//or
//select the new select elements from response
//add event handling on selected new elements
},
...
});
My solution is a little similar to the posters above but to use the observer (pubsub) pattern. You can google for various pub sub libraries out there or you could use jQuery's custom events. The idea is to subscribe to a topic / custom event and run the function that attach the event. Of course, it will be best to filter out those elements that have been initialize before. I havent test the following codes but hopefully you get the idea.
function attachEventsToSelect(html) {
if (!html) { // html is undefined, we loop through the entire DOM we have currently
$('select').doSomething();
} else {
$(html).find('select').doSomething(); // Only apply to the newly added HTML DOM
}
}
$(window).on('HTML.Inserted', attachEventsToSelect);
// On your ajax call
$.ajax({
success: function(htmlResponse) {
$(window).trigger('HTML.Inserted', htmlResponse);
}
});
// On your DOM ready event
$(function() {
$(window).trigger('HTML.Inserted'); // For the current set of HTML
});

jquery function not getting called inside of an ajax function

So im trying do disable links on some <li> ellements that have been loaded in from another page using an .load() function, but for some reason i'm not able to effect those list items.
var from_post = false;
$(document).ready(function() {
//so this is the function that loads in data from another page
$("#gallery").load('http://localhost/index.php/site/gallerys_avalible/ #gallerys_avalible'), function() {
console.log('hello');
// sense there are no other li elliments on the page i thought this
// would be okay. but this function never gets called, i've moved it
// all over i just recently attached it to the load function thinking
// that maybe if the load was not complete it would not run, but i
// have had no luck.
$('li').click(function (e) {
e.preventDefault();
console.log("I have been clicked!");
return false;
});
};
$('#addNew').click(function () {
console.log('i got called');
$('#new_form').fadeIn(1000);
});
$('form').submit(function() {
if(from_post) {
//submit form
return true;
} else {
//dont submit form.
return false;
}
});
any help would be greatly appreciated, oh and the other thing is that i can run this function through firebug, and it works 100% fine. so im stumped.
You are closing your call to .load() too early. You have:
$("#gallery").load('http://...'), function() {
That just calls load and then declares a function. But, that function is not bound to the success handler and it will never be executed. You need the ) to be on the other side of the function declaration so that the function is included as a parameter to your call to load:
$("#gallery").load('http://...', function() {
...
});
Fix that and your code works: http://jsfiddle.net/gilly3/WdqDY/
Try a future-proof event observer like live or delegate:
$('li').live('click', function(){})
or, this method is preferred if you know the parent:
$('#gallery').delegate('li','click',function(){})
The reason for needing this is your click events are being bound to elements that are on the page at the time of the binding. Any li's added later will not see that binding which is how live or delegate works. They bind to the parent and traverse the child nodes every (click in this case) event to see if the event applies to an existing child.
Use .live('click', ...) or .delegate() instead of .click(...).

How to elegantly disable/enable all jQuery UI buttons?

I currently have several action buttons in different pages, and each button performs some AJAX call when clicked. In another word, I have code like this all over the places:-
$("#searchButton")
.button()
.click(function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
});
After doing some testing, it seems like some AJAX calls take at least more than a few seconds to process before the callback function is being called.
My plan is to disable the button when the AJAX call is made and enable it back when the AJAX call is completed. This is to prevent user from clicking the button too many times when the request is being processed. One solution I found is to utilize the unbind() and bind() functions. After modifying my code, it looks like this now:-
var searchButtonClickHandler = function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
};
$("#searchButton")
.button()
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
$(this).button("enable").bind("click", searchButtonClickHandler);
})
.click(searchButtonClickHandler);
This code works fine. Basically, it removes the click handler when the AJAX call is made and addes the click handler back when the AJAX call is completed.
My question is... is it possible to generalize the button disabling/enabling so that I don't have to implement ajaxStart() and ajaxStop on all UI buttons?
Ideally, I would like to use my earlier code snippet to register only the click event handler on the button, and then enable/disable all buttons using the .ui-button selector, something like this...
$(".ui-button")
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
// not sure how to bind the handler here
$(this).button("enable").bind("click", ?? );
});
... but, this doesn't work and I run into trouble in binding the click handler here.
The more I think about it, it almost seems like I need to create a button builder function to do this, for example:-
var createButton = function(selectorName, clickHandler) {
$(selectorName)
.button()
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
$(this).button("enable").bind("click", clickHandler);
})
.click(clickHandler);
};
// create button like this
createButton("#searchButton", function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
});
... but this approach will only disable/enable the selected button, and I want to apply that to all UI buttons.
Do anyone has a better approach in disabling/enabling all the buttons in the page?
Thanks.
Different approach, according to this answer you should be able to get a reference to your previous event handler via .data("events");
Putting that together with your sample it should look like this:
$(".ui-button")
.ajaxStart(function() {
var events = $(this).data("events");
$(this).data("oldEvent", events.click[0]);
$(this).button("disable").unbind("click", events.click[0]);
})
.ajaxStop(function() {
var oldClick = $(this).data("oldEvent");
$(this).button("enable").bind("click", oldClick.handler);
});
Not sure if this will work completely yet, still messing around on jsfiddle.
Update
This should work, example on jsfiddle.
you can use $('input[type=button]').attr('disabled','disable'); to disable all buttons instead of binding and unbinding click event to the buttons... also you can use deferred jquery object, here is an example
Maybe you could attach your handler to the parent element of your buttons with delegate? That way there's only one handler function to bind/unbind.
Yahoo hosts a getElementByClass function, and you could assign a class such as "disableMe" to all your UI buttons. Then use getElementByClass('disableMe') to return an array of all the elements you want to disable.
The link: http://developer.yahoo.com/yui/dom/
You can use
$("button").each(function(){
//your code here
});

Categories

Resources