Reputation: 523
I am trying to achieve this task using MooTools.
Description:
I attached an event listener to myButton
link. A click on this link initiates an AJAX request and updates myDiv
content based on the response text.
During this request a POST variable is being sent to "button.php", but it's not used at the moment..
(i wish to use it later)
OK, as a result, myDiv
gets exactly the same link with the same ID (myButton
) + a random number, so that we could see that each click generates a new number.
The problem:
After the first click on myButton
, myDiv
updates correctly, showing a random number. When I click myButton
for the second time (this time in newly updated div), the div does not refresh anymore.
Please note that I need myButton
to be inside myDiv
, and myDiv
must be updated (refreshed) after each click without having to refresh the entire page.
Can somebody show me how to achieve this task based on this simplified code example?
index.html
<html>
<head>
<script type="text/javascript" src="mootools-1.2.4-core-nc.js"></script>
<script>
window.addEvent('domready', function() {
$('myButton').addEvent('click', function(e) {
e.stop();
var myRequest = new Request({
method: 'post',
url: 'button.php',
data: {
action : 'test'
},
onRequest: function() {
$('myDiv').innerHTML = '<img src="images/loading.gif" />';
},
onComplete: function(response) {
$('myDiv').innerHTML = response;
}
});
myRequest.send();
$('myButton').removeEvent('click');
});
});
</script>
</head>
<body>
<div id="myDiv">
<a id="myButton" href="#">Button</a>
</div>
</body>
</html>
button.php
<a id="myButton" href="#">Button</a> clicked <?php echo rand(1,100); ?>
Upvotes: 3
Views: 1341
Reputation: 141879
Look at Element.Delegation to setup the event on the myDiv
container one time, so you don't have to re-attach handlers each time the contents are updated. You need to include this MooTools-More extension in your scripts as it's not part of core yet, but will be starting from version 1.3.
$("myDiv").addEvent("click:relay(a)", function() {
...
);
If you have multiple <a>
links inside, and you only want to delegate a specific subset of those, add a class or some other property to distinguish them. You can use almost any selector inside relay(..)
. Let's say all links had a class updateTrigger
added to them:
<a class="updateTrigger" id="myButton" href="#">Button</a>
the syntax would then be:
$("myDiv").addEvent("click:relay(a.updateTrigger)", function() {
...
});
See this working example where links are replaced every 5 seconds. There is only one event setup on the myDiv
container and it handles all clicks to all <a>
s, even the dynamic ones.
Upvotes: 2
Reputation: 298938
you are attaching an event to an element that you are replacing. the dom has no way of knowing that to you, the old and the new button are identical. The old button is deleted (and the event listener with it) and the new button created. So you need to re-attach the event to the new button.
That said: why does the button have to be inside the div? The mind boggles. You can always update the button text from javascript, there's no need to replace it and keep creating new listener objects.
Upvotes: 1