T.J. - Mona,

Thank you both very much for your solutions, recommended reading lists
and T.J, for your event delegation suggestion.  FYI Mona's solution
worked out of the box but T.J. your event delegation suggestion makes
a lot of sense - I suspect I will add a new method to my class to
handle all clicks.

I'm going to do some reading first though - will start with ALA's
article on binding.

Many thanks

George



On Nov 17, 1:54 pm, "T.J. Crowder" <[EMAIL PROTECTED]> wrote:
> Doh!  I missed he was doing all of this in an invoke, what I get for
> skimming.
>
> Wow, that's convoluted.  Good answer, though.
>
> George, AFAICS Mona's solution will work for your _editField function
> as defined.  But FWIW, I'd probably define a separate function
> intended as an event handler.  (The reason Mona's had to create an
> anonymous function to bind is that she needs to ditch the event object
> parameter _editField isn't expecting to see.)  Doing that would
> simplify things a bit, I think, and make it easier for debugging.
>
> Another thing you might consider is event delegation:  Hook the
> 'click' event on whatever the container of these 'editable's is, and
> use one event handler rather than many.  Clicks on descendent elements
> bubble up to the parent container, and you can get the element on
> which the click actually happened from the event object.
>
> So given this, for instance:
>
> <div id='container'>
> <span class='editable'>foo foo foo</span>
> <span class='editable'>bar bar bar<span>
> </div>
>
> You can just hook 'click' on the 'container' rather than the
> editables:
>
> $('container').observe('click', this.handleContainerClick.bind(this));
>
> ....and your handler might look like this:
>
> function handleContainerClick(event) {
>     var elm;
>
>     // Get the element on which the click actually occurred
>     elm = event.findElement();
>
>     // Does it exist, and is it editable?
>     if (elm && elm.hasClassName('editable')) {
>         // Yes, edit it
>         this._editField(elm);
>     }
>
> }
>
> Various links on event delegation can be found 
> here:http://proto-scripty.wikidot.com/faq#delegation
>
> HTH,
> --
> T.J. Crowder
> tj / crowder software / com
>
> On Nov 17, 1:34 pm, "Mona Remlawi" <[EMAIL PROTECTED]> wrote:
>
> > great readings suggested.
> > when you finish, you can try the following :)
>
> > $$('.editable').each(function(e) {e.observe('click', (function()
> > {this._editField(e)}).bind(this))}, this);
>
> > the problem is that when you iterate, you have to specify the context.
>
> > On Mon, Nov 17, 2008 at 2:15 PM, T.J. Crowder <[EMAIL PROTECTED]> wrote:
>
> > > Hi George,
>
> > > Go back to school! ;-)
>
> > > No, seriously, you don't need to wrap the call to bindAsEventListener
> > > () in a function; that's its job.  You also don't have to pass the
> > > event object to it.  (And you probably want bind()[1] rather than
> > > bindAsEventListener().)
>
> > > [1]http://prototypejs.org/api/function/bind
>
> > > Some resources that will probably help, both with the concept...
>
> > >http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
> > >http://www.alistapart.com/articles/getoutbindingsituations
>
> > > ...and the details:
> > >http://proto-scripty.wikidot.com/prototype:how-to-hooking-events
> > > (the example near the end alks about instance methods, but I recommend
> > > reading through from the beginning).
>
> > > HTH,
> > > --
> > > T.J. Crowder
> > > tj / crowder software / com
>
> > > On Nov 17, 1:00 pm, George <[EMAIL PROTECTED]> wrote:
> > >> Hi Folks,
>
> > >> I'm pretty sure that I'm going to be told to go back to school here,
> > >> but I've wasted a whole morning trying to figure this out - now it's
> > >> time to ask the experts.
>
> > >> I've simplified my code here to demonstrate what I'm trying to do:
>
> > >> [CODE]
> > >> var buildPage = {};
> > >> buildPage = Class.create();
> > >> buildPage.prototype =
> > >> {
> > >>   initialize: function() {
> > >>     this.rowTemplate = '<tr>...'
> > >>     this.rs = [];
> > >>     this._getData();
> > >>   },// initialize
>
> > >>  _getData : function() {//using AJAX to grab a JSON array from the
> > >> server and store it in this.rs},
>
> > >> _parseTemplate : function() {//write data to screen then add event
> > >> listeners
> > >>  $$('.editable').invoke('observe', 'mouseover',function(e){e.element
> > >> ().addClassName('pseudo-text-box')});
> > >>  $$('.editable').invoke('observe', 'mouseout',function(e){e.element
> > >> ().removeClassName('pseudo-text-box')});
> > >>  $$('.editable').invoke('observe', 'click', function(e)
> > >> {this._editField.bindAsEventListener(this, e) });
>
> > >> },
>
> > >> _editField : function(e) {
> > >> //Inject <INPUT> field}
> > >> };
>
> > >> [/CODE]
>
> > >> My problem is with this line:
>
> > >> $$('.editable').invoke('observe', 'click', function(e)
> > >> {this._editField.bindAsEventListener(this, e) });
>
> > >> At runtime, I always get the message that this._editField is not a
> > >> function, no matter how I try the binding.  The only way I can get
> > >> this to work is to initiate the class (var a = new buildPage) than
> > >> call c._editField from within the function - but that's not much good
> > >> when I come to re-use it.
>
> > >> Can someone explain to me what's going on here - I'm stumped.
>
> > >> Many thanks
>
> > >> George
--~--~---------~--~----~------------~-------~--~----~
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 prototype-scriptaculous@googlegroups.com
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