[Proto-Scripty] Re: Can't call a function within a class using each or invoke

2008-11-17 Thread Mona Remlawi

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



[Proto-Scripty] Re: Can't call a function within a class using each or invoke

2008-11-17 Thread George

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 barspan
 /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 - 

[Proto-Scripty] Re: Can't call a function within a class using each or invoke

2008-11-17 Thread Mona Remlawi

Good call George,  I'll do the same :)

cheers

--
mona
[EMAIL PROTECTED]

On Mon, Nov 17, 2008 at 4:13 PM, George [EMAIL PROTECTED] wrote:

 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 barspan
 /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