mootools event listener disappears after element.innerHTML is changed

1.4k Views Asked by At

I putting together a page that will display a set of stored values. I am using mootools and AJAX calls to update the values without needing to refresh the page each time the user selects a new item from the drop down menus.

the HTML each line looks something like:

<div class="selections">
<input class="checkbox selector" type="checkbox" CHECKED />

<span class="b_name">
    <select class="b_n selector">
        <!-- options -->
    </select>
</span>

<span class="b_level">

    <select class="b_l selector">
        <!-- options -->
    </select>

</span>

<span class="values">
    <!-- the values -->
</span>
</div>

In the head I have set up an event listener like:

$$('.selector').addEvent('change', function(event){changeValues(this);});

My problem is that when the "b_name" select changes I have to update the list of options in the "b_level" select. I accomplish that by getting a list of the possible options from my database through a PHP script on another page and replacing "b_level"'s innerHTML. Once I do that, the event listener attached to "b_l selector" no longer works.

I tried to resolve this issue by explicitly attaching an event listener to "b_l selector" each time "b_name" changes like so:

row.getElement('.b_l').addEvent('change', function(event){changeValues(row.getElement('.b_l'));});

where 'row' is the html element 'div.selections'.

It still isn't working and I have no idea what's going on. Can anyone offer a suggestion as to how I can get this resolved? or perhaps a better way to do what I'm doing.

3

There are 3 best solutions below

5
On BEST ANSWER

When you set innerHTML on an element, the element's contents are completely cleared and replaced with a new set of elements -- the ones parsed from the innerHTML property. Any events set on the old elements will not apply to the new ones.

jQuery provides a solution to this problem with live() events. I found a solution here that apparently achieves the same with mootools.

1
On

Your approach is correct, there's probably just a bug in your addEvent() code. The reason the event handler disappears when you replace the innerHTML is straightforward enough - you are removing the elements that the handlers are on, so the handlers are removed as well. But your approach to re-add the handler should work.

I think it's possible that it's a scoping issue. What happens if you reference the div explicitly, like this:

row.getElement('.b_l').addEvent('change', function(event){
{
  changeValues($$('div.selections .b_l'));
});
2
On

This is how JavaScript works, it's not a bug.

What you need to use is Element Delegation - you attach an event to the parent element, in the same time specifying the element that the event should be delegated to.

Here's a basic example of Element Delegation in action: http://jsfiddle.net/oskar/ENR3E/

And the documentation: http://mootools.net/docs/more/Element/Element.Delegation