Dynamically created anchor links not receiving 'click' events? - javascript

I'm using JS to create the HTML below. (It's a bootstrap dropdown button)
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle my-status" data-toggle="dropdown">
Status <span class="caret"></span>
</button>
<ul class="dropdown-menu status-menu" role="menu">
<li>None</li>
</ul>
</div>
And in JQuery I'm trying to process clicks on the link inside there.
$('li').on('click', 'a.status', function(e) {
e.preventDefault();
alert("hi");
});
I've tried about 6 different ways to select those links, but nothing I do seems to be catching it.
Since they're created dynamically, I know I need to use the 'on' function, but it just doesn't seem to be working in the least.
I can get it to work in a JSFiddle, but the code there isn't created dynamically - which is the issue I think.
Is there something stupidly obvious that I'm missing here?

If that whole chunk of HTML is dynamic, then you need to target the container that HTML is appended to and use on
$(containerOfAppendedContent).on("click", ".btn-group li a", function() {

Assuming the entire block of code you posted is created dynamically, or even just the list, when you bind events to dynamically added elements, you need to bind to elements that are already in the DOM when the code is executed. Try:
$(document).on('click', 'a.status', function(e) {
e.preventDefault();
alert("hi");
});
$(document) is a worst case scenario, so if you have an element closer to the ones being added dynamically that exists when the jQuery is executed, use that over document.

Make sure you are selecting a static parent, so if li is dynamically created too, use its parent or its parent's parent
$('div.btn-group').on('click', 'ul li a.status', function(e) {
e.preventDefault();
alert("hi");
});
if that div is also dynamically created you could go up to the body or even document
$(document).on('click', 'ul li a.status', function(e) {
e.preventDefault();
alert("hi");
});

Why don't you generate the ancor tag with a onclick function?
<li>None</li>
<script>
function DoSomething(){
// Do your work
}
</script>
Hope this helps

Use this
change li to document
$(document).on('click', 'a.status', function(e) {
e.preventDefault();
alert("hi");
});

Related

Trying to write a function from inline javascript

I've got some code from a developer that left our company. He wrote an inline function looking like this:
<button class="xxx" id="MyID" type="button" onclick="javascript: $('#openThis').slideToggle('slow');">btnText</button>
I've tried to remove this and put it in another function to write a callback so I can scroll to the toggled area when it's visible.
$("#MyID").click(function () {
$("#openThis").slideToggle("slow");
});
But I can't seem to get it to work. What am I doing wrong?
are you adding the listener before or after the object is created on the DOM?
because if you are trying to bind that onclick function without waiting the document to be ready theres no object to create the listener.
something like this could work:
$(document).on('ready', function() {
$("#MyID").click(function () {
$("#openThis").slideToggle("slow");
});
});
If you button is added dynamically then use on instead of click
Attach an event handler function for one or more events to the
selected elements.
Event handlers are bound only to the currently selected elements; they
must exist at the time your code makes the call to .on()
//Instead of document you can use a container id
$(document).on('click',"#MyID",function () {
$("#openThis").slideToggle("slow");
});
What this approach does is it adds event to a currently selected element which is document here and it will delegate the event to your selector which is #MyID in this case.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
$(document).on('click', '#myBtn', function(){
$('#foo').slideToggle('slow');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div id="foo">content</div>
<button id="myBtn">Click me</button>
You want to scroll to the area so remove the JavaScript from the button
You need to do something like this
$("#MyID").click(function() {
$('html, body').animate({
scrollTop: $("#openThis").offset().top
}, 2000);
$("#openThis").slideToggle("slow");
});
You should delete the onclick="" attributes in the button tag and in your javascript :
$("#MyID").click(function (e) {
e.preventDefault();
$("#openThis").slideToggle("slow");
});
Use the prevent default.
Hope that help

Elements appeneded not triggering events

I have a list
<ul id="list">
<li> element one <span class="remover">X</span></li>
<li> element two <span class="remover">X</span></li>
</ul>
and this list is dynamically appended with
<input type="text" id="adder">
<button id="add">Add</button>
<script>
$("#add").click(function(){
$("#list").append('<li>'+$("#adder").val()+' <span class="remover">X</span></li>');
});
</script>
but the problem is this with part
<script>
$(".remover").click(function(){
$(this).parent().remove();
});
</script>
The remove works perfectly with the static added items, but when it comes to the new appended items nothing happens on click, doesn't even trigger the function
I'd suggest:
$('#list').on('click', '.remover', function(e){
$(this).parent().remove();
});
JS Fiddle demo.
References:
on().
parent().
remove().
Call the click function on list and set remover as target like so:
$( '#list' ).on( 'click', '.remover', function (e) {
$(e.target).parent().remove();
});
You can't set a click event directly on it, it has to be set on the element that never is added to the page.
you should use
on('click',function(){})
not
.click()
refer to : http://api.jquery.com/on/
as click will relate to current item within document , while on is related to future items that will be added to document , however you should always use on with something that already exists in your document like for example the parent of the future added element so use something like
$("#parent").children("li").children('.remover').on("click",function(){bla bla bla;});

.click function not working when the event is called by element created by another function

I have this function that create an element
function AddPayment(ID)
{
showForm = $('#AddPaymentForm').html();
$('#divAJAX_'+ID).html(showForm);
$(".cancel").click(function(){ AddPayment(ID); });
}
Coming from this
<div id='AddPaymentForm'>
<span class='button' id='cancel' class='cancel' >Cancel</span>
</div>
I wanted that function to place the element in here
<div id='divAJAX_ID'></div>
I also wanted that function to create an onclick function on my span, but it isn't working.
I guess the problem is coming from placing the
$(".cancel").click(function(){ AddPayment(ID); });
at the wrong placement. I've tried all the possible place but I can't still work this right.
What's wrong?
You have two class attributes on the same element. It should be something like:
class="button cancel"
instead of
class="button" id="whatever" class="cancel"
It is probably causing trouble to jQuery.
See how it start working on this fiddle: http://jsfiddle.net/pvNrg/2/
First, your question as the html:
<div id='AddPaymentForm'>
<p>Coming from this</p>
</div>
<span id='cancel' class='cancel'>Cancel</span>
<p>I wanted that function to place the element in here</p>
<div id='divAJAX_ID'></div>
<p>I also wanted that function to create an onclick function on my span, but it isn't working. I guess the problem is coming from placing the ... at the wrong placement. I've tried all the possible place but I can't still work this right.</p>
<p>What's wrong?</p>
And the javascript:
$(function () {
function AddPayment(ID) {
showForm = $('#AddPaymentForm').html();
$('#divAJAX_' + ID).html(showForm);
}
$(".cancel").click(function () {
AddPayment('ID');
});
});
For dynamically created elements ,You have to do event delegation
$(document).on("click", ".cancel" , function(event){
alert($(this).text());
});
Use this code
function AddPayment(ID)
{
var showForm = $('#AddPaymentForm').html();
var container = $('#divAJAX_'+ID);
container.html(showForm);
container.find(".cancel").click(function(){ AddPayment(ID); });
}
$("#AddPaymentForm,[id^=divAJAX_]").on("click", ".cancel" , function(event){
alert($(this).text());
});
Attach the delegated event handlers only the list of containers you need to monitor (not the document) if you need to save performance (you don't need to monitor all the .cancel). With this approach, the event does not have to bubble up more levels. If you have anther element that is parent of AddPaymentForm and all divAJAX_. You could write like this:
$("#anotherContainer").on("click", ".cancel" , function(event){
alert($(this).text());
});

How to change a hidden value and the text of the

I am currently attempting to make a dropdown menu where selecting one of the links from the menu will change the hidden value as well as the text of the hyperlink. This is based upon Twitter's Bootstrap dropdown, and uses jQuery:
<div id="periodChooser" class="btn-group">
<input type="hidden" value="1" name="dtype" id="dtype1"></input>
<a data-toggle="dropdown" href="javascript:;">Weekend</a>
<ul class="dropdown-menu">
<li>Weekend</li>
<li>Week</li>
<li>Midweek</li>
</ul>
</div>
The script that I have attempted to write is as follows:
<script>
jQuery(function($){
$('#periodChooser').each(function() {
$('.dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
});
});
</script>
Unfortunately, whilst it doesn't return any specific error, the code does not work. Any suggestions?
Bind event out side each
<script>
$('#periodChooser .dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
</script>
I think that this can be optimized and made more re-usable.
First of all, you are using jQuery selectors like $('.btn-group') very ineffectively.
Secondly it will break, if you will use more than one "widget", because the context is whole document and it will find all elements with that class .btn-group.
Thirdly it would be more effective to use single event handler that is being binded to the parent <ul> element instead of each <a> element. It's called "event delegation". http://api.jquery.com/delegate/
<script>
$('#periodChooser').each(function() {
var $input = $('input', this),
$select = $('>a', this);
$('ul', this).on('click', 'a', function() {
var $this = $(this);
$input.val($this.data('value')).change();
$select.html($this.html());
});
});
</script>
I made this code available in JSBin: http://jsbin.com/welcome/38724/edit
What I did here?
<script>
$('#periodChooser').each(function() {
// Find and store input and "select" element only once.
var $input = $('input', this),
$select = $('>a', this); // This finds only direct child element <a>
// Find the <ul> element inside the #periodChooser
// Bind a click event that will "bubble up" from <a> elements that are children of it
$('ul', this).on('click', 'a', function() {
// Wrap a jQuery around the <a> element
var $this = $(this);
// Set the input value and execute "change" event(s)
$input.val($this.data('value')).change();
// Change the "select" title. Doesn't matter if you use html() or text() - choose yourself!
$select.html($this.html());
});
});
</script>
Now, you can use this to make multiple widgets inside single page! :)
<script>
$('.btn-group').each( /* Well, you know, the function goes here... */ );
</script>
Of course, threre are many other things that has to be done here, like opening and closing the "option list", scrolling and probably many other things...

Identical JQuery function is working for one link, not another

I have the function:
<script type="text/javascript">
$(function() {
$('#subbutton').click(function() {
$('#subbutton').hide();
});
});
</script>
It simply makes this button hide when clicked:
<a id="subbutton" class="button" href="javascript:TINY.box.show({url: 'follow',width:600,height:170,openjs:'initPopupLogin',opacity:30})"><span>Button</span></a>
Now, if i try to use the identical function, but with a link later on the page, it doesnt work (i have erased the original button at this point) Here is the code:
<div id="subbutton">
<span>Button</span>
</div>
I have tried putting the id in the anchor and in the span, nothing seems to be working for this link. Any idea why this isn't working? (I have deleted the original button so that this second button is a unique id on the page)
Try using .on instead to attach your event handler. I am suspecting the button is not in the dom at the time you attach the event handler.
$(document).on('click', '#subbutton', function() {
$(this).hide();
});
EDIT now that i understand the problem. You are better off giving the buttons a class and using a class selector.
.hide doesn't remove the element from the page so your selector will still be matching on the first element. You need to use .remove to remove the first element from the DOM so the second selector can work.
Also, little jQuery optimization. The nested call to $('#subbutton') is not needed. At best, it is harder to maintain, at worst, it could cause performance issues if you put this in a large loop. This is better.
$(function() {
$('#subbutton').click(function() {
$(this).remove();
});
});
You are missing a " after this:
<a id="subbutton" class="button
and Id has to be unique. Then it should work.
Don't reuse ids, they must be unique. pass the id to the function
Change your javascript to:
$(function() {
$('#subbutton').live("click",function() {
$(this).hide();
});
});​
http://jsfiddle.net/W2agx/
also don't reuse id's. use a class for multiple DOM elements that you want to be able to select together.

Categories

Resources