0

I tried it like this:

Event.observe('.add_select_row', 'click', function() {
    console.log("KLICK!");
});

But I get "Uncaught TypeError: Cannot read property 'get' of undefined"

I also tried:

Event.observe('add_select_row', 'click', function() {
    console.log("KLICK!");
});

... and ...

Event.observe($('.add_select_row'), 'click', function() {
    console.log("KLICK!");
});

enter image description here

http://api.prototypejs.org/dom/Event/observe/

2
  • By the documentation you provide, it seems that the first parameter should be a DOM element or a string with the id of the DOM element. But it seems you are trying to call the observe method with a jQuery object or with a string that is the class of a DOM element. Commented Apr 12, 2019 at 16:44
  • No this is not jQuery, it is prototypejs, which looks quite similar to jQuery Commented Apr 12, 2019 at 17:42

1 Answer 1

3

Event.observe requires a DOM element or an id of a DOM element in order to work. If you want to bind a click event listener to a collection of one or more elements sharing the same classname, then you need to construct your listener differently, or bind a unique listener to each element sharing that classname.

The simplest way to do what you're describing here would be to add an ID to the element you want to listen to. If you can't do that, then you could rewrite your listener so that it responds at a different level:

$(document).observe('click', '.add_select_row', function(evt, elm){
  // evt is now bound to the click event, so you could keep it from bubbling:
  evt.stop();
  // elm is now bound to the element with the classname add_select_row
  // that triggered the click, so you can do something with that
  elm.addClassName('clicked');
  console.log('CLICK');
});

This pattern is known as a "lazy observer", which takes advantage of the fact that click events bubble up and are eventually caught by the document itself. You're not limited to using the document for this, either. You could also set this sort of observer on any parent element of the button, for example:

$('foo').on('click', '.add_select_row', function(evt, elm){});

if you had a div#foo at some ancestor level to that button.

The benefit to this pattern is that you don't end up with a separate observer bound to each element in your page that shares that classname. One observer will work for any number of observable elements, as long as you want each one to do the same thing.

If you really wanted to have a separate observer for each button, you could give each one an unique ID. If that wasn't practical, you could do this (but don't -- it's wasteful to create observers for multiple elements when you're only interested in one):

$$('.add_select_row').each(function(elm){
  elm.observe('click', function(evt){
    console.log('CLICK');
  });
});

The "double-dollar" method in Prototype allows you to use classnames or any other CSS selector to identify a collection of elements on the page. Even if there is only one returned matching element on the page, it always returns an array containing that element. This is similar to how jQuery sees the DOM, and in Prototype 1.7 and up, uses the same Sizzle CSS selector library to select elements.

Sign up to request clarification or add additional context in comments.

2 Comments

Thx! The problem is that the button is created dynamically during runtime, I think your first example will work. I have to test this out on monday.
Thanks, Geek Num 88 for the speedy fix to my example! I'm so spoiled by TextMate that it's easy to forget that pairs aren't automagically balanced as I type here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.