0

So this is kinda sketchy.

DISCLAIMER: I am not a MooTools developer; pretty much never touched it.

I am attempting to fire a MooTools event.

I have a time tracking grid that I am attempting to auto-populate in AtTask using a JavaScript bookmarklet. I have it written to insert the numbers into the input elements on the page but the problem I am running into is that because I insert the values via JS the events don't fire that MooTools has scheduled so the changes aren't recognized. The result is that when I attempt to save the page no values are saved.

I have used VisualEvent to find out about the event.

Is there any way to

kalisjoshua
  • 2,306
  • 2
  • 26
  • 37
  • 2
    if your bookmarklet changes `element.value` directly, you need to let listeners know via: `element.fireEvent('change')` – Dimitar Christoff Sep 19 '13 at 06:24
  • That is what I assumed but I am having difficulty firing the event on the correct element I guess. I think the event listener is on the table and not each individual input element but I am unsure. If it is on the table would I need to fire a change event for each changed input or for all the inputs at once? – kalisjoshua Sep 19 '13 at 12:22
  • 2
    if it's on the table, it is using event delegation, so like `table.addEvent('change:relay(input,select,textarea)', fn);` - you will need to do `table.fireEvent('change', {target: element})` or something to trigger the delegation. having delegated change is dodgy for old IE where it 'normalises' it via `onPropertyChange` hacks for radios and checkboxes... post some code for the binding of events. – Dimitar Christoff Sep 19 '13 at 13:30
  • This helped me out a lot. I was actually able to get the event firing. Even though it is throwing an error everything seems to be working now. Thank you everyone for you help. I am now a step above where I was in my MooTools knowledge. – kalisjoshua Sep 19 '13 at 16:03
  • @kalisjoshua, can you post some code so you get a proper answer and it can be useful to others also? – Sergio Sep 20 '13 at 20:15
  • I'm not going to paste code into here but I will share a link to the bookmarklet I developed https://gist.github.com/kalisjoshua/90abf01fd2d04686f7c0. That is what I was working on when I asked this question. Hope it helps someone. – kalisjoshua Sep 27 '13 at 12:48
  • Now that I think about it here is the code in question really `mt_table.fireEvent('change', {target: input});` where `mt_table` is the table in the DOM and `input` is the DOM input element I am updating. – kalisjoshua Sep 27 '13 at 12:50

1 Answers1

0

So, let's say right now you have a list, and your webpage looks a bit like this:

  • One
  • Two
  • Three

You add a click event to each of the list items.

$$('.list-item').addEvent('click', function(e) {

    console.log("You clicked me!");

});

Let's bold these items so we can visualize what's going on, by bolding the ones which will respond to a click event.

  • One
  • Two
  • Three

Now, if we added a few more items, our list would look like this, since the events are not automatically attached to new elements:

  • One
  • Two
  • Three
  • Four
  • Five

This problem is solved by something called event delegation.

JavaScript events "bubble", which means they continue up through parent nodes of the event target. Since the event target is attached to the event, it then becomes possible to attach events to an outer parent element, which checks to see if the event target matches the chosen selector.

So, instead of attaching a bunch of events, one for each list item, we add a single event to the entire list, which will only fire when a list item has been clicked on.

We can do this using MooTools's event delegation syntax (admittedly not the greatest interface ever).

Let's move our event handler to be on the parent element rather than each item individually.

$('myList').addEvent('click', function() {

   console.log("You clicked somewhere on my list!");

}

Now, this will happen even when the user clicks anywhere within the parent, not just on list items. To limit what happens, we use MooTools' event delegation syntax (which is admittedly pretty strange).

$('myList').addEvent('click:relay(.item)', function() {

   console.log("You clicked on a list item!");

}

You could also use Eve.js, which is a scoped event delegation framework which runs on top of MooTools.

The code in Eve would look like this:

Eve.scope('#myList', function() {

    this.listen('click', '.item', function() {
        console.log("You clicked on a list item!");
    });

});
Michelle
  • 31
  • 2
  • I fully understand the differences between event delegation and listeners. But what you mention above `click:relay(.item)` does that mean that I would need to do something like `$$('#table').fireEvent('change:relay(.item)')` in order to fire the specific event on an element? – kalisjoshua Sep 19 '13 at 13:31