Most of my html is data that is provided via a Jquery request. It is written to the page by inserting it into a "main" div like such:
$("#main").html(passedData);
}
The page works great, but now i'm having problems trying to add any javascript to that data that is written to the div.
Namely I have tables that are inserted into the div and I am trying to write scripts that hide certain cells when others are clicked. I've used http://jsfiddle.net/ to make sure that all of my JS is correct, but for some reason it seems like the JS functions don't see that data in the div and won't manipulate it.
Is there anything I'm missing? When writing data to a page like this do you have to do certain things to reference that data with javascript?
You have to attach event handlers to those "future" elements like this:
$("#main").on("click", ".myelement", function(){
// Do something
});
Read more here. Also, it would be a lot easier if you posted your actual code.
It's hard to troubleshoot without the actual code, but I'm almost certain the problem is that when your jQuery code is executed, the elements that were pulled in through AJAX didn't exist. Therefor, no events will be attached to them.
You should look into using jQuery's .on() event handler. Attach it to a parent element that exists when DOM-ready is fired, and you can manipulate any elements inside it that were pulled in dynamically.
Related
I'm working with a large template of charts and other widgets. I also manually implemented some ajax tabs. Now whenever those tabs load new content (charts), the problem is that all the template scripts in the head tag won't work with those ajax-loaded elements anymore.
I know, normally you would use .live for this kind of problem, but this would mean to go into the whole 50k lines-js template and change everything to .live calls... Not really able to do that.
Is there instead a jquery way of reloading/reactivating all the scripts within the head-tag?
First off .live() has long since been deprecated and even removed from the latest versions of jQuery. You should never be thinking of using .live().
Second, as it sounds like you already know, the "right" way to fix this is to change your code to use the delegated form of .on() which is what replaced .live(). Yes, change all the code that does it the wrong way. Here's a post on using the delegated form of .on() instead of .live().
Third, a work-around would be to put all your initialization code that hooks up these event handlers into a single function (or called by a single function). Then, you call that single function upon initialization and then you can call that single function any time later after you reload your content. The trick is that you can only put code into that initialization function that can be called or should be called more than once after you content has been reloaded. If you put some event handlers in there that should not be in there, then you may get duplicate event handlers installed. So, only event handler initialization that applies to the replaced content should go in this function.
Suppose that function was called initDynamicContent, then it could look like this:
// init event handlers on the original version of the dynamic content
$(document).ready(initDynamicContent);
Then, sometime later after you replace the dynamic content, you can just do:
// code here that replaces the dynamic content with new content
initDynamicContent();
There is no magic jQuery way for this to happen automatically. jQuery has absolutely no way of knowing which code should be run again and which code should not.
I have a form on my page that submits the form via AJAX and then there is a script that processes some MySQL data and returns the data formatted as a <table> and displays it. I wanted to added sorting capabilities to this table, and found this simple but yet usefull plugin.
The issue is that it is not working for me. I tried adding the code in the .ready() portion of my JavaScript file, as well as outside of it. But there is still no effect. Is the onClick function is set when the page loads? and because the page is not refreshed when the table is shown - the onClick is not bound to it?
In that case, how can I bind jQuery to the returned table?
It is recommended to use the .on() method of JQuery.
Something like:
$('.selector_for_table').on('click', '.selector_of_header', function(e){ //logic })
Recommended reading: Jquery documentation .on()
you can use live method instead of using bind it will bind dynamically if control is recreated.
$("#tableId").live('event','method');
Ajax sets up a scenario and jQuery then plays it out. The element does not exist before the page is loaded. I need a way to Animate something that was dynamically added to the page.
Something like:
$(document).on("animate", "div", function (){});
Does anything like this exist?
Okay, there seems to be some confusion, I am using queue() this isn't the issue creating it or doing something after I have the ajax return. After the Ajax the program builds and inserts imgs with specific IDs into the page. I need to reload the dom or something so that I can then animate the objects that were inserted into the page.
I have tested the animated on JSfiddle and they work fine, so my only assumption is that because these objects are not part of the initial dom they will not animate and thus I need the DOM to reload.
All you have to do is animate it with the proper function, like:
$("#nonexistent-element").animate({
right: '10%'
});
and it will animate once #nonexistent-element exists, regardless of whether it existed at page load. You only need to use on() when you want to bind an event to an element that does not exist on page load.
Working jsfiddle: http://jsfiddle.net/emFpw/26/
When the content is loaded via Ajax, we need to bind the events for them to work or we can use the live/on methods of jQuery which will bind the events to either parent/document depending on what we want.
Either of the two techniques ie binding when the content is loaded or using live/on should result in the event being triggered.
For ex: Once the content in inserted we can do as suggested by Lrdwhyt in the above answer.
Or we bind the element before its loaded like
$("#non-existing-elem").live("click",function(){
$(this).animate({right:'10'});
})
I am having a page that loads content dynamically. Depending on which menu item the user clicks, different tables are dynamically loaded and presented using jquery.
One column of each table is having an update linke used to update the content that specific row is representing. When clicking that link a JQuery UI Modal Dialog is presented with a form loaded from a server in which the user should update the content and post back.
This is how I understand it, please correct me if I am wrong. I need to load the jquery script at the same time as I load the dynamic content in order to bind the events between the javascript functions and the elements that is being loaded.
Assuming my assumption is correct I do load the content and the same JQuery UI Dialog scripts each time the user selects a different table. I load the content and jquery files from different javascript functions loaded together with the main index file.
The consequence is unpredictable behaviour (probably predictable using the same use case). When loading the table more than once and updating something so the modal dialog is presented, the dialog is not presented anymore after the first or second usage, as one example.
Could it be a problem that the jquery script is loaded more than once? If it is, what's the principle or patterna I should use for this kind of application. If all above is false assumption, still, what's the principle or patterns for designing this kind of solution where different kind of dynamic content is loaded at several places (all presented within the same index file) and all need the same jquery files.
Take a look a jQuery $.live() and $.delegate():
http://api.jquery.com/live/
http://api.jquery.com/delegate/
These will allow you to bind events to dynamically loaded content.
If I understand you correctly, you are asking how to bind events on dynamically generated content. You do not, in fact, have to load new script at the same time as new content in order to be able to hook events to said content.
What you want is the jQuery 'live' handler. You can specify the target of the binding using standard jQuery selectors. However, instead of the following syntax:
$('.foo').click(function(){ });
You would use
$('.foo').live('click', (function(){ });
The way this works is through event bubbling, where an event invoked on a child element (such as an input box) 'bubbles' up through all parent nodes. In this case, jQuery just watches the whole document for event bubbles, and then matches it against your specific selector conditions.
If I understand you correctly:
1) Multiple tables with an update link on each rows to update their content.
2) Update button opens a modal box with a form.
3) Form is posted and data is retrieved after being processed by the server to feed the concerned table row.
If the flow described above is correct, I don't see why you should load jQuery or jQuery ui more than once.
You should do something like
1) Load the page with all the scripts required.
2) Set up and ajax call with the jquery .ajax() method (doc)
3) Use the ajax call to submit the form data to the server and retrieve the results
4) Use the success callback of .ajax() to feed the row with the updated data. Within the success method you should be able to retrieve the context (a.k.a. the link you clicked) and identify the actual row you clicked.
I hope I make sense.
If by any chance you need to create new rows then you should consider checking the .live() and .delegate() method of jQuery.
Good luck.
I'm using JQuery to set the HTML inside a div. Something like this:
$(div).html(strHtmlBlob);
strHtmlBlob is a chunk of HTML returned via Ajax from the server. After, it's assigned, I set up some events for elements in the new HTML blob by doing this:
$(div).find("a").click(a_ClickHandler);
That all works perfectly fine. The problem is REMOVING the events. I want to make sure I clean up the DOM properly.
I'm removing the HTML like so:
$(div).html("");
But I can see that the events are still there. Is there a way to clean up events for elements that no longer exist?
Use .remove() instead of .html("")
That will clear the elements and events all at once. JQuery does a lot of cleanup magic under the covers if you let it.
$(div).find('a').unbind('click');
Check out the documentation.
Alternatively, you should empty() it:
$(div).empty();
According to the docs:
Note that this function starting with 1.2.2 will also remove all event handlers and internally cached data.