views:

356

answers:

5

On load, I add a desired behavior on all textareas on a page.

Event.observe(window, 'load', function() {
  $$('textarea').each(function(x) {
    x.observe('keydown', dosomethinghere)
  });
});

This works because the textareas are already in the DOM, but how should I treat textareas that are dynamically added after the page loads (ex: if I have a button that says "Add More"). I would like these newly created textareas to have the same behavior. Thanks.

A: 

Consider using jQuery Live.

Sinan Taifour
Unfortunately, jQuery isn't an option. This seems to work though: document.observe('click', function(e) { if (e.findElement('.fuck')) { console.log('clicked'); } });
A: 

$.live() would work as STAii mentions, but there is discussion of implementing a similar function in prototype as well. That would probably be of more benefit so you don't have to add another library.

Mark Hurd
A: 

Well, the answer is a bit tricky. The only way to do this is to maintain a cache of events listeners for your textareas. When adding a new textarea to your page, you would need to call Event.stopObserving on all your cached events. You would then call your $$('textarea').each(...) code again to bind to all the elements.

Thankfully, someone has done this for you already in a very handy lightweight prototype extension called lowpro: http://www.danwebb.net/2006/9/3/low-pro-unobtrusive-scripting-for-prototype

You can do what you wish as simply as:

Event.addBehavior({
  'textarea:keydown': function(e) {
    dosomethinghere(); // e.g. this.hide();
  }
});

Then whenever you add a new textarea dynamically, you simply call Event.addBehavior.reload();

I should point out that "e" is the Event object, and "this" is the element inside the context of the function(e) {} definition.

hobodave
+1  A: 

The way I do it is by just observing the new textarea when I add it, like this:

function doSomethingWithTextAreas(){
   //do something.
}

document.observe("dom:loaded", function() {
  $$('textarea').each(function(s){
   s.observe('keydown', doSomethingWithTextareas);
  });

 $('add_more').observe('click', function(){
   textarea = new Element('textarea');
   textarea.observe('keydown', doSomethingWithTextareas); //Observes the new textarea.
   Element.insert($('textarea_container'), {bottom:textarea});
 });

});
arbales
A: 

A nice way of doing this is to have the javascript function which adds the text areas fire an event which any other function can observe and act on. So:

function add_textarea() {
    // Code creates a new <textarea> and adds it to the page
    var textarea = new Element("textarea");
    $("some-form").insert(textarea);
    textarea.fire("textarea:add")
}

document.observe("textarea:add", function(event) {
    event.target.observe('keydown', dosomethinghere);
});

This allows your 2 functions--one that adds a new textarea and one which attaches observers--to be loosely coupled and not know anything about each other. One simply needs to fire a custom event which the other can observe.

mazelife