views:

206

answers:

2

Hi,

I've been scratching my head over this for an hour... I have a list of todo which has done button on each item. Every time a user clicks on that, it's supposed to do an Ajax call to the server, calling the marking function then updates the whole list.

The problem I'm facing is that the new list has done buttons as well on each item. And it doesn't attach the click event anymore after first update.

How do you attach an event handler on newly updated element with prototype?

Note: I've passed evalScripts: true to the updater wrapper

initial event handler attach

<script type="text/javascript">
 document.observe('dom:loaded', function() {

  $$('.todo-done a').each(function(a) {
   $(a).observe('click', function(e) {
    var todoId = $(this).readAttribute('href').substr(1);
    new Ajax.Updater('todo-list', $.utils.getPath('/todos/ajax_mark/done'), {
     onComplete: function() {
      $.utils.updateList({evalScripts: true});
     }
    });
   });
  })
 });
</script>

updateList:

<script type="text/javascript">
 var Utils = Class.create({
  updateList: function(options) {
   if(typeof options == 'undefined') {
    options = {};
   }

    new Ajax.Updater('todo-list', $.utils.getPath('/todos/ajax_get'), $H(options).merge({
      onComplete: function() {
       $first = $('todo-list').down();
       $first.hide();
      Effect.Appear($first, {duration: 0.7});
      new Effect.Pulsate($('todo-list').down(), {pulses: 1, duration: 0.4, queue: 'end'});
     }
     })
    );     
  }
 })

 $.utils = new Utils('globals');
</script>

any help is very much appreciated, thank you :)

A: 

it may be worth trying to initially unregister your click handlers like this:

$$('.todo-done a').each(function(a) {
   $(a).stopObserving('click);
});

either way you would need to add your new event handler within your oncomplete but this should only be necessary for new dom elements.

Remember as always that Firebug and console.log() are your friend :)

seengee
hmm ok, I'd try reenabling the events. Is there something like jQuery's livequery in prototype?
andreas
A: 

You can use behaviors low-pro at github
Some documentation at http://www.danwebb.net/2006/9/3/low-pro-unobtrusive-scripting-for-prototype

so the code would look something like:

Event.addBehavior({
  '.todo-done a:click' : function(e) {
     var todoId = $(this).readAttribute('href').substr(1);
     new Ajax.Updater('todo-list', $.utils.getPath('/todos/ajax_mark/done'), {
      onComplete: function() {
        $.utils.updateList({evalScripts: true});
      }
     });
   });
});