jquery - unable to invoke function for dynamically created elements - javascript

I have a pagination ajax function displayed below:
$.fn.ajaxPagination = function() {
return this.unbind('click').on('click', function(e) {
e.preventDefault();
//alert();return;
if (!$(this).parent().hasClass('disabled')) {
var href = $(this).attr('href');
var wrapper = $(this).closest('.content-wrapper');
wrapper.addClass('loader-bg');
$.post(href + '&ajax=1', function(response) {
wrapper.removeClass('loader-bg');
wrapper.html(response);
sig.init();
return false;
});
} else {
return false;
}
});
};
I invoke it using the code:
$('.pagination > li > a').ajaxPagination();
Sometimes the anchor links are displayed from the result of ajax. So they become dynamically created elements. I am not able to invoke this function due to the dynamic creation of these anchor tags. I know how to solve this case if it was a click or any other event. But this is the invokation of a function. How to solve this issue? Any ideas are welcome. :)

I advise you to use event delegation. see https://learn.jquery.com/events/event-delegation/
You should bind click on a parent element containing all you dynamically created anchors, matching a selector, and you do not have to bother about adding the click event to the dynamically created elements.

Related

EventListener not working with anchor tel:XXXXXXXXX

I have a tag with href="tel:XXXXXXXXX", and I need catch the click event.
I have tested the following code on chrome: $(document).on('click',console.log). If i click on this tag browser it calls the application, but does not trigger a click event.
$("a[href^='tel']").on('click', console.log);
This is working, but I my have a problem with content load by ajax. My code has loaded a page and after some time application added content by ajax. When i use $(document).on('click', ("a[href^='tel']", console.log), there is a problem.
$("a[href^='tel']").on("click", function(e){
e.preventDefault(); e.stopPropagation();
console.log(this);
alert(this.getAttribute("href"));
})
//or if you want to delegate your function
$(document).on('click', "a[href^='tel']", function(e){
e.preventDefault(); e.stopPropagation();
console.log(this);
alert(this.getAttribute("href"));
});
This will bind an event listener to all click on a tags with a href attribute and prevent the click itself. After click, you'll be able to use your console to see which element was click and what href was used.
Ok, i found resolve.
I use earlier event "mousedown" and change attr "href" to "only number" for disable action click.
Code:
const click2dial_Event = function(e) {
e.preventDefault();
let a = $(this), number;
if (a.attr('href') !== '#') {
number = a.attr('href');
number = number.substr(4);
a.attr('href', '#');
a.attr('data-dial', number)
a.addClass('click-to-dial');
} else {
number = a.attr('data-dial');
}
//...
};
$(document).on('mousedown', "a[href^='tel']", click2dial_Event);
$(document).on('mousedown', '.click-to-dial', click2dial_Event);
This would get the phone number from the a tag starting with a value of tel upon clicking it.
$("a[href^='tel']").on("click", function(e) {
var hrefText = this.getAttribute("href");
var str = hrefText;
var res = str.split(":");
alert(res[1]);
});
On Initial Load
I would first recommend that you wait for the initial DOM to be ready before binding any events to elements.
// DOM ready shorthand
$(function() {
$("a[href^='tel']").on('click', function(e) {
// Do work here
});
});
AJAX Content
If you are adding additional elements after the initial load you will have to bind events to those new elements as well.
You could also do something like adding a data attribute to the elements that you've bound click events to and only add to ones that don't yet have that data attribute - but that's additional unnecessary work.
Full Example Code
// DOM Ready Shorthand
$(function() {
// Click Handler
function clickEvent(e) {
// Do work here
}
// Bind click event to initial tels
$("a[href^='tel']").on('click', clickEvent);
// Arbitrary AJAX request for demonstration (wherever yours may be)
$.ajax('/newContent')
.done(function(html) {
// Adding our response HTML to the page within #someElement
$('#someElement').append(html);
// Bind click event to the new tel elements scoped to the returned html
$("a[href^='tel']", html).on('click', clickEvent);
});
});

Jquery replaceWith() inside loop with click events

im trying to replace various elements with another inside a jquery .each loop and give them on click events to their child nodes, but it does not work, here is my code.
var replacer = function () {
var elementbody = "<div class='Container'><div class='Button'></div></div>";
$('.myclass').each(function (index, element) {
$(element).replaceWith(elementBody);
$(element).find('.Button').click(function () {
//------------------To do on click event------------------//
});
};
After you use
$(element).replaceWith(...);
element still refers to the old element, not the elements that have replaced it. So $(element).find('.Button') doesn't find the button you just added.
Instead of adding the handler to each element that you add, use delegation to bind a handler just once, as explained in Event binding on dynamically created elements?
$("someSelector").on("click", ".Button", function() {
...
});
You can use a delegate as Barmar suggests or you could provide yourself with a new jquery object that references your new content before running the replaceWith
Something like this, maybe:
new_element = $('<div><button>Hello World</button></div');
$(element).replaceWith(new_element);
new_element.find('button').on('click', function(e) {
console.log(e);
});

Appgyver - JQuery on click not working for dynamically written items

I am writing a single page app using appgyver (javascript). There are a number of lists that are written dynamically using javascript (following an external API call). Each list contains an item which, when clicked / pressed, I would like to fire a different js method.
function write_a_list(some_array)
{
$('#some_list').html("");
for ( indexor =0; indexor < some_array.length; indexor++)
{
var this_option_div = $('<div>');
this_option_div.addClass('item');
this_option_div.addClass('some_list_item');
this_option_div.html("Button: " + indexor);
$('#some_list').append(this_option_div);
}
}
$(document).on('click', '.some_list_item', function()
{
supersonic.logger.debug('some_list_item clicked');
alert('some_list_item clicked');
});
For example, an array is passed to the write_a_list function. If an item is clicked it should be detected and fire an alert. However, this behaviour isn't observed. Is there a way that this can be achieved using the jquery 'on' approach?
You are using this_option_div.addClass('some_list_item'); and then calling the click event on an id that may not exist.
Change it to:
$(document).on('click', '.some_list_item', function() { ... }
EDIT ////
Can you try the closest parent selector that is not dynamic instead of document?
$('.static-wrapper').on('click', '.some_list_item', function() { ... }

How do I get an event listener to work on an element that is added to my html via javascript?

I'm adding some HTML to my document via javascript. I also add a button to my HTML via this javascript function. I want this button to have an event listener, but this doesn't seem to work on the element added with javascript. Is it possible to fix this?
my js:
$('#content-overview li').on('click',function(){
// Clear previous videos
$('.content-overview-row').remove();
// Insert new video
var vimeoId = $(this).data('vimeo');
var html = '<li class="content-overview-row"><div class="content-overview-video"><iframe src="http://player.vimeo.com/video/'+vimeoId+'" width="950" height="534"></iframe><a id="close-video"></a></div></li>';
// Find end of row and insert detailed view
var nextRow = $(this).nextAll('.first-in-row:first');
if(nextRow.is('li')){
nextRow.before(html);
}
else{
//last row
if($(this).hasClass('first-in-row'))
{
//first item clicked in last row
$(this).before(html);
}
else{
$(this).prevAll('.first-in-row:first').before(html);
}
}
return false;
$('#close-video').click(function() {
console.log("works");
});
});
close-video is the close button I am talking about.
You need to bind the click event to an element which exists in the DOM when the page is loaded, and delegate the dynamically added element, like so:
$(document).on('click', '#close-video', function() {
...
});
You should change document for the element closest to your #close-video so that it doesn't have to bubble right up to the document.
Also, you're returning false; before the #close-video click handler, so that code would never be executed anyway. Move it outside of your #content-overview li click handler.

Adding jQuery event handlers to elements with wildcard IDs

I currently have the following in a document.ready block:
$("[id^=summaryDetailLink_]").each(function(index) {
var splitID = this.id.split("_");
this.click(alert('clicked: '+splitID[1])); //toggleDetail(splitID[1])
});
Ultimately I want to detect when a TD with an ID of "summaryDetail_" is clicked on and fire the toggleDetail function with the ID taken from the TD.ID attribute.
The above seems to generate the correct ID (the alert popsup) but is firing when the page loads rather than when I click on the element.
So problem number 1 - why is it firing on page load rather than creating a handler for click on each element and waiting for that click?
Problem number 2, in reading around this issue it seems it would be more sensible to create a single event handler on the table rather the TD then determine which TD element was clicked. How would I convert the code to do that?
Answer to first question:
$(function() {
$("[id^=summaryDetailLink_]").click(function() {
var splitID = $(this).id.split("_");
alert('clicked: '+splitID[1])
});
}
Answer to second question, you can do this:
$('table#yourtable').on('click', '[id^=summaryDetailLink_]', function(e) {
var splitID = $(this).id.split("_");
alert('clicked: '+splitID[1])
});
I think you're misunderstanding how the click handler works:
$(function() {
$("[id^=summaryDetailLink_]").click(function() {
var splitID = $(this).id.split("_");
alert('clicked: '+splitID[1])
});
}

Categories