Add a Click Event to elements added to the DOM - javascript

var myOP = '<div>';
for (var i = 0; i < op.length; i++) {
myOP += '<div>';
myOP += '<div id="myBTN-' + [i] + '">' + op[i]['Field1'] + '</div>';
myOP += '<div id="blah-' + [i] + '">' + op[i]['Field2'] + '</div>';
myOP += '</div>';
}
myOP += '</div>';
$("#myBTN-" + i).click(function () {
$('#blah-' + i).toggle("slow");
});
$('#container').html(myOP);
I'm trying to get the click function to fire on the elements i'm created w/ the above for loop. Can anyone point me in the right direction?

As long as the element is just a String, you won't be able to add a handler. You have to add the handler after $('#container').html(myOP);
You could try exploring the idea of event delegation. Using that, your could do something like:
$('#container').on('click', function(e){
e = e || event;
var from = e.target || e.srcElement, i;
if (from.id && /^mybttn/i.test(from.id)){
i = +((from.id.match(/\d{0,}$/)||[-1])[0]);
if (i>=0){
$('#blah'+i).toggle('slow');
}
}
});​
​Demo
Alternatively you could
$('#container').html(myOP);
$('div[id^="myBTN-"]').on('click',function(){
$('#blah-' + this.id.match(/\d{0,}$/)[0]).toggle("slow");
});

after you save the html into #container use this:
$('[id^="myBTN-"]', '#container').click(function () {
$(this).closest('[id^="blah-"]').toggle('slow');
});

jQuery's .on() method will bind to appended elements if used properly. http://api.jquery.com/on/
<div id="existingParent">
<!--<div class="added-later">Hi!</div>-->
<!--<div class="added-later">Hi!</div>-->
</div>
To listen for events on the added-later elements
$('#existingParent').on('click hover','.added-later', myFunction);
The method must be bound to an element that exists. $('body') can be used here, but at the cost of some performance I'd imagine.

Do something like this:
var myOP = '<div>';
for (var i = 0; i < op.length; i++) {
myOP += '<div>';
myOP += '<div id="myBTN-' + [i] + '">' + op[i]['Field1'] + '</div>';
myOP += '<div id="blah-' + [i] + '">' + op[i]['Field2'] + '</div>';
myOP += '</div>';
}
myOP += '</div>';
$(myOP).appendTo('#container').find('div[id^="myBTN"]').click(function () {$(this).next().toggle("slow")});

When you re trying to attach events added dynamically, a simple .click() won't do, you have to use on:
$("#newElementparent").on('click', "#newElement", function() {});

You'd do better to build the element on the fly:
var container = $('<div>');
for (var i = 0; i < op.length; i++) {
container.append(
$('<div>').append(
$('<div>').text(op[i]['Field1']).click(function() {
$(this).next('div').toggle("slow");
}),
$('<div>').text(op[i]['Field2'])
)
);
}
$('#container').empty().append(container);

Related

Cart only changes color of the first item of each game

