I am trying to implement something in the style of Draggables, where I can specify an HTML element that I want to place comments against by clicking on the element. So I have copied the style of Draggables and created the following: <html> <head> <script src="javascript/prototype.js" type="text/javascript"></script> <script src="javascript/scriptaculous.js" type="text/javascript"></ script> <script type="text/javascript"> var Commentables = { commentable: [], register: function(commentable) { this.commentable.push(commentable); } } var Commentable = Class.create(); Commentable.prototype = { comments: [], object_ID: '''', initialize: function(elmid) { this.object_ID = $(elmid); this.eventOnClick = this.newComment.bindAsEventListener(this); Event.observe(elmid, ''click'', this.eventOnClick, false); // save the commentable object away. Commentables.register(this); }, newComment: function(event) { alert(''i have been clicked: ''+this.object_ID.id); this.comments.push(''a comment on ''+this.object_ID.id); this.showComments(); }, showComments: function() { this.comments.each( function(c) { alert(c) } ) } } Event.observe(window, ''load'', page_loaded, false); function page_loaded(evt) { var one = new Commentable(''firstone''); var two = new Commentable(''secondone''); } </script> </head> <body> <div id="firstone">some text just to give the div a width</div> <div id="secondone">more text here just for padding.</div> </body> </html> So basically I have two clickable DIVs, and when you click on each, it displays an alert telling you which was clicked by calling newComment, and then displays all the comments saved against that DIV. It always displays the correct Object_ID, however when I call showComments, it displays an altert for every comment on ALL commentable objects. ie click on firstone: alert(''i have been clicked firstone''); alert(''a comment on firstone''); then click on secondone (without refreshing the page): alert(''i have been clicked secondone''); alert(''a comment on firstone''); // ****** why is this one coming out too?? alert(''a comment on secondone''); I reckon my understanding of how javascript works going wrong here, but why do the contents on the comments array for both object get shown when I thought that only the contents of the one associated with the DIV I click on should? Have I created my objects wrong? Any help is much appreciated as I am baffled about this one! Thanks, Stephen. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Colin Mollenhour
2007-Mar-21 20:00 UTC
Re: Help with draggables style javascript for commenting
What you are doing is the equivalent of Commentable.prototype.comments = [] which creates a sort of shared variable among all instances of that object. I guess the reason object_ID isn''t being overwritten is because when you use this.object_ID = ...; you are overwriting the shared variable with a local variable for that instance. However, this.comments.push(...); is referencing the shared variable. So, for properties of an instance, always use this.someProperty = ...; This will work: Commentable.prototype = { initialize: function(elmid) { this.object_ID = $(elmid); this.comments = []; this.eventOnClick = this.newComment.bindAsEventListener(this); Event.observe(elmid, ''click'', this.eventOnClick, false); // save the commentable object away. Commentables.register(this); }, ... } Colin stephen O''D wrote:> I am trying to implement something in the style of Draggables, where I > can specify an HTML element that I want to place comments against by > clicking on the element. So I have copied the style of Draggables and > created the following: > > <html> > > <head> > <script src="javascript/prototype.js" type="text/javascript"></script> > <script src="javascript/scriptaculous.js" type="text/javascript"></ > script> > > <script type="text/javascript"> > > var Commentables = { > commentable: [], > > register: function(commentable) { > this.commentable.push(commentable); > } > > } > > var Commentable = Class.create(); > > Commentable.prototype = { > comments: [], > object_ID: '''', > > initialize: function(elmid) { > this.object_ID = $(elmid); > this.eventOnClick = this.newComment.bindAsEventListener(this); > Event.observe(elmid, ''click'', this.eventOnClick, false); > // save the commentable object away. > Commentables.register(this); > }, > > newComment: function(event) { > alert(''i have been clicked: ''+this.object_ID.id); > this.comments.push(''a comment on ''+this.object_ID.id); > this.showComments(); > }, > > showComments: function() { > this.comments.each( function(c) { alert(c) } ) > } > } > > Event.observe(window, ''load'', page_loaded, false); > > function page_loaded(evt) { > var one = new Commentable(''firstone''); > var two = new Commentable(''secondone''); > } > > </script> > > </head> > > <body> > <div id="firstone">some text just to give the div a width</div> > <div id="secondone">more text here just for padding.</div> > </body> > </html> > > So basically I have two clickable DIVs, and when you click on each, it > displays an alert telling you which was clicked by calling newComment, > and then displays all the comments saved against that DIV. > > It always displays the correct Object_ID, however when I call > showComments, it displays an altert for every comment on ALL > commentable objects. > > ie click on firstone: > > alert(''i have been clicked firstone''); > alert(''a comment on firstone''); > > then click on secondone (without refreshing the page): > > alert(''i have been clicked secondone''); > alert(''a comment on firstone''); // ****** why is this one coming > out too?? > alert(''a comment on secondone''); > > I reckon my understanding of how javascript works going wrong here, > but why do the contents on the comments array for both object get > shown when I thought that only the contents of the one associated with > the DIV I click on should? Have I created my objects wrong? > > Any help is much appreciated as I am baffled about this one! > > Thanks, > > Stephen. > > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
stephen O''D
2007-Mar-21 21:30 UTC
Re: Help with draggables style javascript for commenting
On Mar 21, 8:00 pm, Colin Mollenhour <eliteii...-NPSFNn/7+NYVo650/ln6uw@public.gmane.org> wrote:> What you are doing is the equivalent of > Commentable.prototype.comments = [] > which creates a sort of shared variable among all instances of that object. I guess the reason object_ID isn''t being overwritten is because when you use > this.object_ID = ...; > you are overwriting the shared variable with a local variable for that instance. However, > this.comments.push(...); > is referencing the shared variable. So, for properties of an instance, always use > this.someProperty = ...; > > This will work: > > Commentable.prototype = { > initialize: function(elmid) { > this.object_ID = $(elmid); > this.comments = []; > this.eventOnClick = this.newComment.bindAsEventListener(this); > Event.observe(elmid, ''click'', this.eventOnClick, false); > // save the commentable object away. > Commentables.register(this); > }, > ... > > } > > Colin > > stephen O''D wrote: > > I am trying to implement something in the style of Draggables, where I > > can specify an HTML element that I want to place comments against by > > clicking on the element. So I have copied the style of Draggables and > > created the following: > > > <html> > > > <head> > > <script src="javascript/prototype.js" type="text/javascript"></script> > > <script src="javascript/scriptaculous.js" type="text/javascript"></ > > script> > > > <script type="text/javascript"> > > > var Commentables = { > > commentable: [], > > > register: function(commentable) { > > this.commentable.push(commentable); > > } > > > } > > > var Commentable = Class.create(); > > > Commentable.prototype = { > > comments: [], > > object_ID: '''', > > > initialize: function(elmid) { > > this.object_ID = $(elmid); > > this.eventOnClick = this.newComment.bindAsEventListener(this); > > Event.observe(elmid, ''click'', this.eventOnClick, false); > > // save the commentable object away. > > Commentables.register(this); > > }, > > > newComment: function(event) { > > alert(''i have been clicked: ''+this.object_ID.id); > > this.comments.push(''a comment on ''+this.object_ID.id); > > this.showComments(); > > }, > > > showComments: function() { > > this.comments.each( function(c) { alert(c) } ) > > } > > } > > > Event.observe(window, ''load'', page_loaded, false); > > > function page_loaded(evt) { > > var one = new Commentable(''firstone''); > > var two = new Commentable(''secondone''); > > } > > > </script> > > > </head> > > > <body> > > <div id="firstone">some text just to give the div a width</div> > > <div id="secondone">more text here just for padding.</div> > > </body> > > </html> > > > So basically I have two clickable DIVs, and when you click on each, it > > displays an alert telling you which was clicked by calling newComment, > > and then displays all the comments saved against that DIV. > > > It always displays the correct Object_ID, however when I call > > showComments, it displays an altert for every comment on ALL > > commentable objects. > > > ie click on firstone: > > > alert(''i have been clicked firstone''); > > alert(''a comment on firstone''); > > > then click on secondone (without refreshing the page): > > > alert(''i have been clicked secondone''); > > alert(''a comment on firstone''); // ****** why is this one coming > > out too?? > > alert(''a comment on secondone''); > > > I reckon my understanding of how javascript works going wrong here, > > but why do the contents on the comments array for both object get > > shown when I thought that only the contents of the one associated with > > the DIV I click on should? Have I created my objects wrong? > > > Any help is much appreciated as I am baffled about this one! > > > Thanks, > > > Stephen.Ah! So the way I was doing it was sort of creating what would be known as Class variables in Ruby speak - variables that are shared by all instance of the class. Makes sense now. Thanks for the help. Stephen. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---