I'm using agile toolkit, a framework that generates javascript code from PHP. I have a div element (I'll call it "top-element") that contains some other div elements, some buttons.
I want to move the "top-element" to another element, to change it's parent.
I tried something like:
$('#top-element').appendTo($('#new-parent'));
But the problem is that the "top-element" have some childrens that have click events, some buttons. After I append the "top-element" to a new element (after changing it's parent), the click events are triggered twice.
I tried to clone the element and append the cloned element to the new parent:
var cloned_top_element = $('#top-element').clone(true);
cloned_top_element.appendTo($('#new-parent'));
I got the same problem, the click event on "top-element" childrens was called twice.
The way to prevent double click is to use:
unbind('click') or off('click')
I tried something like:
$('#new-parent').find('.children-class').unbind('dblclick').unbind('click');
But still no results.
The binding for child buttons is like this:
$('.children-class').bind('click',function(ev){ ev.preventDefault();ev.stopPropagation(); other stuff });
The bind function appears only once. There aren't duplicates in the js code.
Any ideas? Anticipated thanks.
Remove the true in the clone function .clone(); this will not copy the event handlers
Related
I have an element in my DOM with two children, a div block and a button. When I click the button, I want to add a new copy of the same div block to the parentNode. Is this possible? What I have in the button onclick call now is:
document.getElementById("myele").appendChild(document.getElementById("myele").children[0])
But this just moves that child in the children array under the button, and if I click again moves the button back under the div block (this because now children[0] is the button itself). I've also tried to assign the child Node to a variable and append that instead, but the result is the same.
Is there a way to do what I'm trying to do without having to call a JS function that recreates the whole div block and then appends it?
EDIT: Having never used jQuery, I also tried to do this, but it doesn't seem to work:
<script>
function addOne(){
console.log('click')
$('.valori:first-child').clone(true).appendTo($('.valori'))
}
</script>
and the onclick call became:
javascript: addOne()
The console logs 'click', but no changes in the page.
Assuming I've understood you right, cloneNode may be what you are looking for.
You could clone your element and then append the clone to your parent node.
https://developer.mozilla.org/en/docs/Web/API/Node/cloneNode
I have some javascript that successfully clones a template and appends the resulting html to a div. However when I try to reference an element of the clone it is not accessible, even though if I place the exact same element with the exact same ID (confirmed with Firebug) outside the template (and the cloning system) it is accessible. I believe I need to do an update of some kind after cloning but I am not sure. The code I am trying to use to access the (cloned) element (does not log anything to console and is not working) is:
$("#depminusbutton0").on("click", function () {
console.log('I triggered minus 0');
});
And depminusbutton0 shows up like this in firebug inspect element once cloned (doesn't exist prior to cloning, as ID 0 is inserted dynamically:
<a id="depminusbutton0">
Any ideas how I can make this element accessible?
Two possibilities I can think of:
You are installing the event handler before the element exists so it can't find the element to attach the event handler to?
You have a conflicting ID elsewhere in the document.
If you're going to use this form of event handling:
$("#depminusbutton0").on("click", fn);
Then, the #depminusbutton0 element must exist at the time you run that line of code. It will search the DOM for that element at the time you run the code and will not hook up to an element that matches that ID that you create in the future.
You can work around that issue, either by running that line of code AFTER you create the #depminusbutton0 element and insert it in the DOM or you can switch to use delegated event handling which attaches the event handler to a common parent that does exist before you've created the child element.
To see more about how delegated event handling works, see these references:
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
The general idea would be like this:
$(some parent selector).on("click", "#depminusbutton0", fn);
If you have multiple elements with the #depminusbutton0 id, then you will have to fix that and only have one element with that id. Often times with clones, you want to use a class name rather than an id since you can have multiple elements with the same class name.
Are you attaching the event to an element that doesn't exist yet? As described in the jQuery documentation:
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().
Just make sure you are attaching the event to the cloned element after you create it.
$(document).on('click', '.class-or-id-name', function() {
console.log("Heyyy its clickable");
// do more stuff
});
Here is the fiddle.
Ignore the styling, that's not important.
Basically I needed to open the Fancybox with two links present, but I only want one gallery image. I figured that out easily enough. When the thumbnail is clicked it triggers the li anchor.
To keep the galleries separate I did unique classes for each ol.
The problem I have run into is I will be repeating myself.
I attempted to do a loop (commented out), but the logic is beyond my grasp.
What is the best way to attach a new click handler (I need to add 8 more) without repeating myself in my current fashion? I've also tried a function with a couple parameters, but I had trouble with the e.preventDefault().
I greatly appreciate any guidance, thanks!
This looks like a great use case to use jQuery's on() method. on() is a method that will allow you to establish a handler on an outer container that can listen to its children for click events. So, for example: if you specified a class of .js-listen on your lists, you could call on() like this:
$('.js-listen').on('click', 'other-selector', function(e){
// function logic with either $(this) or e.target goes here
}
This block would essentially look for all elements with .js-listen and then when something inside the element with the .js-listen class is clicked, the event will bubble up through the DOM and the event will be handled according to the element that was clicked. The second parameter I have 'other-selector' can be a class name, element, or ID. so you could essentially put something like img there and it would fire the event if the child element clicked was an <img> tag.
This prevents you from attaching a handler a million times, and one of the benefits of on() is that if elements are dynamically added to the container with the handler, you don't have to worry about attaching handlers to those elements, because again, they bubble up!
Hope this helps!
I have a form that I am trying to alter with jQuery. Basically, my form has two elements and I need to change the value of the first option in each of them. However, there is an "add more" option that uses AJAX to dynamically generate another element that also needs changed. This add more button can be clicked an unlimited amount of times.
Right now I have this:
$(document).ready(function(){
$("#myname-0-field option:first").val("None");
$("#myname-1-field option:first").val("None");
});
This works fine, but once the "add more" button is clicked, I have more elements called "#myname-2-field", "#myname-3-field", "#myname-4-field" etc. These obviously aren't affected by adding another line into my jQuery as the document has already loaded when they are added.
So the real question is, can someone point me in the right direction of writing a function that can react when the new element is added and change it. If possible, I'm also looking for the function to be aware and look for "#myname-X-field option:first" for tidyness.
use live() function
Then using each function set value
From the jQuery API look live function
Maybe you could add class to your element, so that finding particular element would be easier and it would not add event to other similar elements.
In the example I have a Li with class
$('li.myClass').live('click', function() {
$(this).val(); // this is the getter for clicked value
$(this).val("some_value_here"); // this is the setter for clicked value
});
Now you can add more elements (that has myClass class) and it will have a click event.
Btw. if you know that all elements are inside some container (div for example) then you can write more efficient jQuery using delegate.
$('#container_id').delegate('li.myClass', 'click', function () {
});
This is more efficient because it looks your new elements only under "containter" not from the whole DOM structure.
I have created a dynamic list picker script using Jquery 1.3 and PHP that sends a JSON AJAX request and returns a list of items to choose from. The AJAX call works perfectly returning an array of items that I use Jquery to append them as an unordered list to an empty container DIV. That portion of the process works as expected.
The problem comes from the fact that from that list of items, I'm drawing them as links whose clicks are handled by a rel attribute. Here's an example:
<a rel="itemPick" id="5|2" href="#">This is the link</a>
The JQUERY handler looks like:
$('a[rel=itemPick]').click(function () {
code here...
});
These links and click handlers work fine when the page loads, but when they are appended to the container DIV, the click event does not get picked up. I don't want to have to refresh the entire HTML page again, so is there something I need to do in addition to append() to get JQUERY to recognize the newly added links?
When you use the jQuery.click method, it's looking for all of the "a" elements that currently exist on the page. Then, when you add a new "a" element, it has no knowledge of that click event handler.
So, there's a new event model in jQuery that allows you to bind functions to all current and future elements called Live Events. You can use Live Events the same way that you use normal event binding, but they will work for all future elements specified. So, you can simply switch your binding logic to:
$('a[rel=itemPick]').live('click', function () {
//code here...
})
$('a[rel=itemPick]').live("click", function (){ code here... });
Do you bind the event after adding the links?