I have this function that add's to my cart html, and its working fine. But when i add two of the same Item i get an error(only changes color in the first of each same item).
The console.log(changeBackgroundColor); console.log(changeColorText); gets only the first div of each game.
const addToCart = function () {
getJSON('games.json', function (err, data) {
var cartBets = document.getElementById('cart-bets');
if (err === null) {
console.log('Ocorreu um erro' + err);
} else {
let html = '';
regexPrice = data.types[whichLoteriaIsVar].price;
totalPrice += regexPrice;
let newTotalPrice = data.types[whichLoteriaIsVar].price
.toFixed(2)
.replace('.', ',');
html += '<div class="bar-side-cart">';
html += '<div class="side-by-side">';
html +=
'<div class="menu-thrash-save"><i onclick="deleteItemCart(this)" value="' +
data.types[whichLoteriaIsVar].price +
'" class="far fa-trash-alt" src="img/thrash-can.jfif" width=15 alt="Thrash"></i>
</div>';
html +=
'<div data-style="cart-thrash-side-bar-' +
data.types[whichLoteriaIsVar].type +
'" class="bets-backgroundcolor-lotos-container"></div>';
html += '<div class="top-by-top">';
html += '<p class="cart-right-text">' + totalNumbers + '</p>';
html += '<div class="side-by-side">';
html +=
'<div data-style="cart-text-thrash-' +
data.types[whichLoteriaIsVar].type +
'" class="bets-color-lotos-container">' +
data.types[whichLoteriaIsVar].type +
'</div>';
html += '<div class="cart-money">R$ ' + newTotalPrice + '</div>';
html += '</div>';
cartBets.innerHTML += html;
var changeBackgroundColor = document.querySelector(
'[data-style="cart-thrash-side-bar-' +
data.types[whichLoteriaIsVar].type +
'"]'
);
changeBackgroundColor.style.backgroundColor =
data.types[whichLoteriaIsVar].color;
var changeColorText = document.querySelector(
'[data-style="cart-text-thrash-' +
data.types[whichLoteriaIsVar].type +
'"]'
);
changeColorText.style.color = data.types[whichLoteriaIsVar].color;
console.log(changeBackgroundColor);
console.log(changeColorText);
getCartTotal();
}
});
};
document.querySelector() only returns the first matched element. Try using document.querySelectorAll() with a loop:
var changeBackgroundColor = document.querySelectorAll(
'[data-style="cart-thrash-side-bar-' +
data.types[whichLoteriaIsVar].type +
'"]'
);
changeBackgroundColor.forEach(
element => element.style.backgroundColor =
data.types[whichLoteriaIsVar].color
);

dynamically created button and its own value

