views:

34

answers:

1

This might not be possible but before I rewrite part of my application I wanted to ask...

I have a JavaScript app which creates a submit <input> and observes that input's click event using Prototype's Element#observe function. For a few particular pages on one particular site which uses this app, I need to apply some additional business logic before the code which executes normally when the button is clicked.

Is there any way I can use Elemen#observe to add my new event handler before the existing event handler, so I can stop the event if these new conditions aren't met? If not I'll probably solve this the "proper" way by having the application fire a specific beforeTakingAction event and add a listener for that which prevents the application from taking it's action, but that's more complicated than this simple problem requires, and requires rewriting part of a shared application for just one user...

A: 

The first way I can think of is to unbind the events, then add all new events:

So if your element is:

<input type="submit" value="Go!" id="mySubmit" />

Maybe you would unbind the existing handler first?

$('mySubmit').stopObserving('click');

Then attach new logic there. Perhaps the existing logic is encapsulated in such a way that it can be rebound easily?

Event.observe('mySubmit', 'click', function(){
  // new logic here
  // old logic next
);

I'd be interested to know if there's a way to capture the existing events into a an object that can be reattached.


Another, sneakier way to do it might be:

  • Hide existing button
  • Add a new button with unique id right after the other button
  • that button has the new business logic attached to it
  • that button triggers the click event for the now-hidden button

You get the new functionality, the old functionality, and submit the form. In theory.


UPDATE

Another thing to watch for is there may be a submit event being observed as well - if that event also has stuff attached to it (say, for validation) then that will need to be dealt with as well.

artlung
Thanks. Not *exactly* what I was asking but close enough, I used the `stopObserving` route.
Josh
Josh, really what I find myself wishing for is a way to save the existing events into a function object, call is `priorFunction`, then add a new `Event.observe` event you craft, then call `priorFunction` in there. In the old days I would capture `element.onclick`, save it, then add it fresh. I'm not smart enough with Prototype to know there's a way to do it.
artlung
That's exactly what I'm doing -- it's called Function#wrap -- `myApplication.someAction = myApplication.someAction.wrap(function(originalFunction){ if(myBusinessLogicIsOK()) return originalFunction(); });`
Josh
http://api.prototypejs.org/language/function/prototype/wrap/
Josh