Javascript/Jquery: issue with append in cycle - javascript

I get Flickr gallery via API/Json. My issue with my code is that the gallery that I fetch has ~ 30 picture, but this snippet:
$.each(data.album.content,function (index,content)
{
album_container.append(column);
[...]
}
Appends only one <div> to the container, and not 30, but appends in right way 30 a/img to this unique column. I cannot figure why and how solve it.
Thank you for your help!
var album_container = $('div#album');
function callGetAjax(url)
{
return $.get(url,{});
}
function getAlbum(feed_url)
{
callGetAjax(absolute_path+'/feed/'+feed_url)
.success(function(data)
{
})
.error(function(xhr, statusText)
{//console.log(statusText);
})
.done(function(data)
{
var loaded = 0;
album_title = data.album.album_title;
$('h1#gallery-title').html(album_title);
var column = $('<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2"></div>');
$.each(data.album.content,function (index,content)
{
album_container.append(column);
$('<a/>')
.append($('<img class="img-responsive">').prop('src', content.photo))
.prop('href', content.target)
.prop('title', content.title)
.attr('data-gallery', '')
.appendTo(column)
.colorbox({rel:'gallery', speed:0, maxWidth:'95%', maxHeight:'95%'});
});
});
}
Current HTML result:
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2">
<img src="..." />
<img src="..." />
<img src="..." />
[...]
</div>
HTML that I need:
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2">
<img src="..." />
</div>
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2">
<img src="..." />
</div>
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2">
<img src="..." />
</div>
[...]

Remember that .append() will move the HTML node around the DOM tree when the node already exists in your document. In your case, you have declared:
var column = $('<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2"></div>')
…outside of your $.each() loop, therefore causing it to be repeatedly moved around inside album_container, instead of being cloned as you have expected. Therefore, what you would do is to declare it within your loop, such that the instance is not outside the scope of your loop:
var album_container = $('div#album');
function callGetAjax(url)
{
return $.get(url,{});
}
function getAlbum(feed_url)
{
callGetAjax(absolute_path+'/feed/'+feed_url)
.success(function(data)
{
})
.error(function(xhr, statusText)
{//console.log(statusText);
})
.done(function(data)
{
var loaded = 0;
album_title = data.album.album_title;
$('h1#gallery-title').html(album_title);
$.each(data.album.content,function (index,content)
{
// Creates a new column for every image element
var column = $('<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2"></div>'),
item = $('<a/>')
.append($('<img class="img-responsive">').attr('src', content.photo))
.attr('href', content.target)
.attr('title', content.title)
.attr('data-gallery', '')
.appendTo(column)
.colorbox({rel:'gallery', speed:0, maxWidth:'95%', maxHeight:'95%'});
// Append column instance to the album container
album_container.append(column);
});
});
}
If you're also looking for a review of your code, may I suggest you transition away from the jqXHR.success() and jqXHR.error() methods? They have been deprecated in favour of the jqXHR.done() and jqXHR.fail() methods. Using promises, we have a backbone that looks like this:
var album_container = $('div#album');
function callGetAjax(url)
{
return $.get(url,{});
}
function getAlbum(feed_url)
{
// Store returned promise from $.get() in a variable
var ajaxCall = callGetAjax(absolute_path+'/feed/'+feed_url);
// Now we listen to the promise
ajaxCall
.done(function(data) {
var loaded = 0;
album_title = data.album.album_title;
$('h1#gallery-title').html(album_title);
$.each(data.album.content,function (index,content)
{
var column = $('<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2"></div>'),
item = $('<a/>')
.append($('<img class="img-responsive">').attr('src', content.photo))
.attr({
'href': content.target,
'title': content.title,
'data-gallery': ''
})
.appendTo(column)
.colorbox({rel:'gallery', speed:0, maxWidth:'95%', maxHeight:'95%'});
album_container.append(column);
});
})
.fail(function(xhr, statusText) {
// Log error
// console.log(statusText);
});
}

Related

Append in JQuery from JSON Response

I am trying to add data from a response inside a HTML block
What I have done
...
success: function () {
console.log($("#re-side-cart-items"))
$.getJSON('/cart.js', function (cart) {
$.each(cart.items, function (index, element) {
if(element.id == rewards_variant_id){
console.log($("#re-sidecart-item-template").html());
$("#re-side-cart-items").append($("#re-sidecart-item-template").html())
}
})
});
},
....
My HTML block was assigned to this var htmlwid = $("#re-sidecart-item-template").html();
<div id="re-sidecart-item-template" class="hide">
"<div class=cart-product row id=" + element.id + ">"
<div class="col-lg-3 col-md-3 col-sm-4 product-img">
<div class="image">
<div class="aspect-container">
<img src="element.img" alt="element.handle" loading="lazy" />
</div>
</div>
</div>
<div class="col-lg-8 col-md-8 col-sm-7 product-info">
<div class="product-title">
element.title element.price/mo.</b>
</div>
</div>
</div>
</div>
I want to take the element values from the responses, it basically not working the way it should.
I was able to fix it
success: function () {
if (window.location.pathname == '/cart'){
window.location.href = "/cart";
}
else{
$.getJSON('/cart.js', function (cart) {
$.each(cart.items, function (index, element) {
if(element.id == rewards_variant_id){
$("#re-side-cart-items").append($('<div>').attr('id', element.id).attr('class', 'cart-product row')
.append($('<div>').attr('class', 'col-lg-3 col-md-3 col-sm-4 product-img')
.append($('<div>').attr('class', 'image')
.append($('<div>').attr('class', 'aspect-container')
.append($('<img>').attr('src', element.image).attr('alt', element.product_title).attr('loading', 'lazy')))))
.append($('<div>').attr('class', 'col-lg-8 col-md-8 col-sm-7 product-info')
.append($('<div>').attr('class', 'product-title')
.append($('<a>').attr('href', element.url)
.append(element.product_title + ' ' + element.price/100 + '/mo.')
)
.append($('<div>').attr('class', 'cart-pricing')
.append($('<a>').attr('href', '/cart/change?line='+element.index+'&quantity=0').attr('data-line', element.id)
.append('<u>Remove</u>')
))
))
);
}
})
});
}
},

How to get first class name dynamically added using javascript

I have multiple div element's which is generated dynamically. I want to access the first class name using javascript. So far i did this:
function changeFilter(cat) {
console.log(cat);
var x = {};
x = document.getElementsByClassName("itemProductList");
console.log(x);
if (cat == x) {
console.log("yes");
} else {
console.log("nope");
}
}
In console I get this:
div.Desserts.itemProductList.item-list.col-md-3.col-lg-3.col-xs-12.col-sm-4,
My div elements that are generated dynamically looks something like this:
<div class="{{product.category}} itemProductList item-list col-md-3 col-lg-3 col-xs-12 col-sm-4" style="float:left; min-height:370px; margin-bottom:20px;" ng-repeat="product in store.products | filter:search | filter:category">
How can I get Deserts from above?
Can someone help me out?
Use the classList property and take the first element.
The function document.getElementsByClassName() will return an iterable with possibly many items, so you can use Array.forEach() to iterate over them, but you have to convert the result to an array first:
const divs = document.getElementsByClassName("itemProductList");
[...divs].forEach(div => console.log(div.classList[0]));
<div class="Desert itemProductList item-list col-md-3 col-lg-3 col-xs-12 col-sm-4">
<div class="Desert itemProductList item-list col-md-3 col-lg-3 col-xs-12 col-sm-4">
<div class="Desert itemProductList item-list col-md-3 col-lg-3 col-xs-12 col-sm-4">
You can split the element's classname on a space and get the first part of that array.
document.getElementsByClassName returns a HTMLCollection which you can iterate over with a for loop.
for(var i=0; i<x.length; i++){
console.log(x[i].className.split(" ")[0]);
}

Dynamic checkbox onchange not working using jquery?

I have created dynamic checkboxes using jQuery and showing in div and I have created checkbox onchange function.
static checkbox onchange function working but when I generate dynamic checkbox and same function call it didn't work.
Dynamic checkbox code:
$(document).on("click", "#item_modal", function() {
$.ajax({
url: '<?=base_url()?>extraItem',
type: 'post',
dataType: 'json',
data: {itemId: id}
})
.done(function(data) {
console.log(data);
var extraItems = "";
$.each(data, function(index, el) {
extraItems+='<div class="col-md-4 col-lg-4"> <label style="width:100%"> <div class="col-md-6 col-lg-6 col-sm-6 col-xs-6"> <div style="font-size:14px;color:#fff;" class="checkbox"> <input name="product" value="'+el.amt+'" type="checkbox" id="p'+el.id+'"> <b>'+el.name+'</b> </div></div><div class="col-md-6 col-lg-6 col-sm-6 col-xs-6"> <p style="color:#fff;padding:10px;font-size:12px"> <span class="fa fa-rupee"></span> <b>'+el.amt+'</b> </p></div></label> </div>';
});
$('.extraItemList').append(extraItems);
jQuery('#myModal .modal-content').html();
$('#myModal').modal({
"backdrop": "static"
});
});
});
Checkbox Onchange Function :
$(document).ready(function() {
$(":checkbox").on("change", function() {
console.log("check");
});
});
Html Static Checkbox : It's working
<div class="col-md-12 col-lg-12" style="padding:0 34px;">
<div class="col-md-4 col-lg-4">
<label style="width:100%">
<div class="col-md-6 col-lg-6 col-sm-6 col-xs-6">
<div style="font-size:14px;color:#fff;" class="checkbox"> <input name="product" value="60.00" type="checkbox" id="p4" class="checkboxes"> <b>Extra Veg</b> </div>
</div>
<div class="col-md-6 col-lg-6 col-sm-6 col-xs-6">
<p style="color:#fff;padding:10px;font-size:12px"> <span class="fa fa-rupee"></span> <b>60.00</b> </p>
</div>
</label>
</div>
</div>
Html Dynamic :
<div class="col-md-12 col-lg-12 extraItemList" style="padding:0 34px;">
</div>
I am adding dynamic checkboxes on .extraItemList class
I have spent lots of time to resolve it but could not find anything.
Is it any solution ? because it's weird.
You can bind checkbox change like this:
$(document).ready(function() {
$(".extraItemList").on("change", 'input[type="checkbox"]', function() {
console.log("check");
});
});
By doing so it will bind to all inputs of checkbox type which are inside the extraItemList class.
I hope this helps.
You should use event delegation for dynamic element like following.
$(".extraItemList").on("change", ":checkbox", function() {
console.log("check");
});
Change
$(document).ready(function() {
$(":checkbox").on("change", function() {
console.log("check");
});
});
To
$(document).ready(function() {
$(".extraItemList").on("change", ":checkbox", function() {
console.log("check");
});
});
If you go with you solution jQuery wil bind the event to the checkboxes currently available, if you go with mine jQuery will bind the event to the document and will check if the element is the checkbox and it will trigger the event. So it'll work for dynamic content

Javascript in html tags to avoid repetition

I am a newbie to JavaScript and I need to use it with bootstrap for my own web page. My question is now how can I make a loop so that pictures names (stored as an array) can emerge in the right places of the HTML code so I do not have to copy the blocks of code for each picture.
For example :
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="01.jpg">
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="01.jpg">
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="02.jpg">
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="03.jpg">
</div>
</div>
As we can see here the only different text is the src.How can I store the names (paths) in an array and make a loop that changes the src property?
Thank you!
Try this demo: http://jsbin.com/pinoxeqapi/1/edit?html,output
I think that's what you're looking for.
CODE
$(function () {
var images = ["01.jpg", "01.jpg", "02.jpg", "03.jpg"];
$.each(images, function (index, element) {
var imgContainer = "<div class='row'><div class='col-md-3 col-xs-6 portfolio-item><img class='img-responsive' src='" + element + "'></div></div>";
$("body").append(imgContainer);
});
});
First Include JQuery (If not)
<script>
var srcArray = ['01.jpg', '02.jpg', '03.jpg', '04.jpg'];
$(document).ready(function () {
for (var i = 0; i < srcArray.length; i++) {
$('div.row img.img-responsive').eq(i).attr("src", srcArray[i]);
}
});
</script>
I would recommend using one of the templating frameworks described in some of the other answers. If you're interested to see how to implement this in pure JS:
var temp = document.querySelector('#portfolio-item-template');
['01.jpg', '02.jpg', '03.jpg', '04.jpg'].forEach(function(src) {
temp.content.querySelector(".img-responsive").src = src;
var newImg = document.importNode(temp.content, true);
document.querySelector('#insertion-point').appendChild(newImg);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="portfolio-item-template">
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive">
</div>
</div>
</template>
<div id="insertion-point">
</div>
You can use a template stored in the HTML and then generate the actual elements using an array of the image sources. Something like John Resig's micro-templates can achieve this.
<script type="text/template" id="img-tmpl">
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item>
<img class="img-responsive" src="<%= src %>">
</div>
</div>
</script>

Get children under a parent using jQuery

$(document).ready(function() {
$.ajax({
type: "POST",
url: 'some/url',
data: {
'name':'myname'
},
success: function (result) {
var result = ["student", "test"];
var length = result.length;
for (var i = 0; i < length; i++) {
var datastores = result;
$('#data_stores').append(
"<div class='col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore' id=" + datastores[i] + "> </div>");
}
}
})
var ids = $('#data_stores').children().map(function(){ return this.id }).get();
$('<pre>').appendTo('body').text(JSON.stringify(ids));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="data_stores">
</div>
<div id="data_stores">
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="students">
//Some other codes here
</div>
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="teachers">
//Some other codes here
</div>
</div>
This is a block of code in my HTML. The inner divs under data_stores are created using jquery. The IDs of the children div were result of an AJAX request and assigned on success.
The problem is, I need the ID values of the children divs to use for another AJAX call.
I ran the following:
console.log($("#data_stores"));
Output I got is the same above.
But for,
console.log($("#data_stores").find('.datastore'));
[prevObject: m.fn.init[1], context: document, selector: "#data_stores
.datstore"]
But, when accessing the child it says the element is undefined.
I need to do both AJAX calls on
$(document).ready(function() {
})
Using children like this works:
var ids = $('#data_stores').children().map(function(){ return this.id }).get();
var ids = $('#data_stores').children().map(function(){ return this.id }).get();
$('<pre>').appendTo('body').text(JSON.stringify(ids));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="data_stores">
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="students">
//Some other codes here
</div>
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="teachers">
//Some other codes here
</div>
</div>

Categories

Resources