How to get data-index of clicked button:
var removePair = $("button[name=removePair]"),
tbody = $('tbody[name=tb-table]'),
function DrawHtml(list) {
var html = '';
for (var i = 0; i < list.length; i++) {
var o = list[i];
html += '<tr name="row-' + i + '">';
html += ' <td>';
html += ' <button name="removePair" data-index="' + i + '" class="btn btn-primary mx-1" type="button"><i class="fa fa-trash-o" aria-hidden="true"></i></button>';
html += ' </td>';
html += '</tr>';
}
return html;
}
$(tbody).on("click", removePair, function () {
console.log($(this));
console.log($(this).val());
console.log($(removePair));
});
The only way that I know to add event on dynamiclly added button is to attache it to parrent (tbody), and fire by dynamiclly created button removePair, but I dont know how to get clicked removePair for further logic.
this return tbody instead of removePair
thanks!!
You should pass the selector to .on() method instead of elements. As the elements are created dynamically hence $("button[name=removePair]") doesn't exists.
Use
removePair = "button[name=removePair]"
var removePair = "button[name=removePair]",
tbody = $('tbody[name=tb-table]');
function DrawHtml(list) {
var html = '';
for (var i = 0; i < list; i++) {
html += '<tr name="row-' + i + '">';
html += ' <td>';
html += ' <button name="removePair" data-index="' + i + '" type="button">' + i + '</button>';
html += ' </td>';
html += '</tr>';
}
return html;
}
//Create HTML
tbody.html(DrawHtml(5));
$(tbody).on("click", removePair, function() {
console.log($(this).text());
console.log($(removePair).length);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody name="tb-table"></tbody>
</table>
Rather than name attribute use class instead
$('body').on('click', '.btn-primary', function (e) {
});

Toggle animation on click

I would like to add a jquery toggle effect on my code which has HTML within my Javascript. Any advice?
GuessGame.prototype.createBoard = function(){
var html = '';
Object.keys(this.cards).forEach(function(key) {
html += '<div class="card" id="' + key + '"';
html += ` style='background-image: url(img/${key}.jpg)'`;
html += '>'
html += '<div class="front" ';
html += 'id="' + key + '">';
html += '</div>';
html += '</div>';
});
// Add all the divs to the HTML
document.getElementById('board').innerHTML = html;
In your example you're not really using the power of jQuery.
Here is a better approach.
GuessGame.prototype.createBoard = function(){
var board = $('#board');
Object.keys(this.cards).forEach(function(key) {
var card = $('<div class="card" id="' + key + '" style="background-image: url(img/${key}.jpg)"><div class="front"></div></div>');
// add onClick Event
card.on('click', function(e) {
card.toggleClass('toggled-class');
});
// append card to board
board.append(card);
});

Need help using a 'for loop' extracting data from a Table

Just wondering if anyone can help me.
I have created a table, and using Javascript I am extracting all the data and placing it into divs.
$(function () {
$('table').each(function () {
var output = "",
table = $(this),
rowHead = table.find('tbody tr th'),
rowSubject = table.find('thead tr th:not(:first-child)'),
rowContent = table.find('tbody tr td'),
copy = table.clone();
output += '<div class="mobiled-table">';
for (i = 0; i < rowHead.length; i++) {
output += '<div class="head">' + $(rowHead[i]).html() + '</div>';
for (j = 0; j < rowSubject.length; j++) {
output += '<div class="subject">' + $(rowSubject[j]).html() + '</div>';
output += '<div class="content">' + $(rowContent[i]).html() + '</div>';
}
}
output += '</div>';
$('table').append(output);
});
});
It all works great except the .content class isnt working correctly. I believe I am using the wrong 'for loop' or I need to create another 'for loop'. Please take a look at my codepen and you will see my problem
http://codepen.io/anon/pen/JrKBf
I hope someone can help.
Because rowContent contains the matrix of cells but as a one dimension array, you have to translate (i, j) to a valid index for rowContent which is (i * 4) + j:
rowContent[i]
should be replaced by:
rowContent[(i*4) + j]
In a simpler way, you can do like this,
var container=$("#container");
$("table tr:not(:first)").each(function() {
var heading = $(this).find("th").html();
container.append('<div class="subject">' + heading + '</div>');
$(this).find("td").each(function(i) {
container.append('<div class="subject">' + $("table th").eq($(this).index()).html() + '</div>');
container.append('<div class="content">' + $(this).html() + '</div>');
});
});
Fiddle

Jquery .Hover issue with Ajax

I have this code:
cuts_html = '';
for( i = 0; i < attachments.length; i++ ) {
fburl3 = site_url + '/haircut-detail/?img_id=' + attachments[i].ID + '&uid=' + attachments[i].post_author;
if( isNaN(attachments[i].view_count) ) attachments[i].view_count = 0;
cuts_html += '<div id="controller-image" class="cut-image">';
cuts_html += '<div id="cut-imageplacer">';
cuts_html += '<div class="cut-image-info">' +
'By <a href="' + user_profile_url +
'&user_id=' + attachments[i].post_author + '">' +
attachments[i].author_name + '</a>' +
'</div>';
cuts_html += '<div class="commentbox-1">' +
'<img src="https://d2xcq4qphg1ge9.cloudfront.net/assets/17276/435546/original_views.png"> ' +
attachments[i].view_count +
' <img src="https://d2xcq4qphg1ge9.cloudfront.net/assets/17276/435545/original_talk-bubble.png"> ' +
'<fb:comments-count href="' + fburl3 + '"></fb:comments-count>' +
'</div></div>';
cuts_html += '<a class="cut-image-a" ' +
'href="' + image_detail_url +
'?uid=' + attachments[i].post_author +
'&img_id=' + attachments[i].ID + '">' +
attachments[i].attachment_image_html + '</a>';
cuts_html += '</div>';
}
Div Id cut-imageplacer is display:none, so what I want is when someone hovers the controller-image div, the cut-imageplacer to show and hide of course when not on. I use this code:
<script type="text/javascript">$(document).ready(function(){ $('.cut-image').hover(
function(){ $('#cut-imageplacer').show();
}, function () { $('#cut-imageplacer').hide(); }); }); </script>
But it doesn't work... Any idea what I am doing wrong? Or point me to correct direction?
It look like you are trying to attach events to elements that are being dynamically created. You need to use Live() or On() to attach events to these elements after they are created. Look at This and This to see how to use those.
like:
<script type="text/javascript">
$(document).ready(function(){
$('.cut-image').live("hover",
function(){
$('#cut-imageplacer').show();
}, function () {
$('#cut-imageplacer').hide();
});
}); </script>

Categories