jQuery method .on() on dynamically(AJAX) loaded data - javascript

So i have a page in my site that has a with class name 'mainContent' that automatically updates with new data every like 1 minute using AJAX .ajax(). Content in this requires some JavaScript for some functionalities. The problem now is that JavaScript does not work on the new data loaded into the DOM without whole page refresh. I have searched and found using .on() to bind the data to the DOM should work, like so:
$(document).on('click', '.mainContent',function(){
expand();
});
where expand is a JS function.
However, it only works fully on the new data but not on the data that had been added in the previous AJAX call...

You're almost there, it's just your logic. This is how this jQuery function works:
You set a container. This is the element that will hold the AJAX-crated items that you want to bind. The more specific, the better. Otherwise, you'll wire an event for your whole page, which is bad
The event. What are you listening to?
Who will fire the handler. A selector to form the phrase: when these guys inside this big guy fire this event, run this code.
Let's suppose that your mainContent gets filled with hyperlinks (I'm not sure because your question lacks on details):
$('.mainContent').on('click', 'a', function () {
//do your magic
//$(this) is the clicked link
});
This way, our phrase is: when links inside .mainContent are clicked, run this.
UPDATE
Based on the comments, I think that your problem may be on the expand function.
Let's give a try:
$('.mainContent').on('click', 'a', function () {
$(this).simpleexpand();
});

Have you try to apply your binding on the callback of the ajax function that load your new datas ?
Something like that :
$.ajax({
url: url...//Classic ajax call
}).done(function ( data ) {
//Apply your 'on' here
});

Related

Detect ul list content change jQuery

