jQuery - click on a link dynamically generated by AJAX - javascript

I read many different posts about this matter but I can't solve my problem.
I am trying to create a simple lightbox on dynamically generated content.
$(document).ready(function() {
$("body").on("click", "button", function() {
$("button").removeClass("selected");
$(this).addClass("selected");
var flickrAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
var animal = $(this).text();
var flickrOptions = {
tags : animal,
format: "json"
};
var displayPhotos = function(data) {
var photoHTML = "<ul>";
$.each(data.items, function(i, photo) {
photoHTML += '<li class="grid-25 tablet-grid-50">';
photoHTML += '<a href="' + photo.link + '" class="image">';
photoHTML += '<img src="' + photo.media.m + '" ></a></li>';
});
photoHTML += '</ul>';
$('#photos').html(photoHTML);
}
$.getJSON(flickrAPI, flickrOptions, displayPhotos);
var $overlay = $('<div id="overlay"></div>');
var $image = $("<img>");
var $caption = $("<p></p>");
//An image to overlay
$overlay.append($image);
//A caption to overlay
$overlay.append($caption);
//Add overlay
$("body").append($overlay);
//Capture the click event on a link to an image
$("#photos a").click(function(event){
event.preventDefault();
var imageLocation = $(this).attr("href");
//Update overlay with the image linked in the link
$image.attr("src", imageLocation);
//Show the overlay.
$overlay.show();
//Get child's alt attribute and set caption
var captionText = $(this).children("img").attr("alt");
$caption.text(captionText);
});
//When overlay is clicked
$overlay.click(function(){
//Hide the overlay
$overlay.hide();
});
});
});
Here is my complete code on jsfiddle
The click event after the AJAX call doesn't fire up.
How can I solve this?

what it's happening its that you are adding the event before the DOM exists, what you should do its wait for the response to actually render all the event and the interface or replace this:
$("#photos a").click(function(event){
});
for
$(document).on("click","#photos a",function(){
});
that way the event its gonna exist always... Its my guess... I'm not sure if $("#photos a") actually get the element you want to attach the event, but you got the idea of how you can add event to DOM elements that still dont exist on the DOM.

Related

second js function doesn't work

if user click <li><a id="print" href="">출력 하기</a></li>
it's id ="print" so it makes id="print2" button, title is 복사하기. and makes checkbox.
and then if user click id="print2" button "복사하기"
it doesn't work. there is no reaction.
what do i miss?
$(document).ready(function(){
$("#print").unbind('click');
$("#print").on('click', function(ev){
$('#main').prepend('<center><button class="btn btn-primary btn-lg" id="print2">복사하기</button></center>')
$('.post').prepend('<input type="checkbox" />');
ev.preventDefault();
});
$("#print2").on('click', function(){
var images ='';
$('li').each(function(){
var thisCheckFlag=$(this).children('input[type="checkbox"]').is(':checked');
if(thisCheckFlag){
images+='<img src ="'+$(this).find('img').attr('src')+'">';
}
});
if(images){
var myWindow=window.open('','printWindow','width=800,height=800');
myWindow.document.write(
'<html><head><title>Print</title></head><body>'
+images+'</body></html>'
);
myWindow.focus();
myWindow.print();
}
else alert('먼저 선택하세요.');
});
});
Your #print2 is not defined when you are attaching the click to it.
You need to delegate the click to a parent, typically the document.. See more
So your function will become:
$(document).on('click', '#print2', function(){
//rest of code.
});
The problem here is that the event will not bind with the dynamically created elements, So whatever you add a new button you need to add the event associated to it so :
$(document).ready(function() {
$("#print").unbind('click');
$("#print").on('click', function(ev) {
$('#main').prepend('<center><button class="btn btn-primary btn-lg" id="print2">복사하기</button></center>')
$('.post').prepend('<input type="checkbox" />');
$("#print2").on('click', function() {
var images = '';
$('li').each(function() {
var thisCheckFlag = $(this).children('input[type="checkbox"]').is(':checked');
if (thisCheckFlag) {
images += '<img src ="' + $(this).find('img').attr('src') + '">';
}
});
if (images) {
var myWindow = window.open('', 'printWindow', 'width=800,height=800');
myWindow.document.write(
'<html><head><title>Print</title></head><body>' + images + '</body></html>'
);
myWindow.focus();
myWindow.print();
} else alert('먼저 선택하세요.');
});
ev.preventDefault();
});
});

