> > 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 -~----------~----~----~----~------~----~------~--~---
