Modify Dynamically Created (jQuery) Elements - javascript

I have this <li>, that when you click it, it creates another <li> before it (with a bunch of classes applied to it), which is all working great.. Problem is, I can't modify (via jQuery) the newly created <li> elements because they were created dynamically.
Currently, it is setup as:
$(".foo").on("click", function() {
//Blah blah blah
});
And I have already tried the code below instead, which still did not work.
$(".foo").on("click", function() {
//Blah blah blah
});
Thanks for your help in advance!

Since li are created dynamically for jQuery v1.7 tto attach an event handler for all elements which match the current selector, now and in the future.
$(document).on("click", ".foo", function() {
//Blah blah blah
});
Essentially if you are using 1.7 and above you're syntax is slightly incorrect for on.

Try this approach:
$("ul").on('mouseup', '.item', function() {
$(this).toggleClass("completed");
});
JS Fiddle demo.
The problem you were having is that the .item elements weren't present in the DOM at the point at which the mouseup event was bound to them. This approach binds the mouseup to the ul which does exist, and uses the on() method to listen for that event and, if the target element matches the selector (.item) passed to the method it implements the anonymous function (the third argument passed to the method).
If the target does not match that selector then the event either does nothing or contiunues to propagate through the ancestors.

Bind the event to an already present parent element:
$('#parent').on('click', '.foo', function() {
...
});
'#parent' would probably be a selector for your <ul> element.