Fade in and out when clicking on an anchor tag

I have a page which loads content with php when clicking on the anchor tags on my menu and it works fine.
I have been trying to find the answer for days now.
Which code do I have to use to fade from one content to another? and where exactly do I add this code?
Here is my code:
$(document).ready(function() {
// Set trigger and container variables
var trigger = $('#centerMenu div a'),
container = $('#content');
// Fire on click
trigger.on('click', function() {
// Set $this for re-use. Set target from data attribute
var $this = $(this),
target = $this.data('target');
// Load target page into container
container.load(target + '.php');
// Stop normal link behavior
return false;
});
});
Also you can use this:
$(document).ready(function() {
// Set trigger and container variables
var trigger = $('#centerMenu div a'),
container = $('#content');
// Fire on click
trigger.on('click', function() {
// Set $this for re-use. Set target from data attribute
var $this = $(this),
target = $this.data('target');
// Load target page into container
container.fadeOut(250);
container.load(target + '.php').fadeIn(500);
// Stop normal link behavior
return false;
});
});
Give this a try:
$(document).ready(function(){
var trigger = $('#centerMenu div a'),
container = $('#content');
trigger.on('click', function(e){
e.preventDefault();
var $this = $(this),
target = $this.data('target');
container.fadeOut(500,function(){
container.load(target + '.php', function(){
container.fadeIn(500);
});
});
});
});
Note that 300ms is default fade time. I changed to 500 to show you where to make that change, if desired.

Can't target JSON-created block

