I upload to the page elements by ajax and some of them have children with class "evented". I need to add class to parent on child load. I tried this
$(document).on('load','.evented',function(){
$('.evented').parent().closest('td').addClass('td_class');
});
But as expected it doesn't work because td doesn't have "load" event. I can execute this code like a part of ajax response but in this case I will have duplicate event listeners and I still need same code for elements that exist when document is ready.
I assume you are using load() method to load the contents, In that case you have to make use of the success handler of the load method to do this.
$(el).load(url, function(){
$(this).find('.evented').closest('td').addClass('td_class');
})
If you are not using load() method, instead other ajax methods like $.ajax()/$.get() etc then after you add the contents to your page you will have to do this like
$.ajax(...).done(function(result){
$(el).html(result).find('.evented').closest('td').addClass('td_class');
})
Related
I need to execute:
$('.btn-toolbar').toolbar({
content: '#toolbar-options'
});
Elements with .btn-toolbar class are not in DOM because are added after and ajax request. How can I select elements outside DOM?.
In other similar question it's solved with Delegate Event, but I don´t have any event for managing it, I don´t need enable click on it, hover or any other event. I just want to execute toolbar function for all elements with btn-toolbar, but $('.btn-toolbar') is empty at this time.
You can execute the code on the ajax call success/complete after it places the elements of class .btn-toolbar in the DOM.
$.ajax({
....
}).done(function() {
// Places/Inserts the .btn-toolbar elements in the page.
$('.btn-toolbar').toolbar({
content: '#toolbar-options'
});
});
If the ajax call is made by some other script where you cannot(for example - by some other plugin's minified script, or that script is from other site) inject your code, still you can interfere on the ajax call and attach your code to be run after.
You can use jQuery.ajaxSetup() to customize the ajax calls made in your site.
For example you can run your code whenever an ajax call completes successfully by:
$( document ).ajaxSuccess(function() {
$('.btn-toolbar').toolbar({
content: '#toolbar-options'
});
});
If an element is not in any element subtree (i.e. not a child of any other element), and you aren't holding a reference to it (nor is any other object referencing it), it's effectively gone, and subject to garbage collection.
If you are holding a reference to it, you will need to use that reference. If it's a child of some other element (whether or not that element is in the DOM tree), you'll need to include that parent element in your selection, which means you will need at least a reference to that parent element. Otherwise you don't really have any other way of reaching it.
If the element doesn't actually exist yet, and you're just saying "invoke this command on any .btn-toolbar as it gets loaded into the page", then you need a mutation observer.
I know putting JavaScript in partials is a bad idea because the page will have to load up a new script every time a new partial is loaded. I am aware of and have read this question, but its answer did not work for me (putting the script into app/javascripts/application.js). I think it is because I am working with partials that are dynamically generated onto the page. I think the dynamically generated partial does not react to the script loaded up on the initial page.
For example, I have a "Rule" div with a select input that has a script to do something when the select input is changed. This works for every Rule div that is generated on page load. But then there is also a "+" or "ADD" button which will dynamically generate more Rule divs which do not respond to the script, unless that script is in the partial.
Is there a good way to keep the script out of the partial when the partial is dynamically generated?
JQuery sets listeners on page load (i.e. $(selector).on(etc.)), so it doesn't listen for events on dynamically added elements. There is a way around it, though. You need to use what is called a delegate.
$(document).ready( function() {
$('body').on('change', 'input.selector', function(e) {
// do something
});
});
I'm not sure what your event (here I put change) or selector for the select you are using (here I put input.selector), but if you replace those with the appropriate information, it should work even with dynamically added elements.
You can use JQuery to execute the code only after the document has loaded onto the DOM:
$( document ).ready(function() {
//Call your functions here
});
That way, your JS will have access to whatever is on the page, because you are ensuring that it is fully loaded.
If your divs are not in place on document ready, you can use event delegation, as suggested by ptd. Basically what this means is that you install a handler on a parent div (which will be present on document ready) which says, "hey, when you click on this dynamic div inside of me, call this function".
$('div#master').on('click', 'div.dynamic', function(event) {
console.log("action here")
var $dynamicDiv = $(event.currentTarget) //The current Target is the thing you clicked on, not the parent.
});
If you are adding elements to the DOM using AJAX calls, but want to keep your JavaScript in your assets folder only, here's a quick and clean way to accomplish this.
// /app/assets/javascript/foo.js
// On intial page load
$(document).ready(function() {
yourJavaScriptForPartials();
});
// After a subdomain field is loaded via AJAX
$(document).ajaxComplete(function() {
yourJavaScriptForPartials();
});
function yourJavaScriptForPartials() {
// Insert your javascript here.
};
Now, any JavaScript you put in the yourJavaScriptForPartials() function will be available both to the initially loaded DOM, and to any DOM elements added via AJAX. For reference, here is the JQuery page for the ajaxComplete event listener.
$.get('page.php', function(data){
$('#container').append(data);
});
$('.delete').click(function(){
alert();
});
I have a page use get to fetch & append more data into the page,
in my main page, i have a button script for class delete, this works for all button in main page, but not the new data append into, is any way to solve this problem?
This is an event delegation issue. The click handler is only set on elements present at the time the code is executed.
Try:
$('body').on('click', '.delete', function(){
alert();
});
body is here just a placeholder for any parent element of .delete. Try to attach the handler to a parent element with as less child elements as possible (in your example #container seems appropriate) to prevent performance issues.
I have a list whose li are generated dynamicaly via AJAX:
<ul>
<li id="hello"></li>
<li id="world"></li>
<li id="helloWorld"></li>
</ul>
I also have a global var in my script like this:
var world = 'world';
I want, on document ready, as soon as the list gets loaded, to find the li item with the same id as my global var:
$('ul').find('#' + world);
I can't use a conventional .on() event listener here since there is no other event to trigger it, except for the end of the loading itself.
So my next step was to trigger a custom event in my loading script:
$('ul').trigger('loadingDone');
And then listen for it:
$('ul').one('loadingDone', theFunctionThatDoesTheSearch );
Problem is, this failed and it completely ignored any of the generated elements.
I know that a possible solution would be to run these operations inside the success method of the ajax call, but the current architecture of the app I'm building doesn't allow for that. (I can and do trigger the event inside the success AJAX method, I just cant do the search there)
Basically what I am asking for are alternative solutions for allowing the loading script to let me know when it is done and ways to filter trough the generated content without doing the filtering inside the loading script itself.
$(document).on("customevent","ul",function(){
console.log("event triggered from inside the ajax success handler");
});
$.ajax({
url:'/echo/json/',
success:function(){
$('div').append("<ul><li>asd</li></ul>");
$("ul").trigger("customevent");
}
});
http://jsfiddle.net/xp7sr/2/
If your ajax request is performed through jquery, you could try http://api.jquery.com/ajaxComplete/.
Not sure if this is a bug or I am not suppose be doing this.
I have a page with sidebars that loads the main body dynamically.
For page1, I have a callback for an element #id1, which works on initial load.
After the user navigates to page2, the main content will get replaced by contents of page2, which also has an element with #id1, they serve the same purpose. events are initialized there as well.
The problem is that everything on page 2 would work except the event associated with #id1.
If navigating back to page 1, #id1 wouldn't work as well.
After looking at the console, I found that when calling $("#id1") sometimes give me the initial load element (not destroyed?), which is probably the reason.
The ajax load simply uses:
$.get(path, function(data) {$('#main').html(data)});
Any idea what's going on here?
If the old elements are not 'properly destroyed in jquery', what is suppose to be done here.
While it's not clear exactly what you're binding, the solution is to use (depending on your jQuery version) live() or on() to ensure that you bind to elements that aren't in the DOM at execution time.
jQuery 1.7+: on()
$(document).on('click', '.selector', function() { ... });
jQuery <1.7: live()
$('.selector').live('click', function() { ... });
Remember that an ID should only occur once
Because you don't know what elements with ID's may still be living in the DOM after the Ajax call you should stick with classname's instead.
With that you can use jQuery's .live() to bind to elements that have been dynamically loaded.
You have to generate dynamic id for that. When you click the right bar option the id will generated and place the id in the body element "id" tag.So you know that which id is generated for which page. Call a javascript function on "onclick" event and pass that id to this function then call the body element as $("#id"+that generated_id).something;
I think this will help.