Greetings all, I''ve written an object to create a lightbox-like dialog on-screen (I posted about it earlier; search for "dialogish" within the group and you''ll find that thread). I then ran into the Control.Modal window which did much of what I wanted, but was also much more complex. I didn''t understand all of what the developer of Control.Modal was doing so I tried to take what I did understand from his class and apply it to mine. If you''re unfamiliar with Control.Modal, you can find it here: http://livepipe.net/projects/control_modal/. The problem I''m facing as that the functions that are called to respond to different dialog-centric events (like beforeLoad, beforeOpen, etc.) have a scope that''s not that of the dialog object. Code time: var dialog = new Dialog("test.php", { beforeLoad: function() { return { window_id: $F("window_id") } } }); dialog.activate(); The above snippet shows the basics of how the dialog object is started. You pass the URL of the information to be loaded via Ajax.Updater as well as any custom functions which need to respond to one of four different events within the dialog code: before the information is loaded, before the content is shown, before the content is hidden, and before the dialog container is actually removed from the DOM. The above snippet would work fine, but I can imagine a time when I might want to do something like this: var dialog = new Dialog("test.php", { beforeClose: function() { $(this.dialog_id).getElementsByTagName("input").each(function(input) { /* ... */ }) } }); dialog.activate(); The above snippet doesn''t work, clearly because the this keyword refers to the scope of the anonymous function, unless I misunderstand something crucial. So, I tried to do something like this: Dialog.prototype = { initialize: function(href, custom_responders) { /* ... do other setup stuff ... */ if(custom_responders) for(responder in custom_responders) this.responders[responder] = custom_responder[responder]; *for(responder in this.responders) this.responders[responder].bind(this)* I thought that the above use of the bind() function would tell the the responder functions which are passed within the custom_responders object to use the scope of the dialog object as their scope but that doesn''t seem to be the case. Simply uses of this binding like the following still fail: var dialog = new Dialog("test.php", { beforeLoad: function() { alert(this.dialog_id) } }); For what it''s worth, it alerts undefined. Here''s the code: http://pastie.caboo.se/52614 Note that the usage of bind() mentioned in this post is not in the pastie. My bad. -- Dash -- --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
You can attach .bind(this) to anonymous functions... beforeOnload: function() {....stuff....}.bind(this) On 4/9/07, David Dashifen Kees <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> wrote:> > Greetings all, > > I''ve written an object to create a lightbox-like dialog on-screen (I > posted about it earlier; search for "dialogish" within the group and you''ll > find that thread). I then ran into the Control.Modal window which did > much of what I wanted, but was also much more complex. I didn''t understand > all of what the developer of Control.Modal was doing so I tried to take > what I did understand from his class and apply it to mine. If you''re > unfamiliar with Control.Modal, you can find it here: > http://livepipe.net/projects/control_modal/. > > The problem I''m facing as that the functions that are called to respond to > different dialog-centric events (like beforeLoad, beforeOpen, etc.) have a > scope that''s not that of the dialog object. Code time: > > var dialog = new Dialog("test.php", { > beforeLoad: function() { return { window_id: $F("window_id") } } > }); dialog.activate(); > > The above snippet shows the basics of how the dialog object is started. > You pass the URL of the information to be loaded > via Ajax.Updater as well as any custom functions which need to respond to > one of four different events within the dialog code: before the information > is loaded, before the content is shown, before the content is hidden, and > before the dialog container is actually removed from the DOM. The above > snippet would work fine, but I can imagine a time when I might want to do > something like this: > > var dialog = new Dialog("test.php", { > beforeClose: function() { > $(this.dialog_id).getElementsByTagName("input").each(function(input) > { /* ... */ }) > } > }); dialog.activate(); > > The above snippet doesn''t work, clearly because the this keyword refers > to the scope of the anonymous function, unless I misunderstand something > crucial. So, I tried to do something like this: > > Dialog.prototype = { > initialize: function(href, custom_responders) { > /* ... do other setup stuff ... */ > > if(custom_responders) > for(responder in custom_responders) > this.responders[responder] = custom_responder[responder]; > > *for(responder in this.responders) this.responders > [responder].bind(this)* > > I thought that the above use of the bind() function would tell the the > responder functions which are passed within the custom_responders object to > use the scope of the dialog object as their scope but that doesn''t seem to > be the case. Simply uses of this binding like the following still fail: > > var dialog = new Dialog("test.php", { beforeLoad: function() { alert( > this.dialog_id) } }); > > For what it''s worth, it alerts undefined. Here''s the code: > http://pastie.caboo.se/52614 > > Note that the usage of bind() mentioned in this post is not in the > pastie. My bad. > > -- Dash -- > > > > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-920-955-1457 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Right, but the function is defined outside of the scope of the dialog ... usually in an anonymous function within a window.onload observer. I pass an object containing those anonymous functions to the intialize() method of the dialog class and then copy them over into the class itself. That way, a page can have more than one dialog which respond to their own set of event handlers. I have found out that specifying the context of the function using the call() method of the JavaScript Function object seems to work, but I''m not sure this is a well known feature of Javascript actions. For example, here''s a dialog with an anonymous beforeLoad function. I can''t bind() it here because this refers to the local scope and I can''t bind it to "dialog" since it''s not actually initialized until after the Dialog.prototype.initialize() function completes... var dialog = new Dialog("test.php", { beforeLoad: function() { alert(this.dialog_id); return null; } }); But, if I add the following to line #46 in the pastie from my original post, things work: this.json = this.responders["beforeLoad"].call(this); Everything is happy. I found out about the call method of Functions in JavaScript only after I posted my message above. I wonder if this is common practice? Also, I notice that it is used in the prototype.js code, so maybe this is the best way to do it? -- Dash -- Ryan Gahl wrote:> You can attach .bind(this) to anonymous functions... > > beforeOnload: function() {....stuff....}.bind(this) > > On 4/9/07, David Dashifen Kees <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> wrote: > >> Greetings all, >> >> I''ve written an object to create a lightbox-like dialog on-screen (I >> posted about it earlier; search for "dialogish" within the group and you''ll >> find that thread). I then ran into the Control.Modal window which did >> much of what I wanted, but was also much more complex. I didn''t understand >> all of what the developer of Control.Modal was doing so I tried to take >> what I did understand from his class and apply it to mine. If you''re >> unfamiliar with Control.Modal, you can find it here: >> http://livepipe.net/projects/control_modal/. >> >> The problem I''m facing as that the functions that are called to respond to >> different dialog-centric events (like beforeLoad, beforeOpen, etc.) have a >> scope that''s not that of the dialog object. Code time: >> >> var dialog = new Dialog("test.php", { >> beforeLoad: function() { return { window_id: $F("window_id") } } >> }); dialog.activate(); >> >> The above snippet shows the basics of how the dialog object is started. >> You pass the URL of the information to be loaded >> via Ajax.Updater as well as any custom functions which need to respond to >> one of four different events within the dialog code: before the information >> is loaded, before the content is shown, before the content is hidden, and >> before the dialog container is actually removed from the DOM. The above >> snippet would work fine, but I can imagine a time when I might want to do >> something like this: >> >> var dialog = new Dialog("test.php", { >> beforeClose: function() { >> $(this.dialog_id).getElementsByTagName("input").each(function(input) >> { /* ... */ }) >> } >> }); dialog.activate(); >> >> The above snippet doesn''t work, clearly because the this keyword refers >> to the scope of the anonymous function, unless I misunderstand something >> crucial. So, I tried to do something like this: >> >> Dialog.prototype = { >> initialize: function(href, custom_responders) { >> /* ... do other setup stuff ... */ >> >> if(custom_responders) >> for(responder in custom_responders) >> this.responders[responder] = custom_responder[responder]; >> >> *for(responder in this.responders) this.responders >> [responder].bind(this)* >> >> I thought that the above use of the bind() function would tell the the >> responder functions which are passed within the custom_responders object to >> use the scope of the dialog object as their scope but that doesn''t seem to >> be the case. Simply uses of this binding like the following still fail: >> >> var dialog = new Dialog("test.php", { beforeLoad: function() { alert( >> this.dialog_id) } }); >> >> For what it''s worth, it alerts undefined. Here''s the code: >> http://pastie.caboo.se/52614 >> >> Note that the usage of bind() mentioned in this post is not in the >> pastie. My bad. >> >> -- Dash -- >> >> >> >> >> >> > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Ah, ok, now I get it. Then yea, that works, and is a very fine way to do it (to answer the "is this a well known way")... Another way could be to pass the instance into the callback function as an argument. So then you''d define the callback as such... var dialog = new Dialog("test.php", { beforeLoad: function(dlg) { alert( dlg.dialog_id); return null; } }); On 4/9/07, David Dashifen Kees <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> wrote:> > Right, but the function is defined outside of the scope of the dialog ... > usually in an anonymous function within a window.onload observer. I pass > an object containing those anonymous functions to the intialize() method of > the dialog class and then copy them over into the class itself. That way, a > page can have more than one dialog which respond to their own set of event > handlers. > > I have found out that specifying the context of the function using the > call() method of the JavaScript Function object seems to work, but I''m not > sure this is a well known feature of Javascript actions. For example, > here''s a dialog with an anonymous beforeLoad function. I can''t bind() it > here because this refers to the local scope and I can''t bind it to "dialog" > since it''s not actually initialized until after the > Dialog.prototype.initialize() function completes... > > var dialog = new Dialog("test.php", { beforeLoad: function() { alert( > this.dialog_id); return null; } }); > > But, if I add the following to line #46 in the pastie from my original > post, things work: > > this.json = this.responders["beforeLoad"].call(this); > > Everything is happy. I found out about the call method of Functions in > JavaScript only after I posted my message above. I wonder if this is common > practice? Also, I notice that it is used in the prototype.js code, so > maybe this is the best way to do it? > > -- Dash -- > > > > > > Ryan Gahl wrote: > > You can attach .bind(this) to anonymous functions... > > beforeOnload: function() {....stuff....}.bind(this) > > On 4/9/07, David Dashifen Kees <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> wrote: > > Greetings all, > > I''ve written an object to create a lightbox-like dialog on-screen (I > posted about it earlier; search for "dialogish" within the group and you''ll > find that thread). I then ran into the Control.Modal window which did > much of what I wanted, but was also much more complex. I didn''t understand > all of what the developer of Control.Modal was doing so I tried to take > what I did understand from his class and apply it to mine. If you''re > unfamiliar with Control.Modal, you can find it here: > http://livepipe.net/projects/control_modal/. > > The problem I''m facing as that the functions that are called to respond to > different dialog-centric events (like beforeLoad, beforeOpen, etc.) have a > scope that''s not that of the dialog object. Code time: > > var dialog = new Dialog("test.php", { > beforeLoad: function() { return { window_id: $F("window_id") } } > }); dialog.activate(); > > The above snippet shows the basics of how the dialog object is started. > You pass the URL of the information to be loaded > via Ajax.Updater as well as any custom functions which need to respond to > one of four different events within the dialog code: before the information > is loaded, before the content is shown, before the content is hidden, and > before the dialog container is actually removed from the DOM. The above > snippet would work fine, but I can imagine a time when I might want to do > something like this: > > var dialog = new Dialog("test.php", { > beforeClose: function() { > $(this.dialog_id).getElementsByTagName("input").each(function(input) > { /* ... */ }) > } > }); dialog.activate(); > > The above snippet doesn''t work, clearly because the this keyword refers > to the scope of the anonymous function, unless I misunderstand something > crucial. So, I tried to do something like this: > > Dialog.prototype = { > initialize: function(href, custom_responders) { > /* ... do other setup stuff ... */ > > if(custom_responders) > for(responder in custom_responders) > this.responders[responder] = custom_responder[responder]; > > *for(responder in this.responders) this.responders > [responder].bind(this)* > > I thought that the above use of the bind() function would tell the the > responder functions which are passed within the custom_responders object to > use the scope of the dialog object as their scope but that doesn''t seem to > be the case. Simply uses of this binding like the following still fail: > > var dialog = new Dialog("test.php", { beforeLoad: function() { alert( > this.dialog_id) } }); > > For what it''s worth, it alerts undefined. Here''s the code: > http://pastie.caboo.se/52614 > > Note that the usage of bind() mentioned in this post is not in the > pastie. My bad. > > -- Dash -- > > > > > > > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-920-955-1457 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
I didn''t even think of just passing it as a parameter. Seems like it''s a little more clear than the call() method but the latter is more elegant than the form (and allows the use of the this keyword as necessary). Thanks Ryan, -- Dash -- Ryan Gahl wrote:> Ah, ok, now I get it. Then yea, that works, and is a very fine way to do it > (to answer the "is this a well known way")... > > Another way could be to pass the instance into the callback function as an > argument. So then you''d define the callback as such... > > var dialog = new Dialog("test.php", { beforeLoad: function(dlg) { alert( > dlg.dialog_id); return null; } }); > > > > On 4/9/07, David Dashifen Kees <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> wrote: > >> Right, but the function is defined outside of the scope of the dialog ... >> usually in an anonymous function within a window.onload observer. I pass >> an object containing those anonymous functions to the intialize() method of >> the dialog class and then copy them over into the class itself. That way, a >> page can have more than one dialog which respond to their own set of event >> handlers. >> >> I have found out that specifying the context of the function using the >> call() method of the JavaScript Function object seems to work, but I''m not >> sure this is a well known feature of Javascript actions. For example, >> here''s a dialog with an anonymous beforeLoad function. I can''t bind() it >> here because this refers to the local scope and I can''t bind it to "dialog" >> since it''s not actually initialized until after the >> Dialog.prototype.initialize() function completes... >> >> var dialog = new Dialog("test.php", { beforeLoad: function() { alert( >> this.dialog_id); return null; } }); >> >> But, if I add the following to line #46 in the pastie from my original >> post, things work: >> >> this.json = this.responders["beforeLoad"].call(this); >> >> Everything is happy. I found out about the call method of Functions in >> JavaScript only after I posted my message above. I wonder if this is common >> practice? Also, I notice that it is used in the prototype.js code, so >> maybe this is the best way to do it? >> >> -- Dash -- >> >> >> >> >> >> Ryan Gahl wrote: >> >> You can attach .bind(this) to anonymous functions... >> >> beforeOnload: function() {....stuff....}.bind(this) >> >> On 4/9/07, David Dashifen Kees <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> <dashifen-NT0ononE2K1Wk0Htik3J/w@public.gmane.org> wrote: >> >> Greetings all, >> >> I''ve written an object to create a lightbox-like dialog on-screen (I >> posted about it earlier; search for "dialogish" within the group and you''ll >> find that thread). I then ran into the Control.Modal window which did >> much of what I wanted, but was also much more complex. I didn''t understand >> all of what the developer of Control.Modal was doing so I tried to take >> what I did understand from his class and apply it to mine. If you''re >> unfamiliar with Control.Modal, you can find it here: >> http://livepipe.net/projects/control_modal/. >> >> The problem I''m facing as that the functions that are called to respond to >> different dialog-centric events (like beforeLoad, beforeOpen, etc.) have a >> scope that''s not that of the dialog object. Code time: >> >> var dialog = new Dialog("test.php", { >> beforeLoad: function() { return { window_id: $F("window_id") } } >> }); dialog.activate(); >> >> The above snippet shows the basics of how the dialog object is started. >> You pass the URL of the information to be loaded >> via Ajax.Updater as well as any custom functions which need to respond to >> one of four different events within the dialog code: before the information >> is loaded, before the content is shown, before the content is hidden, and >> before the dialog container is actually removed from the DOM. The above >> snippet would work fine, but I can imagine a time when I might want to do >> something like this: >> >> var dialog = new Dialog("test.php", { >> beforeClose: function() { >> $(this.dialog_id).getElementsByTagName("input").each(function(input) >> { /* ... */ }) >> } >> }); dialog.activate(); >> >> The above snippet doesn''t work, clearly because the this keyword refers >> to the scope of the anonymous function, unless I misunderstand something >> crucial. So, I tried to do something like this: >> >> Dialog.prototype = { >> initialize: function(href, custom_responders) { >> /* ... do other setup stuff ... */ >> >> if(custom_responders) >> for(responder in custom_responders) >> this.responders[responder] = custom_responder[responder]; >> >> *for(responder in this.responders) this.responders >> [responder].bind(this)* >> >> I thought that the above use of the bind() function would tell the the >> responder functions which are passed within the custom_responders object to >> use the scope of the dialog object as their scope but that doesn''t seem to >> be the case. Simply uses of this binding like the following still fail: >> >> var dialog = new Dialog("test.php", { beforeLoad: function() { alert( >> this.dialog_id) } }); >> >> For what it''s worth, it alerts undefined. Here''s the code: >> http://pastie.caboo.se/52614 >> >> Note that the usage of bind() mentioned in this post is not in the >> pastie. My bad. >> >> -- Dash -- >> >> >> >> >> >> >> >> >> > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Hey David, bind *returns* a wrapped version of your original function: binding is not a property of a function, it''s something that is determined at calling time. You can either bind all responders at initialization, or just call them with the proper binding each time. Early binding: for(responder in this.responders) this.responders[responder] = this.responders[responder].bind(this); On-the-fly bound calling, example for beforeLoad: if (this.responders.beforeLoad) this.responders.beforeLoad.call(this, arg1, arg2...); ''HTH -- Christophe Porteneuve a.k.a. TDD "[They] did not know it was impossible, so they did it." --Mark Twain Email: tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Yeah, using the call() method is where I went. Before I posted this topic I didn''t know about the call() method but I read about it this afternoon and it seems to be my best option. Thanks, - Dash - Christophe Porteneuve wrote:> Hey David, > > bind *returns* a wrapped version of your original function: binding is > not a property of a function, it''s something that is determined at > calling time. > > You can either bind all responders at initialization, or just call them > with the proper binding each time. > > Early binding: > > for(responder in this.responders) > this.responders[responder] = this.responders[responder].bind(this); > > On-the-fly bound calling, example for beforeLoad: > > if (this.responders.beforeLoad) > this.responders.beforeLoad.call(this, arg1, arg2...); > > ''HTH > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---