For some reason I'm having a hard time implementing draggable (either jquery's or draggabilly) on JSON/jquery-created elements.
This is my jQuery along with the JSON.
var setTotal = function (){
var total = 0;
$('.block').each(function(){
total = total+parseInt($(this).data('cost'));
});
$('.totalSum').html(total);
};
window.onload = function(){
$.getJSON( "ajax/test.json", function( data ) {
$.each( data.createButton, function( key, val ) {
var button = $('<button class="btn" id="' + val.name +'" style="background: ' + val.color + '">' + val.name + '</button>');
button.on("click", function(){
//console.log("button " + val.name + " was clicked!");
var block = $('<div id="draggable" class="block ' + val.name + '-piece">'+ val.name + '<div class="close">-</div></div>');
block.data('cost', val.cost);
block.on("click", ".close", function(){
$(this).parent().remove();
// call set total to refresh it when item is removed
setTotal();
});
$('#boxes').append(block);
// call set total to calculate total blocks' cost
setTotal();
});
$('#field').append(button);
});
});
};
and this is how it's called in the html document;
<!-- Grab Google CDN's jQuery -->
<script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
<!-- Grab draggable -->
<script src="//cdnjs.cloudflare.com/ajax/libs/draggabilly/1.2.0/draggabilly.pkgd.min.js"></script>
<!-- My own scripts -->
<script src="js/main.js" type="text/javascript"></script>
<script>
var $draggable = $('#draggable').draggabilly({
// options...
});
</script>
<!-- End scripts -->
Now for some reason I can't target the ID (for testing only) nor the class (block) of the block variable. Does anyone know why? The draggable works fine with any other element on the page.
Sincerely, Sebastian
Two things :
you are appending multiple elements with id="draggable". Ids should be unique.
there's no evidence of invoking draggabilly on the appended elements.
Draggabilly needs to be invoked on :
any blocks that already exist on page load
dynamically created blocks after they have been appended
Personally, I would write the code something like this :
window.onload = function() {
var draggabilly_options = {
// options...
};
function create_button(key, val) {
$('<button/>', {
'id': val.name,
'class': 'btn',
'style': 'background-color:' + val.color,
'html': val.name,
})
.appendTo("#field")
.on('click', create_block.bind(val));
}
function create_block() {
$('<div/>' {
'class': 'block ' + this.name + '-piece',
'html': this.name + '<div class="close">-</div>'
})
.appendTo('#boxes')
.draggabilly(draggabilly_options) //invoke draggabilly on the div.block just added
.data('cost', this.cost)
.find('.close')
.on('click', close);
}
function close() {
$(this).closest(".block").remove();
setTotal();
}
function setTotal() {
var total = 0;
$(".block").each(function() {
total += parseInt($(this).data('cost'));
});
$('.totalSum').html(total);
};
$.getJSON( "ajax/test.json", function(data) {
$.each(data.createButton, create_button);
setTotal();
});
//You need this only if the page loads with any "draggable" blocks already in place.
$("#boxes .block").draggabilly(draggabilly_options);
};
Thank you for all responses. I took some advice from your code you published and put it like this;
// Start this after window is loaded
window.onload = function(){
// Init draggabilly
var draggabilly_options = {
// Dragabilly options
containment: '#boxes',
grid: [ 100, 100 ]
};
and also defined it further down in the button click function like so;
button.on("click", function(){
var block = $('<div id="block-' + val.id + '" class="block ' + val.name + '-piece"></div>');
var close = $('<div class="close">-</div>');
$(block).append(close);
block.data('cost', val.cost);
block.draggabilly(draggabilly_options);
This appeared to solve it for me! Thank you for the help and answers, they solved my problem :)

Preload images with jCarousel

I have the following code which loads a JSON feed and creates all the HTML needed for the jCarousel to work. However, I'm not sure how to preload the images. Anyone have any idea's how to do this?
$(".banner ul").jcarousel({
itemLoadCallback:loadTopBanner,
auto: 6,
wrap: 'circular',
scroll: 1,
animation:1000,
itemFallbackDimension:10
});
function loadTopBanner(carousel, state){
$.getJSON("get_top_banner.php", function(data){
carousel.size( data.length );
$.each(data, function(i){
carousel.add(i, makeTag(this.imageURL, this.URL));
});
});
}
function makeTag(img, url){
return "<a href='" + url + "'><img src='" + img + "'></a>";
}
This should do the trick, however, it is untested, and can be further optimised:
function loadTopBanner(carousel, state) {
$.getJSON("get_top_banner.php", function(data) {
carousel.size(data.length);
// make array of elements to which load events can be attached
var imgs = [];
$.each(data, function(i) {
var img = $("<img/>").attr("src", this.imageURL);
imgs.push(img);
});
// init a load counter
var loadCounter = 0;
$.each(imgs, function() {
$(this).one("load", function() {
loadCounter++
// when all have loaded, add to carousel
if (loadCounter == data.length) {
$.each(data, function(i) {
carousel.add(i, makeTag(this.imageURL, this.URL));
});
}
});
if(this.complete) $(this).trigger("load");
});
});
}
May not be a good solution but you can try to load the images somewhere on the page in a hidden div so that they will get cached before you make a ajax call and use them in loadTopBanner method. This way the carousel will not show any delay in loading the images.
If you really want to preload images, you don't need to put them in a hidden div -- you can use the Image object:
var image = new Image();
image.src = "images/foo.jpg";

Jquerymobile ListView

I am using following code to create a list dynamically. It works fine but when I click the particular list item, then the selected row's font color should turn yellow. How can I do it?
Thanks in advance.
$('#DateListView').children().remove('li');
//Make a new list
var parent = document.getElementById('DateListView');
for (var menuid = 0; menuid < weekStartDates.length; menuid++) {
var listItem = document.createElement('li');
listItem.setAttribute('id', 'listitem_' + weekStartDates[menuid]);
listItem.innerHTML = "<div data-role='button' style='margin-left:10px;font-size:15px'data-theme ='c' id='" + menuId + "'>" + Hai +"</div>";
parent.appendChild(listItem);
}
var list = document.getElementById('DateListView');
$(list).listview("refresh");
$('#DateListView li ").bind("click", function() {
$(this).setAttribute("style" , "font-color:yellow");
});
is this a typo? $('#DateListView li ") should have matching single or double quotes
This:
$('#DateListView li ").bind("click", function() {
$(this).setAttribute("style" , "font-color:yellow");
});
Should be:
$('#DateListView li').bind("click", function() {
$(this).setAttribute("style" , "font-color:yellow");
});
or:
$("#DateListView li").bind("click", function() {
$(this).setAttribute("style" , "font-color:yellow");
});
Also you might want to call the refresh after your added markup
$("#DateListView li").bind("click", function() {
$(this).setAttribute("style" , "font-color:yellow");
});
$(list).listview("refresh"); // Move after added markup
UPDATE:
$("#DateListView li").bind("click", function() {
$(this).attr("style" , "font-color:yellow");
});
$(list).listview("refresh"); // Move after added markup

Categories