JQuery 1.7+
I think it should work with the on() function:
$(".foo").on('click', function() {
// more code
});
Other
$(".foo").live('click', function(){
// more code
}

Does this work for you?:
$(function() {
var task =
$('<li class="editable todo-item">Double Click to Edit</li>');
$(document).on('click', '.todo-new', function() {
$('.todo-new').before(task);
});
$(document).on('dblclick', '.todo-item', function() {
$(this).toggleClass("todo-completed");
});
});

Related

dynamic <a></a> doesn't run with jquery

I want to make a web site for a photos.
Inside a dynamic div created with a jquery function (.append) there is this anchor:
<a href='#' style='color:green;' id='"+this.foto_id+"' data-id='"+this.foto_id+"' class='modificaDataFoto modificaDataFoto"+this.foto_id+"'>Modifica</a>
The page is load normally and if I use the browser debugger I see all the HTML code including all dynamic data from database...
But if I try to set a class of the anchor in a jquery function it doesn't run:
$('.modificaDataFoto').bind('click', function(event) {
event.preventDefault();
var idFotoModifica= $(this).attr("data-id");
console.log(idFotoModifica);
$("dataFoto"+idFotoModifica).focus();
$("dataFoto"+idFotoModifica).css("color", "red");
$(this).attr("class", "modificaDataFotoConferma");
});
Why does that function not work?
.bind() only works on elements that are already present in the DOM. It's likely that you're trying to bind the click event to the element before the dynamic element exists.
There are two ways to fix this:
wait until after the <a> element has been appended to the document before running your $('.modificaDataFoto').bind(), or
Delegate the click event from a non-dynamic element (or the document itself):
$(document).on('click', '.modificaDataFoto', function() {
// this is essentially the same as your existing function; I've
// consolidated it a bit and removed the no-longer-needed preventDefault.
$("dataFoto" + $(this).attr("data-id")).css("color", "red").focus();
$(this).attr("class", "modificaDataFotoConferma");
}
Use this code:
$(document).on('click', '.modificaDataFoto', function(event) {
event.preventDefault();
var idFotoModifica = $(this).attr("data-id");
console.log(idFotoModifica);
$("dataFoto"+idFotoModifica).focus();
$("dataFoto"+idFotoModifica).css("color", "red");
$(this).attr("class", "modificaDataFotoConferma");
});
I'm not entirely sure if I understood your question but if you are trying to change the element's class name then you can simply do this:
$( this ).switchClass( "old class", "modificaDataFotoConferma", 1000, "easeInOutQuad" );
instead of
$(this).attr("class", "modificaDataFotoConferma");
You also have the .toggleClass()
EDIT:
You can also use removeClass() and then use the addClass().

jQuery - .on('click' ... ) does not work on already existing elements while working on dynamically created ones

javascript:
$('body').on('click', '.deleteButton > a', function() {
alert('pop');
return false;
});
html:
<div class="deleteButton">
✖
</div>
This type of binding the click event is working well on newly created elements (via .clone and .prepend), but not working on already existing ones.
But using .click() instead of .on() is working on already existing elements while not working on newly created.
Is there any way to bind a click event both on new and already existing elements with one line?
Well you can just have a look at the fiddle JsFiddle
$('body').on('click', '.deleteButton > a', function () {});
What you need to do is to attach the event to the body instead of the classes or id's. Doing this will bind your event to the body and in return all the body elements will automatically bind to this event.
Your code is working fine. But still you can try this one. It also worked.
$('.deleteButton > a').on('click', function () {
alert('pop');
return false;
});
Use
$(document).ready(function(){
$('body').on('click', '.deleteButton > a', function() {
alert('pop');
return false;
});
});
Hope this will help you.
check this jsFiddle

jQuery event delegation with .on (this reference)

Where does this reference to in a delegated .on event?
Example:
$('#foo').on('click', $('.bar'), function() {
console.log(this);
});
In the example this will reference to #foo. But how do i access the bar element that got clicked? I might have 5 bar elements and I want to know which one was clicked.
Thanks
Edit:
Sorry i changed #bar to .bar (since it exists multiple times).
The answer that i should just use '.bar' helped. But what if i have selector like this:
$('.bar').find('a');
How would i incorporate something like this?
This won't work: (cause this will reference to #foo)
$('#foo').on('click', $('.bar').find('a'), function() {
console.log(this);
});
Change it to this...
$('#foo').on('click', '.bar', function() {
console.log(this);
});
Now this will be the clicked .bar.
If you want a jQuery object then use $(this) as normal.
Edit
As per the change to question code, you'll need this...
$('#foo').on('click', '.bar a'), function() {
console.log(this);
});
That simply extends the click event handler to links inside .bar elements that may not exist at document.ready.
Two ways.
Use a string selector, not a jQuery object, when calling .on():
$('#foo').on('click', '#bar', function() {
console.log(this); // #bar
});
Specify a parameter name for the jQuery normalised event object, and use its target property:
$('#foo').on('click', $('#bar'), function(e) {
console.log(this); // #foo
console.log(e.target); // #bar
});
EDIT: Ignore the second option. jQuery doesn't accept a jQuery object for the selector, and as a result simply ignores it. You will not be setting up event delegation, you'd instead just be setting a static click event handler on #foo, which works due to event propagation.
An ID should be used once in a page. So you can add a class fooClass to your 5 elements and do :
$('.fooClass').onclick(function() {
alert("my bar element: " + $(this));
});
and do what you want with $(this).

jQuery 1.7+ on(click..) doesn't work on <li> added dynamically

I have a dialog with a
<ul id="suggestions0">
<li id="suggestion0-0" class="suggestion">BLO</li>
<li id="suggestion0-1" class="suggestion">BLU</li>
<li id="suggestion0-2" class="suggestion">BLL</li>
<li id="suggestion0-3" class="suggestion">BOO</li>
<li id="suggestion0-4" class="suggestion">CLA</li>
</ul>
that I want to replace the content dynamically.
I change to ul content with this
$("#suggestions0").html("<li id='test0-1' class='suggestion'>BLO</li><li id='test0-2' class='suggestion'>BLO</li><li id='test0-3' class='suggestion'>BLO</li><li id='test0-4' class='suggestion'>BLO</li><li id='test0-5' class='suggestion'>BLO</li><li id='test0-6' class='suggestion'>BLO</li>");
What I want is when I click on one of these word, I want to do something, suppose an alert.
I try to do this
$(".suggestion").on("click", function() {
alert(this.id);
});
but the alert never appear.
here a sample that show the problem
http://jsfiddle.net/survivant/cyFxp/1/
in the sample, if you click on OK, it doesn't change to content, so if you click on a LI, it will works, but if you click on NOTOK, the events won't be received.
I'm using jQuery 1.7+, the live api is deprecated, or removed, it the APi suggest to use on().
You are not using on correctly. live is used to bind event handlers to the document to listen for events that bubble up from a specific selector, but by calling on explicitly on .suggestion, you will only attach the listeners to existing suggestions. So you need to use on to bind on an element that will always exist, and pass a selector to pick out the elements that get created dynamically.
// With live like this:
$('.suggestion').live('click', ...
// Is equivalent to this:
$(document).on('click', '.suggestion', ...
// Not this:
$('.suggestion').on('click', ...
In your case, rather than basing on off document, you can use your ul.
$("#suggestions0").on('click', '.suggestion', function(){
alert(this.id);
});
I found a solution, not sure that is the best one, but seems to work.
$("#suggestions").on("click","li", function() {
alert(this.id);
});
The script below only bind click event to DOMs current exist in the page.
$(".suggestion").on("click", function() {
alert(this.id);
});
To bind click event to all DOMs that are and will be created in the page. Bind the event to the document instead.
$(document).on("click", ".suggestion", function() {
alert(this.id);
});
See fiddler for codes.
Pass a selector to on() and it works like the old live():
$("#suggestions0").on("click", ".suggestion", function () { alert(this.id); });
See updated fiddle: http://jsfiddle.net/cyFxp/2/
suggestions is not a class but an id thus
it should not be
$(".suggestion").on("click", function() {
alert(this.id);
});
But like this
$("#suggestion").on("click", function() {
alert(this.id);
});
That is, instead of a dot you prefix it with a pound sign #.

jQuery: Any way to "refresh" event handlers?

I have two divs, one that holds some stuff and the other with all possible stuff. Clicking on one of the divs will transfer items to the other div. The code I came up with is:
$("#holder > *").each(function() {
$(this).click(function(e) {
$(this).remove();
$("#bucket").append(this);
});
});
$("#bucket > *").each(function() {
$(this).click(function(e) {
$(this).remove();
$("#holder").append(this);
});
});
This one works perfectly, except that the event handlers need to be refreshed once I append or remove elements. What I mean is, if I first click on an element, it gets added to the other div, but if I click on this element again, nothing happens. I can do this manually but is there a better way to achieve this?
Try jquery live events .. the $.live(eventname, function) will bind to any current elements that match as well as elements added to the Dom in the future by javascript manipulation.
example:
$("#holder > *").live("click", function(e) {
$(this).remove();
$("#bucket").append(this);
});
$("#bucket > *").live("click", function(e) {
$(this).remove();
$("#holder").append(this);
});
Important:
Note that $.live has since been stripped from jQuery (1.9 onwards) and that you should instead use $.on.
I suggest that you refer to this answer for an updated example.
First, live is deprecated. Second, refreshing isn't what you want. You just need to attach the click handler to the right source, in this case: the document.
When you do
$(document).on('click', <id or class of element>, <function>);
the click handler is attached to the document. When the page is loaded, the click handler is attached to a specific instance of an element. When the page is reloaded, that specific instance is gone so the handler isn't going to register any clicks. But the page remains so attach the click handler to the document. Simple and easy.
Here you go, using the more intuitive delegate API:
var holder = $('#holder'),
bucket = $('#bucket');
holder.delegate('*', 'click', function(e) {
$(this).remove();
bucket.append(this);
});
bucket.delegate('*', 'click', function(e) {
$(this).remove();
holder.append(this);
});
EDIT: don't use live, it be deprecated!
Take advantage of the fact that events bubble. Using .on():
var = function( el1, el2 ) {
var things = $('#holder, #bucket');
things.each(function( index ) {
// for every click on or in this element
things.eq(index).on('click', '> *', function() {
// append will remove the element
// Number( !0 ) => 1, Number( !1 ) => 0
things.eq( Number(!index) ).append( this );
});
});
any click on any element (existing at the time of bind or not) will bubble up (assuming you haven't manually captured the event and stopped propagation). Thus, you can use that event delegation to bind only two events, one on each container. Every click that passed the selector test of the 2nd argument (in this case, > *, will remove that element and then append it to the alternate container as accesesed by things.eq( Number(!index) )
Have you looked at jQuery's live function?
The most Efficient way (dont load all event for all elements) it:
//NORMAL FUNCTION
function myfunction_click(){
//custom action
}
$('id_or_class_of_element').on('click', myfunction_click);
//LOAD OR REFRESH EVENT
$(document).on('click', 'id_or_class_of_element', myfunction_click);

Categories