>
> That's not bind(), that's Event.observe().  bind() is general-purpose,
> knows nothing about events.


D'oh! That's an obvious blunder in my reply. Thanks :)


Ryan Gahl
CEO
Nth Penguin, LLC
http://www.nthpenguin.com
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl


On Fri, Apr 10, 2009 at 10:30 AM, T.J. Crowder <[email protected]>wrote:

>
> Hey Ryan,
>
> Thanks.  It was too long, though, really.
>
> > FWIW, I know bindAsEventListener isn't actually legacy...
>
> Yeah, I was thinking about that, and since one of its two main reasons
> for being is DOM0-style handlers, "legacy" isn't necessarily the wrong
> word... :-)
>
> BTW, meant to mention:
>
> > Note, I believe .bind() automagically passes the event object along to
> the
> > bound function these days...
>
> That's not bind(), that's Event.observe().  bind() is general-purpose,
> knows nothing about events.  If you're using a DOM0 handler, bind()
> won't help you out with IE's window.event thing.  bindAsEventHandler()
> will (it ensures that the first argument is the event object [even on
> IE] -- an unextended event object, but an event object).  But why
> would you use a DOM0 handler? ;-)
>
> -- T.J. :-)
>
> On Apr 10, 3:00 pm, Ryan Gahl <[email protected]> wrote:
> > Thanks for jumping in TJ, great response!
> >
> > FWIW, I know bindAsEventListener isn't actually legacy - I guess I was
> just
> > being a bit lazy in my response and was sort of just implying that it
> > probably wasn't needed (I have never had to use it).
> >
> > You certainly have a knack for the more detailed replies :)
> >
> > Ryan Gahl
> > CEO
> > Nth Penguin, LLChttp://www.nthpenguin.com
> > --
> > Inquire: 1-920-574-2218
> > Blog:http://www.someElement.com
> > LinkedIn Profile:http://www.linkedin.com/in/ryangahl
> >
> > On Fri, Apr 10, 2009 at 5:39 AM, T.J. Crowder <[email protected]
> >wrote:
> >
> >
> >
> > > Hi,
> >
> > > >         this.MSOFindForm.getInputs('text').each(function(input) {
> > > >             Event.observe(input, 'keyup',
> this.Find.bindAsEventListener
> > > > (this));
> > > >         });
> > > > The above is part of the initialize event for the class MSOFindForm.
> >
> > > A few things that may help:
> >
> > > bindAsEventListener()
> > > ---------------------
> > > It's _extremely_ rare to need to use bindAsEventListener(), and you
> > > don't need to in this case.  You just need bind(), because you're not
> > > burning in (currying) any other arguments in your event handler that
> > > need to follow the event object.  It's not a legacy form of bind() as
> > > Ryan suggested earlier, it's a highly specific solution to a highly
> > > specific problem you don't have in this code. :-)
> >
> > > So to start with, use bind() instead of bindAsEventListener() in the
> > > code above.  But that won't solve the "Find" problem...
> >
> > > each()
> > > ------
> > > Remember that Enumerable#each() calls the iterator function you
> > > provide.  The act of calling a function sets the "context" of that
> > > function, including what "this" means.  Unless you do something
> > > specific to set the context, within a function "this" will default to
> > > the global object, which is "window" in browser implementations.  So
> > > no matter what "this" means outside an each() loop, unless you do
> > > something on purpose, this === window within the loop.
> >
> > > So in this code:
> >
> > >    this.MSOFindForm.getInputs('text').each(function(input) {
> > >         Event.observe(input, 'keyup', this.Find.bind(this));
> > >    });
> >
> > > it doesn't matter what "this" means outside the iterator function,
> > > *inside* the iterator, this === window.
> >
> > > Now, you can _tell_ each() what context it should use when calling the
> > > iterator function, which would fix that problem and probably make that
> > > code work; see the docs[1].  But wait, there's more we can do...
> >
> > > [1]http://prototypejs.org/api/enumerable/each
> >
> > > Bind once, use many
> > > -------------------
> > > That code is doing something else you probably want to fix:  It's
> > > creating a whole lot more functions than it has to.  On every loop,
> > > it's doing this:
> >
> > >    Event.observe(input, 'keyup', this.Find.bind(this));
> >
> > > Remember that bind() [like bindAsEventListener()] creates a *new
> > > function* every time it's called, and returns that function.  The
> > > purpose of the new function is to set the context ('this') correctly
> > > when calling the original function.  You don't need a separate
> > > function for every text element, they all do exactly the same thing:
> > > They set "this" to the MSOFindForm and then call Find.  Instead,
> > > create your bound function once, then reuse it, like so:
> >
> > >    var handler;
> > >    handler = this.Find.bind(this);
> > >     this.MSOFindForm.getInputs('text').each(function(input) {
> > >         Event.observe(input, 'keyup', handler);
> > >    });
> >
> > > That creates the function just once, and then reuses it for each
> > > input.  You could also do it with Enumerble#invoke[2]:
> >
> > >    this.MSOFindForm.getInputs('text').invoke(
> > >        'observe',
> > >        'keyup',
> > >        this.Find.bind(this)
> > >    );
> >
> > > Event delegation
> > > ----------------
> > > 'keyup' is a bubbling event, so you could use a single handler on the
> > > form element instead of individual handlers on the text elements; the
> > > form's handler can use event.findElement() to find the actual element
> > > the keyup occurred in.  This is frequently called event delegation.
> > > [3]  Very roughly:
> >
> > >    // During initialization
> > >    $('formid').observe('keyup', this.handleKeyUp.bind(this));
> >
> > >    // In your class
> > >    handleKeyUp:  function(event) {
> > >        var element;
> >
> > >        // Get the element the event actually occurred on
> > >        element = event.findElement();
> >
> > >        // Is it a text field?
> > >        if (element.tagName.toLowerCase() == 'input' &&
> > >            element.type == 'text') {
> > >            // keyup logic goes here
> > >        }
> > >    }
> >
> > > [2]http://prototypejs.org/api/enumerable/invoke
> > > [3]http://proto-scripty.wikidot.com/faq#delegation
> >
> > > FWIW & HTH,
> > > --
> > > T.J. Crowder
> > > tj / crowder software / com
> > > Independent Software Engineer, consulting services available
> >
> > > On Apr 10, 3:52 am, kstubs <[email protected]> wrote:
> > > > So I'm trying to setup the keyup event for my form inputs like this:
> >
> > > >         this.MSOFindForm.getInputs('text').each(function(input) {
> > > >             Event.observe(input, 'keyup',
> this.Find.bindAsEventListener
> > > > (this));
> > > >         });
> >
> > > > The above is part of the initialize event for the class MSOFindForm.
> > > > The MSOFindForm has a Find method.  I am getting an error though,
> > > > which says that this.Find is not defined.  Uggg, I'm confused.
> >
> > > > Karl..
> >
> > > > On Apr 9, 4:17 pm, Ryan Gahl <[email protected]> wrote:
> >
> > > > > OK
> >
> > > > > Someone might want to jump in here, as I'm not 100% of the behavior
> of
> > > the
> > > > > passed in event obj.
> >
> > > > > Basically I think you can just do the following:
> >
> > > > > var func = function() { this.Find(input, objEvent, false);
> > > }.bind(this);
> >
> > > > > > //get rid of the func = func.bind(this) line and just bind inline
> >
> > > > >  since the variables input and objEvent are closed over that should
> be
> > > all
> > > > > you need to do. The caveat to that is if the objEvent reference
> changes
> > > with
> > > > > other events that happen after you set up the timer, and that's
> where
> > > > > someone like kangax can probably jump in and say yea or nay
> immediately
> > > (of
> > > > > course you can just try it).
> >
> > > > > If that doesn't work, then you might want to create the timer in
> such a
> > > way
> > > > > that it passes just the keycode part of the event object (which is
> all
> > > you
> > > > > seem to need). I can see that looking kind of like this:
> >
> > > > > Find: function(input, objEvent, useractive) {
> >
> > > > > >    var keycode = objEvent.keyCode;
> > > > > >    this.__doFind(input, keycode, useractive);
> > > > > > },
> > > > > > __doFind: function(input, keycode, useractive) {
> > > > > >     this.flgUserActive = useractive;
> >
> > > > > >    // keycode ignore list
> > > > > >    if (this.aKeyCodeIgnoreList.include(keycode))
> > > > > >        return false;
> >
> > > > > >    // ajax spinning (no action)
> > > > > >    if (this.flgAjaxActive)
> > > > > >        return;
> >
> > > > > >    // user typing (no immediate action, set timer)
> > > > > >    if (this.flgUserActive) {
> > > > > >        this.flgUserActive = false;
> >
> > > > > >        var form = this.MSOFindLayer.select('form')[0];
> >
> > > > > >        //test 2 leters in 1st word for up to two words (trailing
> > > space is
> > > > > > bad)
> > > > > >        if
> > > (!($(input).value.match(/^[a-zA-Z]{2,40}(.[a-zA-Z]{1,40})?$/im)))
> > > > > >            return;
> >
> > > > > >        if (this.timer != null)
> > > > > >            clearTimeout(this.timer);
> >
> > > > > >        var func = function() { this.__doFind(input, keycode,
> false);
> > > > > > }.bind(this);
> > > > > >        this.timer = setTimeout(func, 300);
> >
> > > > > >        return;
> > > > > >    }
> >
> > > > > >    // if we made it this far, call the find
> > > > > >    __find(input);
> > > > > > }
> >
> > > > > Ultimately, though, you should be attaching your listeners via
> > > javacript,
> > > > > which in this case will probably make life a little easier.
> >
> > > > > Ryan Gahl
> > > > > CEO
> > > > > Nth Penguin, LLChttp://www.nthpenguin.com
> > > > > --
> > > > > Inquire: 1-920-574-2218
> > > > > Blog:http://www.someElement.com
> > > > > LinkedIn Profile:http://www.linkedin.com/in/ryangahl
> >
> > > > > On Thu, Apr 9, 2009 at 4:55 PM, kstubs <[email protected]> wrote:
> > > > > > var func = function(input, objEvent) { this.Find(input,
> > > > > > objEvent, false); };
> >
> >
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to