Proper way to add dynamic HTML through .ajax() request - javascript

I have this example of the success part of a JSON Facebook Graph API request,
success: function(res){
console.log(res);
$(res.data).each(function(index, value){
var pic = 'https://graph.facebook.com/' + value.id + '/picture?width=200&height=200';
$('<img class="hover" src="'+pic+'" width="200" height="200">').load(function(){
$(this).appendTo("#results").fadeIn("fast");
$(this).wrap('');
})
});
},
That looks for the recieved data objects, puts the page-id picture inside an img tag, and when it's already loaded, it appends it to the #results div.
However I don't have control in img .hover elements. I tried with
$("img.hover").hover(function(){
$(this).fadeOut() //for example
});
and nothing happens. I suspect that's because any img did exist when the document was created. So, how could get those new elements?

You need to use event delegation, the .hover() method is a shortcut for registering mouseenter and mouseleave events so
$(document).on('mouseenter', 'img.hover', function () {
$(this).fadeIn() //for example
}).on('mouseleave', 'img.hover', function () {
$(this).fadeOut() //for example
});

Related

Jquery function doesn't work after Ajax call

I've got this function:
$(document).ready(function() {
$('.post_button, .btn_favorite').click(function() {
//Fade in the Popup
$('.login_modal_message').fadeIn(500);
// Add the mask to body
$('body').append('<div class="overlay"></div>');
$('.overlay').fadeIn(300);
return false;
});
My page loads content with favourite buttons, but after Ajax call and generated additional new content the function doesn't work when you click new content's buttons. What could be not right?
That is because you are using dynamic content.
You need to change your click call to a delegated method like on
$('.post_button, .btn_favorite').on('click', function() {
or
$("body").on( "click", ".post_button, .btn_favorite", function( event ) {
Instead of this:
$('.post_button, .btn_favorite').click(function() {
do this:
$(document).on('click','.post_button, .btn_favorite', function() {
on will work with present elements and future ones that match the selector.
Cheers
class-of-element is the applied class of element. which is selector here.
$(document).on("click", ".class-of-element", function (){
alert("Success");
});
If you know the container for .post_button, .btn_favorite then use
$('#container_id').on('click', '.post_button, .btn_favorite', function () { });
so if '.post_button, .btn_favorite' are not found then it will bubble up to container_id
else if you don't know the container then delegate it to document
$(document).on('click', '.post_button, .btn_favorite', function () { });
Reference
I am not sure if I am getting your question right but you may want to try..
$.ajax({
url: "test.html"
}).done(function() {
$('.post_button, .btn_favorite').click(function() {
//Fade in the Popup
$('.login_modal_message').fadeIn(500);
// Add the mask to body
$('body').append('<div class="overlay"></div>');
$('.overlay').fadeIn(300);
return false;
});
Just try to paste your code inside done function.
Hope it helps :)
EDIT:
I also notice you are missing }); on your question.
The following worked for me
$(document).ready(function(){
$(document).bind('contextmenu', function(e) {
if( e.button == 2 && jQuery(e.target).is('img')) {
alert('These photos are copyrighted by the owner. \nAll rights reserved. \nUnauthorized use prohibited.');
return false;
}
});
});
You need to bind the jQuery click event once your ajax content is replaced old content
in AJAX success block you need to add code like here new response html content one a tag like
Click Me
So you can bind the new click event after change the content with following code
$("#new-tag").click(function(){
alert("hi");
return false;
});

Manipulate json data with jQuery

I am looking to load json data as html as show in this fiddle and below.
(function () {
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON(flickerAPI, {
tags: "mount rainier",
tagmode: "any",
format: "json"
})
.done(function (data) {
$.each(data.items, function (i, item) {
$("<img>").attr("src", item.media.m).appendTo("#images");
if (i === 3) {
return false;
}
});
});
})();
jQuery("#images img").on("click", function (event) {
console.log('aaa');
});
I can get the json to load however I can't then get events such as on click to work with data that has been loaded with json, what am I doing wrong here?
You need to delegate your click events. They're being bound to items in the DOM, and then you're adding new items, and the events are not bound to them.
Try replacing your click binder with this:
jQuery(document).on("click", "#images img", function (event) {
console.log('aaa');
});
You'll want to replace document with the lowest-level consistent wrapper to avoid redundant traversal on click.
try this instead:
$("#images").on("click", "img", function (event) {
console.log('aaa');
});
the element with the id images exists when your event binding is attached, but the image elements do not. So using the on method, you can pass the img elements as a second parameter so that all img elements that are added after the page load are properly bound to this event handler.

Jquery simple ajax - Insert html

When a div is opnened i want to load html content into it via ajax. This is the code im working with:
http://jsfiddle.net/uhEgG/2/
$(document).ready(function () {
$('#country').click(function () {
$("#country_slide").slideToggle();
});
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
});
The code I think I need is this:
$.ajaxSetup ({
cache: false
});
var ajax_load = "Loading...";
var loadUrl = "www.test.com/site.html";
$("#load_basic").click(function(){
$("#country_slide").html(ajax_load).load(loadUrl);
})
How can I make it work to make it load up when the div is opened by the code above, firstly because it is setup for a click function not a toggle function, and second, because the toggle doesn't seem to be able to distinguish if the div is open or not.
to make it load up when the div is opened by the code above
$("#country_slide").slideToggle(function(){
if($(this).is(':visible')){
$("#country_slide").html(ajax_load).load(loadUrl);
}
});
Try to delegate the events.. Looks like the element is not yet available in the DOm when the event is bound
Replace
$('#country').click(function () {
with
$(staticContainer).on('click', '#country', function () {
staticContainer is the element which is already in your DOM when the event is bound and the ancestor of country
Either store the slide state in a variable or in a data attribute liek this:
<div id="country_slide" data-state="1">
And make something like this:
$('#country').click(function () {
$("#country_slide").slideToggle();
if ($("#country_slide").attr("data-state") == 0)
$("#country_slide").html(ajax_load).load(loadUrl);
});

How to check if a certain html fragment is already loaded?

Have the following code:
$("#blogs").mouseover(
function () {
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
$("#content").hide().load("blogs.html", function(){
$("#content").show("slide");
});
});
Works all fine, but now I would like the load() / show() function only be called if #content does not already contain blogs.html.
In other words: I would like to check if blogs.html is already loaded and if yes, simply do nothing and only if not there yet I would load and show it.
Have tried some things with hasClass() and some if-formulas but struggle to get this check.
Tried stuff like this:
$("#content section").hasClass("check_blog").hide().load("blogs.html", function(){
$("#content").show("slide");
Basically I just need to know how I can check if blogs.html is already the contents of #content.
Thanks a lot for any help. Regards, Andi
Add an ID to some element in blogs.html, say blogsloaded, then you can check for it with:
if (!$("#blogsloaded").length)
$("#content").hide().load("blogs.html" ...
Another method would be to store in a variable if you already loaded it:
if (!this.blogsloaded)
{
this.blogsloaded=true;
$("#content").hide().load("blogs.html" ...
}
I would split up your mouseover events into two namespaced events. One which will only run once.
// This event will only run once
$("#blogs").on("mouseover.runonce", function () {
$("#content").load("blogs.html");
});
// because this event will unbind the previous one
$("#blogs").on("mouseover.alwaysrun", function () {
$(this).off("mouseover.runonce");
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
$("#content").hide();
});​
Update a data attribute on #content that contains the url or id of the currently loaded content. Also, you should handle the case where the user hovers over a different section before the previous is done loading.
var request; // use this same var for all, don't re-declare it
$("#blogs").mouseover(function () {
// exit event if the blog is the current content in #content
if ( $("#content").data("current") == "blog") return;
$("#content").data("current","blog");
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
// if a previous request is still pending, abort it
if ($.isFunction(request.abort) && request.state() == "pending") request.abort();
// request content
request = $.get("blogs.html");
$("#content").hide();
// when content is done loading, update #content element
request.done(function(result){
$("#content").html(result);
});
});
I strongly suggest against using hover for loading content with ajax.
Also, in it's current form, this code is not very re-usable, you'll have to have one for each link. I suggest instead using classes and having only one event binding handling all of the links.
You can do it like this using .has() to detect descendants of content
$("#blogs").mouseover(
function () {
$(this).addClass("hover");
$("#home,#homepages,#apps,#facebook,#kontakt").removeClass("hover");
var $c = $("#content");
if($c.has('.check_blog')){ // if content contains an element with that class
$("#content").hide().load("blogs.html", function(){
$("#content").show("slide");
}
});
});
You could do something like this:
$("#blogs").mouseover(
function () {
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
if($('#content').html() == '') {
$("#content").hide().load("blogs.html", function(){
$("#content").show("slide");
});
}
});

Jquery doesnot bind events to ajax added dom

I have an ajax function that loads the content of 4 checkboxes as follows:
$.ajax({
url : some url..,
dataType : 'json',
success : function(data) {
buildCheckboxes(data);
},
error : function(data) {
do something...
}
});
build checkboxes methods does something like this:
function updateNotificationMethods(items) {
var html = [];
$.each(items, function(i, item) {
htmlBuilder = [];
htmlBuilder.push("<input type='checkbox' class='checkbox-class' name='somename' value='");
htmlBuilder.push(item.id);
htmlBuilder.push("'");
htmlBuilder.push("/> ");
htmlBuilder.push(item.name);
htmlBuilder.push("<br/><br/>")
html.push(htmlBuilder.join(''));
});
$("#div").html(html.join(''));
}
i have also an event binder that should be triggered when checkbox value changes:
$(".checkbox-class").change(function() {
alert("change");
});
it works if i have the checkboxes html in the source (i.e. static) as opposed to the set up i have here, where i dynamically load the data from server.
is there something i can do so that binding take place timely?
peace!
This is because the element is not present when you bind your handler.
Try this:
$( document ).on( 'change', '.checkbox-class', function() {
alert("change");
});
Or if you are using an older version of jQuery (less than 1.7) ...
$( '.checkbox-class' ).live( function() {
alert("change");
});
Checkboxes are not available while you are binding the events. jsfiddle
Assuming that element with id div is present while binding the event.
$("#div").on("change",".checkbox-class",function() {
alert("change");
});
This code:
$(".checkbox-class").change(function() {
alert("change");
});
do not establishes a continuous and on-going rule, instead, this code attaches an event manager (in this case to the change event) to each matching DOM object that exists at the moment it is executed.
If you want you can re-execute this code (or one similar and narrow) each time you add checkboxes to the DOM.

Categories

Resources