JQuery on click event not working inside dropdown menu with hyperlink? - javascript

I have an autocomplete dropdown using twitter-typeahead as follows:
$('#Data').typeahead(
{
displayKey: 'description',
source: myData.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
<a class="js-not-found" href="#">No results found</a>,
'</div>'
].join('\n'),
suggestion: function (data) {
return '<span>' + data.description + '</span>';
}
}
}
);
When no results are found the dropdown display a link. I have wired this to a Jquery on click handler as below but when I click the link it just reloads the page?
$(".js-not-found").click(function (e) {
e.preventDefault();
// some stuff
});
The event handler works fine if I have a normal link outside of the dropdown as follows <a class="js-not-found" href="#">No results found</a>

The link is not inside the DOM when you attach the event. For dynamically generated elements you should use on.
Can you try :
$(document).on('click','.js-not-found', function (e) {
e.preventDefault();
// some stuff
});
For better performance it's recommanded to use the direct ancestor inside the DOM of the generated element :
$(".container").on('click','.js-not-found', function (e) {
e.preventDefault();
// some stuff
});

Using delegate() function you can click on dynamically generated HTML elements that are not in your DOM.
Example:
$(document).delegate('.js-not-found', 'click', function()
{
e.preventDefault();
//your code
});
or you can use on() as
$(document).on('click', '.js-not-found', function()
{
// your code
});

Related

After appending an element the event click is not working on the appended element in jQuery

I am appending item by jQuery. But after appending can't bind the event on the appended item. I am appending as follows:
var item = '<div id="'+newInputId+'" class="col-md-9" style="padding-right: 0px;">';
item += '<input id="txtInScope" type="text" value="'+currentScopeVal+'" class="form-control" readonly="readonly"/>';
item += '</div>';
item += '<div id="inScopeActionDiv'+newInputId+'" class="col-md-3" style="padding-left: 2px;">';
item += '<button type="button" class="btn btn-warning btn-sm remButton" title="Remove this item">Remove Item</button>';
item += '</div>';
$('#inScopeDiv').append(item);
And after appending this I want to bind a click event on the above remButton class as below:
$("#inScopeDiv").delegate(".remButton", "click", function(){
alert('you clicked me again!');
});
$('#inScopeDiv').on('click', '.remButton', function() {
alert("working");
})
$('.remButton').live('click', function() {
alert('live');
})
But no result. What can I try next?
$('.remButton').live('click', function() {
alert('live');
})
jquery method live is not valid anymore:
"As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live()."
Source: jquery live
Little explanation about event attachment:
You must realize that a target what you want to add a event, exists BEFORE to call the add event function(in this case with the method on of jQuery).
on another hand, exists with jquery a manner to make work a event attachment without the existence of the element before:
$('html').on('click', '#inScopeDiv .remButton', function () {
alert('works!');
});
Bind it on a parent that is not dynamic but always in the DOM.
You need to add the listener each time you add an item:
$('#inScopeDiv').append(item)
.off() //unbind old listeners so no duplicate listeners
.on('click', '.remButton', function() {
alert("working");
});
You could store the appended div in a variable using .appendTo and then you could attach the click event directly to the variable. See it working: JSFiddle
$(".appendDiv").click(function () {
var item = "<div>I'm a new div!</div>";
var appended_div = $(item).appendTo(".container");
appended_div.click(function () {
alert("Working!");
});
});

Trigger AJAX inside an AJAX loaded page [duplicate]

