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 :)
Related
I am using Templating Example of select2 library. When first time I change dropdown value it works and preview correct image, but second time, it appends second image and do not place first image.
Js:
$(document).ready(function () {
$('select#event_palette').change(function () {
var selectVal = 'res/img/Palette/' + $(this).val() + '-md.jpg';
$("#app-bg").append("<img src='"+ selectVal + "'></img>");
// $("#app-bg").remove();
});
});
You are appending new image to same node replace it to make it work.
$(document).ready(function () {
$('select#event_palette').change(function () {
var selectVal = 'res/img/Palette/' + $(this).val() + '-md.jpg';
$("#app-bg").html("<img src='"+ selectVal + "'></img>");
});
});
use html() instead of append().
$(document).ready(function () {
$('select#event_palette').change(function () {
var selectVal = 'res/img/Palette/' + $(this).val() + '-md.jpg';
$("#app-bg").html("<img src='"+ selectVal + "'></img>");
});
});
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.
Getting data from xml to insert into ul tag. When I run the code, page is loading and I can see images on browser but jquery codes are not working (ex. click to #GalleryList element) because appended codes are not seen browser view source. How can I find solution?
JS:
$(document).ready(function () {
$.ajax({
type: "GET",
url: "data.xml",
dataType: "xml",
success: function (xml) {
var items = [];
$(xml).find("item").each(function (i) {
items.push({
img: $(this).find("img").text(),
content: $(this).find("content").text()
});
$('#GalleryList').append('<li>' + items[i].img + '</li>');
$('#GalleryDetail').append('<li><div class="detailLeft">' + items[i].img + '</div><div class="detailRight">' + items[i].content + '</div></li>');
i++;
});
return items;
}
});
var currentElem, lastElem;
lastElem = $('#GalleryList li').last().index();
$('#GalleryList li').click(function () {
currentElem = $(this).index() + 1;
$('#GalleryList').hide();
$('.GalleryDetail').show();
$('#GalleryDetail li').hide();
$('#GalleryDetail li:nth-child(' + currentElem + ')').show();
pageControl();
});
});
HTML:
<ul id="GalleryList" class="clearfix">
</ul>
<div class="GalleryDetail">
<ul id="GalleryDetail">
</ul>
</div>
You need to use event delegation since the li elements are created dynamically
$('#GalleryList').on('click, 'li', function () {
currentElem = $(this).index() + 1;
$('#GalleryList').hide();
$('.GalleryDetail').show();
$('#GalleryDetail li').hide();
$('#GalleryDetail li:nth-child(' + currentElem + ')').show();
pageControl();
});
Use $.on("click",.. and not $.click. http://api.jquery.com/on/
You should use on to bind event to element dynamically created:
$('#GalleryList li').on('click', function ()
I'm getting an error on some JS code for a content window I'm trying to create. I'm getting told that }); shouldn't be where it is, but I can't understand what the problem is. Am I using terms from an outdated jquery?
jQuery(document).ready(function($) {
$('.contentwindow_trigger').click(function(e) {
e.preventDefault();
var image_href = $(this).attr("href");
if ($('#contentwindow').length > 0) {
$('#content').html('<img src="' + image_href + '" />');
$('#contentwindow').show();
}
else {
var contentwindow =
'<div id="contentwindow">' +
'<p>Click to close</p>' +
'<section id="content">' +
'<img src="#" />' +
'</section>' +
'</div>';
$('body').append(contentwindow);
}
}); //HERE
$('#contentwindow').on('click', function() {
$('#contentwindow').hide();
});
});
The fault is where it says HERE, any help would be appreciated.
Thanks!
Use this sript:
jQuery(document).ready(function() {
$('.contentwindow_trigger').click(function(e) {
e.preventDefault();
var image_href = $(this).attr("href");
if ($('#contentwindow').length > 0) {
$('#content').html('<img src="' + image_href + '" />');
$('#contentwindow').show();
}
else {
var contentwindow =
'<div id="contentwindow">' +
'<p>Click to close</p>' +
'<section id="content">' +
'<img src="#" />' +
'</section>' +
'</div>';
$('body').append(contentwindow);
}
}); //HERE
$('#contentwindow').on('click', function() {
$('#contentwindow').hide();
});
});
remove the $ from this line your code
function($) {
to
function() {
/
jQuery(document).ready(function() {
$('.contentwindow_trigger').click(function(e) {
// Click event code
});
$('#contentwindow').on('click', function() {
$('#contentwindow').hide();
});
});
One more change required which does not affect the Syntax error in the page is that I see that you are dynamically adding an element and associating a click event to it .
You need to delegate the event for such case and the Event might not work
$('body').on('click','#contentwindow' , function() {
$('#contentwindow').hide();
});
Not sure what the syntax error you're seeing is, but it seems to work fine in this jsfiddle:
http://jsfiddle.net/xV58c/
One change I made there that may help you. Instead of:
$('#contentwindow').on('click', function() {
$('#contentwindow').hide();
});
I did:
$('body').on('click', '#contentwindow', function() {
$('#contentwindow').hide();
});
which uses the "on" method in a way that allows the containing element ("body" in this case) to deal with events on elements below, even elements generated that way that #contentwindow is.
Hope this helps.
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