We have an unordered list with id #some-list. In our Backbone implementation, when certain data is returned, list entries are rendered and appended to the list and the list is displayed.
We want to detect when such change is completed using JQuery. We used $(#some-list).ready() and $(#some-list).load(), but it looks like they are not working.
What are some ways to capture such change? Could anyone shed some lights here?
Well you didn't post any code so it's really hard to see guess where you fail.
But in general what i would do is trigger a custom event on the ajax callback (you do use ajax to get the content and appending it to the list right?).
for example:
loadData(){
// invoke the ajax request
var def = $.get(...);
def.then(function(result){
// $(#ul) append(result) ...
// now trigger the custom event
$(document).trigger('listRendred');
});
}
Now on a different place or script you can listen to it:
$(document).on('listRendred', function(e){ // do what ever... })
Since you are using BackboneJS you could try to listen to its events.
To find out which events you could use, try following code (replace my * placeholders first) and have a look inside your browser's console.
*backboneobject*.on("all", function(e) {
console.log(e)
});
Afterwards just listen for the event by using
*backboneobject*.on("*yourevent*", function() {
doStuff();
});

Changing onclick for a greasemonkey function before it is defined

I will describe my problem, hopefully someone can provide a solution.
I am adding a GreaseMonkey script to an existing page, the page loads with ajax an element with an onclick:
onclick="getProperty('http:/...')"
I searched for a way to override their getProperty, which was hard on itself because I can't know what object will have this onclick before it arrives via ajax.
I can't bind my own click and unbind the previous one because there's no trigger for such a function when the content is dynamic. I tried adding my click and preventing the previous from being called by that doesn't work.
The selector I'm using looks like this:
a[onclick^='getProperty']
What I discovered was a method someone wrote for this exact problem, called waitForKeyElements. I hope someone here is already familiar with it.
What it does is check if an element matching a selector was added by ajax to the page, and if so runs a function.
This method let me workaround binding my function to override theirs:
waitForKeyElements("a[onclick^='getProperty']", updateToNewGetProperty);
function updateToNewGetProperty(ajaxLinks){
ajaxLinks.each(function(){
var oldOnclick = $(this).attr("onclick");
var UrlStartPos = oldOnclick.indexOf('\'') + 1;
var UrlEndPos = oldOnclick.indexOf('\'',UrlStartPos);
var Url = oldOnclick.substring(UrlStartPos,UrlEndPos);
$(this).attr("onclick", ""); // unbind
$(this).click(function() { // bind mine
myGetProperty(Url);
return false;
});
});
}
This works, it unbinds the previous javascript onclick and sets the jquery click.
However then I discovered that another segment of their code grabs the URL value that is inside the onclick, so I can't use the jquery click bind as that leaves the onclick empty.
I had to revert back to:
$(this).attr("onclick",$(this).attr("onclick").replace('getProperty', 'myGetProperty'));
This returns function not defined when clicking the link, I believe because the original page loads the ajax content before the greasemonkey is fully loaded. Triggering the waitForKeyElements before my function is registered.
Any help / advice would be greatly appreciated

Call JavaScript function when button loaded by ajax is clicked

I have an html form that loads its contents through ajax and includes buttons that, when clicked, should execute a JavaScript function that is defined in the html page's script tag. SO: Button is loaded through ajax (works), but when button is clicked, it doesn't trigger the desired action and doesn't trigger a JavaScript error in Firebug. How does one get the onclick signal of a bunch of buttons loaded through ajax to bind to an already existing JavaScript function?
EDIT: I should have noted also that I am not using JQuery. I am willing to do so if it is the only way, but otherwise, I would prefer to use only native JavaScript.
EDIT2: My problem was a bit more involved, but as was stated in the chosen answer, you should be able to set the onclick event handler in the php script before sending the data through ajax. If you have a data-heavy response and want to reduce bandwidth, you might consider doing everything client-side, but I find it easier in most situations just to set the onclick attribute in the php script.
Your dynamically generated button could have an inline event bound to it. When generating the button, simply make sure it has an onclick="alreadyExistingFunc();" and the page will happily execute it.
Alternatively, when your AJAX data is finished writing itself into the document, find the new button(s) and bind the event to them:
function ajaxSuccess()
{
document.getElementById('newButtonIdHere').onClick = function() {
alreadyExistingFunc();
}
}
That should do the trick. Also note that if you ever "need" a small part of jQuery to do something (like selectors or event handling), you can almost always do it without loading the whole library.
Append/insert the HTML (retrieved AJAX response) to DOM and bind click event to it:
function alreadyExistingFunc() {
alert('button is clicked!');
}
var ajax_data ="<button id='my-button'>My Button</button>";
$('body').append(ajax_data).find('#my-button').on('click', function(e){
alreadyExistingFunc();
// some more code...
});
OR:
$('body').append(ajax_data).find('#my-button').on('click', alreadyExistingFunc);
You could also use a callback:
function getAjaxContent(callback) {
$.ajax({url: "url"}).done(function() {
callback(data);
});
}
getAjaxContent(function (data) {
//ajax content has been loaded, add the click event here
}

How to call a Javascript after a div is replaced?

I dynamically have to call a Javascript after a tag is rendered. Is it possible? I am doing some Ajax call which on return should repaint a DIV tag. And it is repainting successfully. I need to fire a Javascript method AFTER the DIV tag is repainted. How to do that?
Thanks
Short answer: directly it ain't possible (there is no "repaint" or "change" event on DIVs).
However using jQuery or other JS framework that supports custom events you could add an event listener on the div and fire an event in your AJAX call (i suppose it the onSuccess function; so as the last action inside fire custom event).
Even more simply you could just call the desired JavaScript method after you finish changing your DIV.
// I am doing some Ajax call
function ajax( url ) {
xmlHttp.onreadystatechange = function () {
// ...
};
// which on return should repaint a DIV tag.
div.modify();
// I need to fire a Javascript method AFTER the DIV tag is repainted.
javascriptMethod();
}
Or am I missing something here? :) Maybe you want to do the painting thing when the request is finished, but still i don't see any problem here.

Re-running JQuery's selectors and actions after a programmatic insertion of new content

Fellow JQuery hackers, hello :-)
Suppose you have the following code:
$('.links').click(function(){
//Do something
}
And I then insert dynamic content into a DIV's HTML content (Say, for example, after clicking a button, the new content gets inserted). This content has the "links" class. The problem is that the "click" button doesn't get registered with the newly inserted content.
How do I tell JQuery to re-select all the elements with a "links" class and apply the above function on them? Can this be automated?
Thanks.
You'll want to use event delegation:
$('.links').live("click",function(){
//Do something
});
That will prevent dynamically inserted elements with the class links from losing their click event handler. Note that you will also need jQuery 1.3 or later for that to work.
See Events/live.
Another way is to re-bind using the callback of whichever of jQuery's ajax methods you have opted to use, example:
$('#someDiv').load('page.html', function() {
$('.links').click(function(){
//Do something
});
});
or neater still:
function initLinks() {
$('.links').click(function(){
//Do something
}
}
$('#someDiv').load('page.html',initLinks);

Categories

Resources