I have a link, myLink, that should insert AJAX-loaded content into a div (appendedContainer) of my HTML page. The problem is that the click event I have bound with jQuery is not being executed on the newly loaded content which is inserted into the appendedContainer. The click event is bound on DOM elements that are not loaded with my AJAX function.
What do I have to change, such that the event will be bound?
My HTML:
<a class="LoadFromAjax" href="someurl">Load Ajax</a>
<div class="appendedContainer"></div>
My JavaScript:
$(".LoadFromAjax").on("click", function(event) {
event.preventDefault();
var url = $(this).attr("href"),
appendedContainer = $(".appendedContainer");
$.ajax({
url: url,
type : 'get',
complete : function( qXHR, textStatus ) {
if (textStatus === 'success') {
var data = qXHR.responseText
appendedContainer.hide();
appendedContainer.append(data);
appendedContainer.fadeIn();
}
}
});
});
$(".mylink").on("click", function(event) { alert("new link clicked!");});
The content to be loaded:
<div>some content</div>
<a class="mylink" href="otherurl">Link</a>
Use event delegation for dynamically created elements:
$(document).on("click", '.mylink', function(event) {
alert("new link clicked!");
});
This does actually work, here's an example where I appended an anchor with the class .mylink instead of data - http://jsfiddle.net/EFjzG/
If the content is appended after .on() is called, you'll need to create a delegated event on a parent element of the loaded content. This is because event handlers are bound when .on() is called (i.e. usually on page load). If the element doesn't exist when .on() is called, the event will not be bound to it!
Because events propagate up through the DOM, we can solve this by creating a delegated event on a parent element (.parent-element in the example below) that we know exists when the page loads. Here's how:
$('.parent-element').on('click', '.mylink', function(){
alert ("new link clicked!");
})
Some more reading on the subject:
https://learn.jquery.com/events/event-delegation/
http://jqfundamentals.com/chapter/events
if your question is "how to bind events on ajax loaded content" you can do like this :
$("img.lazy").lazyload({
effect : "fadeIn",
event: "scrollstop",
skip_invisible : true
}).removeClass('lazy');
// lazy load to DOMNodeInserted event
$(document).bind('DOMNodeInserted', function(e) {
$("img.lazy").lazyload({
effect : "fadeIn",
event: "scrollstop",
skip_invisible : true
}).removeClass('lazy');
});
so you don't need to place your configuration to every you ajax code
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers.
Example -
$( document ).on( events, selector, data, handler );
For those who are still looking for a solution , the best way of doing it is to bind the event on the document itself and not to bind with the event "on ready"
For e.g :
$(function ajaxform_reload() {
$(document).on("submit", ".ajax_forms", function (e) {
e.preventDefault();
var url = $(this).attr('action');
$.ajax({
type: 'post',
url: url,
data: $(this).serialize(),
success: function (data) {
// DO WHAT YOU WANT WITH THE RESPONSE
}
});
});
});
If your ajax response are containing html form inputs for instance, than this would be great:
$(document).on("change", 'input[type=radio][name=fieldLoadedFromAjax]', function(event) {
if (this.value == 'Yes') {
// do something here
} else if (this.value == 'No') {
// do something else here.
} else {
console.log('The new input field from an ajax response has this value: '+ this.value);
}
});
use jQuery.live() instead . Documentation here
e.g
$("mylink").live("click", function(event) { alert("new link clicked!");});
For ASP.NET try this:
<script type="text/javascript">
Sys.Application.add_load(function() { ... });
</script>
This appears to work on page load and on update panel load
Please find the full discussion here.
Important step for Event binding on Ajax loading content...
01. First of all unbind or off the event on selector
$(".SELECTOR").off();
02. Add event listener on document level
$(document).on("EVENT", '.SELECTOR', function(event) {
console.log("Selector event occurred");
});
Here is my preferred method:
// bind button click to function after button is AJAX loaded
$('#my_button_id').bind('click', function() {
my_function(this);
});
function my_function () {
// do stuff here on click
}
I place this code right after the AJAX call is complete.
I would add one point that was NOT obvious to me as a JS newb - typically your events would be wired within document, e.g.:
$(function() {
$("#entcont_table tr td").click(function (event) {
var pk = $(this).closest("tr").children("td").first().text();
update_contracts_details(pk);
});
}
With event delegation however you'd want:
$(function() {
// other events
}
$("#entcont_table").on("click","tr td", function (event) {
var pk = $(this).closest("tr").children("td").first().text();
update_contracts_details(pk);
});
If your event delegation is done within the document ready, you'll an error of the like:
cant assign guid on th not an boject

JQuery anchor link selector issue

I'm trying to select the list anchor link using jquery. Though 'list' link doesn't exist in the page as shown in the console output, it seems 'click' is still getting triggered. What could be causing 'list' and 'add' to trigger?
I have this simple code using jquery 1.10.2:
<!-- List -->
Delete
Add
<script>
jQuery(document).ready(function($) {
if ($('a[href$="#list"]').length>0){
console.log('list found');
}else{
console.log('list not found');
}
function opentab(value){
console.log('opentab: ' + value );
//perform task here
}
$(document).on('click', 'a[href="#list"]', opentab('list'));
$(document).on('click', 'a[href="#add"]', opentab('add'));
});
</script>
console output:
list not found
opentab: list
opentab: add
Here's jsfiddle link: http://jsfiddle.net/2FHf6/
you need to declare a function in the event that when this event occurs call this function, currently the method inside event is called on page load as your way of calling is not right:
do like this:
$(document).on('click', 'a[href="#list"]', function(){
opentab('list')
});
$(document).on('click', 'a[href="#add"]', function(){
opentab('add')
});
UPDATED FIDDLE
$(document).on('click', 'a[href="#list"]', function(e){
opentab('list');
});
$(document).on('click', 'a[href="#add"]', function(e){
opentab('add');
});
Demo:
http://jsfiddle.net/XJhN6/
See this updated fiddle.
When you want to call a function on an event triggered and the function needs to pass values, you have to do it in an "wrapper" function, like this:
jQuery(document).ready(function($) {
if ($('a[href$="#list"]').length>0){
console.log('list found');
}else{
console.log('list not found');
}
function opentab(value){
console.log('opentab: ' + value );
//perform task here
}
$(document).on('click', 'a[href="#list"]', function() {
opentab('list');
});
$(document).on('click', 'a[href="#add"]', function() {
opentab('add');
});
});
Otherwise it will be called when the event listener is set, not on the actual event.

How to bind Events on Ajax loaded Content?

I have a link, myLink, that should insert AJAX-loaded content into a div (appendedContainer) of my HTML page. The problem is that the click event I have bound with jQuery is not being executed on the newly loaded content which is inserted into the appendedContainer. The click event is bound on DOM elements that are not loaded with my AJAX function.
What do I have to change, such that the event will be bound?
My HTML:
<a class="LoadFromAjax" href="someurl">Load Ajax</a>
<div class="appendedContainer"></div>
My JavaScript:
$(".LoadFromAjax").on("click", function(event) {
event.preventDefault();
var url = $(this).attr("href"),
appendedContainer = $(".appendedContainer");
$.ajax({
url: url,
type : 'get',
complete : function( qXHR, textStatus ) {
if (textStatus === 'success') {
var data = qXHR.responseText
appendedContainer.hide();
appendedContainer.append(data);
appendedContainer.fadeIn();
}
}
});
});
$(".mylink").on("click", function(event) { alert("new link clicked!");});
The content to be loaded:
<div>some content</div>
<a class="mylink" href="otherurl">Link</a>
Use event delegation for dynamically created elements:
$(document).on("click", '.mylink', function(event) {
alert("new link clicked!");
});
This does actually work, here's an example where I appended an anchor with the class .mylink instead of data - http://jsfiddle.net/EFjzG/
If the content is appended after .on() is called, you'll need to create a delegated event on a parent element of the loaded content. This is because event handlers are bound when .on() is called (i.e. usually on page load). If the element doesn't exist when .on() is called, the event will not be bound to it!
Because events propagate up through the DOM, we can solve this by creating a delegated event on a parent element (.parent-element in the example below) that we know exists when the page loads. Here's how:
$('.parent-element').on('click', '.mylink', function(){
alert ("new link clicked!");
})
Some more reading on the subject:
https://learn.jquery.com/events/event-delegation/
http://jqfundamentals.com/chapter/events
if your question is "how to bind events on ajax loaded content" you can do like this :
$("img.lazy").lazyload({
effect : "fadeIn",
event: "scrollstop",
skip_invisible : true
}).removeClass('lazy');
// lazy load to DOMNodeInserted event
$(document).bind('DOMNodeInserted', function(e) {
$("img.lazy").lazyload({
effect : "fadeIn",
event: "scrollstop",
skip_invisible : true
}).removeClass('lazy');
});
so you don't need to place your configuration to every you ajax code
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers.
Example -
$( document ).on( events, selector, data, handler );
For those who are still looking for a solution , the best way of doing it is to bind the event on the document itself and not to bind with the event "on ready"
For e.g :
$(function ajaxform_reload() {
$(document).on("submit", ".ajax_forms", function (e) {
e.preventDefault();
var url = $(this).attr('action');
$.ajax({
type: 'post',
url: url,
data: $(this).serialize(),
success: function (data) {
// DO WHAT YOU WANT WITH THE RESPONSE
}
});
});
});
If your ajax response are containing html form inputs for instance, than this would be great:
$(document).on("change", 'input[type=radio][name=fieldLoadedFromAjax]', function(event) {
if (this.value == 'Yes') {
// do something here
} else if (this.value == 'No') {
// do something else here.
} else {
console.log('The new input field from an ajax response has this value: '+ this.value);
}
});
use jQuery.live() instead . Documentation here
e.g
$("mylink").live("click", function(event) { alert("new link clicked!");});
For ASP.NET try this:
<script type="text/javascript">
Sys.Application.add_load(function() { ... });
</script>
This appears to work on page load and on update panel load
Please find the full discussion here.
Important step for Event binding on Ajax loading content...
01. First of all unbind or off the event on selector
$(".SELECTOR").off();
02. Add event listener on document level
$(document).on("EVENT", '.SELECTOR', function(event) {
console.log("Selector event occurred");
});
Here is my preferred method:
// bind button click to function after button is AJAX loaded
$('#my_button_id').bind('click', function() {
my_function(this);
});
function my_function () {
// do stuff here on click
}
I place this code right after the AJAX call is complete.
I would add one point that was NOT obvious to me as a JS newb - typically your events would be wired within document, e.g.:
$(function() {
$("#entcont_table tr td").click(function (event) {
var pk = $(this).closest("tr").children("td").first().text();
update_contracts_details(pk);
});
}
With event delegation however you'd want:
$(function() {
// other events
}
$("#entcont_table").on("click","tr td", function (event) {
var pk = $(this).closest("tr").children("td").first().text();
update_contracts_details(pk);
});
If your event delegation is done within the document ready, you'll an error of the like:
cant assign guid on th not an boject

Appending data from a handler loaded after the script

I've made a site that displays a user's Facebook photos. The code below appends the photos to the div "facebook-images". This part works fine. The problem I have is that the images are being appended after the Javascript code below is loaded; so the handler "fb-image" is not created when the browser reads the click function code at the bottom, therefore it does not work.
I believe I need to use jQuery on(), but where? I've tried to put on() everywhere in the code below. I've tried to bind with append, I've tried live (which I know is deprecated but worth a shot). Nothing is working.
Any ideas?
<div class="target">
</div>
<div id="facebook-images">
</div>
<script>
$.when(window.deferredes.fbLoaded, window.deferredes.fbLoggedIn).then(function () {
$.getJSON('https://graph.facebook.com/me/photos?access_token=' + FB.getAccessToken(), function (data) {
$.each(data.data, function (i, face) {
$('#facebook-images').append("<div class='fb-image'><img src='" + face.source + "' ></div>");
});
});
});
$(".fb-image img").click(function () {
$(".target").append("<h1>hi</h1>");
});
</script>
The simplest way to fix this is to add the click handlers AFTER the images are inserted into the page.
<script>
$.when(window.deferredes.fbLoaded, window.deferredes.fbLoggedIn).then(function () {
$.getJSON('https://graph.facebook.com/me/photos?access_token=' + FB.getAccessToken(), function (data) {
$.each(data.data, function (i, face) {
$('#facebook-images').append("<div class='fb-image'><img src='" + face.source + "' ></div>");
});
$(".fb-image img").click(function () {
$(".target").append("<h1>hi</h1>");
});
});
});
</script>
You can also use delegated event handling if you want. To do that, you set the event handler on a common parent that does exist at the time you run the event handling code with .on() and you use the delegated form of .on() by passing it a selector like this:
<script>
$.when(window.deferredes.fbLoaded, window.deferredes.fbLoggedIn).then(function () {
$.getJSON('https://graph.facebook.com/me/photos?access_token=' + FB.getAccessToken(), function (data) {
$.each(data.data, function (i, face) {
$('#facebook-images').append("<div class='fb-image'><img src='" + face.source + "' ></div>");
});
});
});
$("#facebook-images").on('click', ".fb-image img", function () {
$(".target").append("<h1>hi</h1>");
});
</script>
The delegated form of .on() works like this:
$(selector of static parent).on(event, selector that matches dynamic object, fn);

Categories