469,946 Members | 1,866 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,946 developers. It's quick & easy.

Get reference to Ajax Control in button click event

Frinavale
9,735 Expert Mod 8TB
I'm in the middle of implementing a custom Ajax enabled Server Control.
At this point I need help finding the answer to an Ajax Framework question...here it goes:

I have a Server Control that extends from a Panel and implements the IScriptControl interface:
Expand|Select|Wrap|Line Numbers
  1. Public Class MyCustomControl
  2.     Inherits Panel
  3.     Implements IScriptControl
This Server Control consists of a collection of Labels, Panels, Buttons, Literals, other Ajax Extenders.

One of the buttons is an "ok" button.

In the JavaScript Object that represents the server control client side, I'm adding handlers to the buttons. For example, here I am adding a handler to my "ok" button:
Expand|Select|Wrap|Line Numbers
  1. MyNamespace.MyCustomControl.prototype = {
  2.     initialize: function() {
  3.         MyNamespace.MyCustomControl.callBaseMethod(this, 'initialize');      
  4. //Here I initialize a bunch of private Object variables
  5.  
  6. //Now I'm adding a handler for the buttons...here's the one in question:
  7.         $addHandler($get(this.get_OkID()), 'click', this._okClick);
  8.     },
  9. //...............
  10.  
In the _okClick method that handles the "ok" button's click, I need to some how get a reference to the JavaScript Object that the button belongs to... that the button is associated with.

In that method "this" refers to the button element that was clicked, not the JavaScript Object. The button element has no way to refer to the JavaScript Object it is associated with because it's just a regular Dom element.

I tried looking at the event, but it has no way to reference the JavaScript Object that the event originated from/is associated with.

I tried grabbing all of the JavaScript Object instances loaded (using the Sys.Application.getCommponents method) but while looping through these I'm not able to check if the button belongs to them (if there's a way to do this I'm unaware of it).

Does anyone know how to get a reference to the JavaScript Object that the button element is associated with in the method that handles the button click event?

Thanks,

-Frinny
Mar 4 '09 #1
19 4087
gits
5,390 Expert Mod 4TB
try the following closure:

Expand|Select|Wrap|Line Numbers
  1. var me = this;
  2.  
  3. $addHandler($get(this.get_OkID()), 'click', function() {
  4.     this._okClick.apply(me, arguments);
  5. });
kind regards
Mar 4 '09 #2
Frinavale
9,735 Expert Mod 8TB
This doesn't work.

What's "me"? Did you mean "this"?
What's arguments?
What does the apply() method do? Where did you get this idea from?
Mar 4 '09 #3
Frinavale
9,735 Expert Mod 8TB
Ok I solved the problem.

I wish there was better documentation out there on the Ajax Framework...because piecing things together is difficult without a good resource but anyways...

Apparently if you want to reference the JavaScript Object that is associated with the button in the method that handles the button click event you have create a delegate and pass that as the parameter to the $addHandler() method.

Originally I was just passing a reference to the method (not using a delegate) like this:
Expand|Select|Wrap|Line Numbers
  1. MyNamespace.MyCustomControl.prototype = {
  2.     initialize: function() {
  3.         MyNamespace.MyCustomControl.callBaseMethod(this, 'initialize');      
  4. //Here I initialize a bunch of private Object variables
  5.  
  6. //Now I'm adding a handler for the buttons...here's the one in question:
  7.         $addHandler($get(this.get_OkID()), 'click', this._okClick);
  8.     },
  9. //...............
  10.  
Once I changed the code to use a delegate instead, "this" in the _onClick method referred to the JavaScript Object instead of the button element:

Expand|Select|Wrap|Line Numbers
  1. MyNamespace.MyCustomControl.prototype = {
  2.     initialize: function() {
  3.         MyNamespace.MyCustomControl.callBaseMethod(this, 'initialize');      
  4. //Here I initialize a bunch of private Object variables
  5.  
  6.  
  7. //Creating a delegate for the _okClick method
  8.  
  9. this._okClickDelegate = Function.createDelegate(this, this._okClick);
  10.  
  11. //Now I'm adding a handler for the buttons...here's the one in question:
  12.         $addHandler($get(this.get_OkID()), 'click', this._okClickDelegate);
  13.     },
  14. //...............
  15.  
This gave me the ability to change some properties of the JavaScript Object and call a method on that specific Object.

I was stuck on this problem all afternoon yesterday!

Now I have an even bigger problem: how do I raise an event....but before I ask the question for real I'm going to do some research on the topic and try a few things.
Mar 4 '09 #4
gits
5,390 Expert Mod 4TB
aahhrg, my bad ... it should be:

Expand|Select|Wrap|Line Numbers
  1. var me = this;
  2.  
  3. $addHandler($get(this.get_OkID()), 'click', function() {
  4.     me._okClick.apply(me, arguments);
  5. });
  6.  
ok ... to explain it a bit :) with

Expand|Select|Wrap|Line Numbers
  1. var me = this;
we store the value of the reference to the current context in a new var me. this reference-value is even stored (closed) in the anonymous function that is used as a 'context'-wrapper in your event-adder-function. so later on me refers to the context that we assigned here. since i guess that you are using the this-keyword in the _onClick()-method we now have to pass that context to this call and therefore we might use the apply() method that gets the context passed as the first arg and the second arg is an array of more parameters ... arguments is a JavaScript-keyword for the args of a function and we just pass it from the wrapper to the _onClick() method ... in case you would need it?

kind regards
Mar 4 '09 #5
gits
5,390 Expert Mod 4TB
ahh ... your solution does a similar thing ;) ... as you see it looks like the apply wrapped in a function ;) would you mind to test my suggestion to see whether it works? ...

kind regards
gits
Mar 4 '09 #6
Frinavale
9,735 Expert Mod 8TB
@gits
'context-wrapper'....this is an Object?
I'm going to look into this.


@gits
When I tried googling the apply() method I came up with thousands of references that didn't pertain to my problem. Is this a native JavaScript method?

@gits
I'm guessing that this is probably done in the Function.createDelegate() method that I used....and that is how JavaScript Object was made available to me in the _onClick method.
Mar 4 '09 #7
Frinavale
9,735 Expert Mod 8TB
@gits

I did try your suggestion...well I ended up changing it so that "this" was passed into the apply method.

It didn't work, for some reason the _onClick method was never called when I clicked the button.

I'm assuming this is because you are supplying an inline function (can't think of a better term) to the $addHandler method:

Expand|Select|Wrap|Line Numbers
  1. var me = this;
  2.  
  3. $addHandler($get(this.get_OkID()), 'click', function() {
  4.     this._okClick.apply(me, arguments);
  5. });
I tried changing it to :

Expand|Select|Wrap|Line Numbers
  1. var me = this;
  2.  
  3. $addHandler($get(this.get_OkID()), 'click', function() {
  4.     return this._okClick.apply(me, arguments);
  5. });
But that didn't work either.....

I'll try again.
Mar 4 '09 #8
gits
5,390 Expert Mod 4TB
it is a native JavaScript method ... have a look here ... MDC is a very good reference for all JavaScript related things ...

and 'context'-wrapper was just a descriptive name that i used for the closure-construct in the current case that we had ;)

kind regards
gits
Mar 4 '09 #9
gits
5,390 Expert Mod 4TB
yes ... i corrected it in my follow-up post (#5):

Expand|Select|Wrap|Line Numbers
  1. var me = this;
  2.  
  3. $addHandler($get(this.get_OkID()), 'click', function() {
  4.     me._okClick.apply(me, arguments);
  5. });
did you try this too? i think it should work?

PS: otherwise i had to rethink my above explainations ;)
Mar 4 '09 #10
Frinavale
9,735 Expert Mod 8TB
Ok.........I got it to work sort of.............(I think?)
Just sec let me clean it up and explain what I'm doing.

The problem was that I renamed the button and function when I posted the code, when I tried using your code I forgot to change one of the names and it was not working..
Mar 4 '09 #11
gits
5,390 Expert Mod 4TB
and now it is? i mean working? ;)
Mar 4 '09 #12
Frinavale
9,735 Expert Mod 8TB
Haha yes you were right, oh mighty king of JavaScript :)

I broke it up a bit so that I could better understand what was going on:
Expand|Select|Wrap|Line Numbers
  1. MyCustomNamespace.MyCustomControl.prototype = {
  2.     initialize: function() {
  3.         MyCustomNamespace.MyCustomControl.callBaseMethod(this, 'initialize');
  4. //...........
  5.  
  6.  
  7. //getting a reference to the ok button
  8.         var okButton = $get(this.get_OkID());
  9. //Assigning context to the method that handles the ok button click
  10.         this._okClick.apply(this, arguments);
  11.  
  12. //Adding an event listener to the button click that executes the _okClick method
  13.         $addHandler(okButton, 'click', this._okClick);
Now, what's interesting here is that my _okClick method is executed when the Object is created.

Does the apply() method cause it to be executed?

This is causing a problem because the _okClick method is setting a property in the Object that is used in the method that displays the visual parts of the control (displays the Ok button)....because this property is getting set, the display method is not displaying the control when I call that method (in another button click...)
Mar 4 '09 #13
gits
5,390 Expert Mod 4TB
puuuuh ... i thought i couldn't be wrong ... and fortunatly i wasn't *lol*

yes ... apply calls the method with the given context and args ... so you need to use the closure (what you called 'inline'-function) to wrap that. and therefor we need the me-variable since the function has a new context inside ;)

have a look what i found somewhere - this is the code for the createDelegate:

Expand|Select|Wrap|Line Numbers
  1. Function.createDelegate = function Function$createDelegate(instance, method) {
  2.     /// <summary locid="M:J#Function.createDelegate" />
  3.     /// <param name="instance" mayBeNull="true"></param>
  4.     /// <param name="method" type="Function"></param>
  5.     /// <returns type="Function"></returns>
  6.     var e = Function._validateParams(arguments, [
  7.     {name: "instance", mayBeNull: true},
  8.     {name: "method", type: Function}
  9.     ]);
  10.     if (e) throw e;
  11.     return function() {
  12.       return method.apply(instance, arguments);
  13.     }
looks like our example ... doesn't it? ;)
Mar 4 '09 #14
Frinavale
9,735 Expert Mod 8TB
:) it looks exactly the same.....

In that case, why didn't the inline method work?

Let me try it again..
Mar 4 '09 #15
gits
5,390 Expert Mod 4TB
oh ... i thought it did? #10 and #5 should work ...?
Mar 4 '09 #16
Frinavale
9,735 Expert Mod 8TB
Ok the following does work.

Expand|Select|Wrap|Line Numbers
  1. MyNamespace.MyCustomControl.prototype = {
  2.     initialize: function() {
  3.         MyNamespace.MyCustomControl.callBaseMethod(this, 'initialize');      
  4. //Here I initialize a bunch of private Object variables
  5.  
  6.          var me = this;
  7.          var okButton = $get(this.get_OkID());
  8.  
  9.         $addHandler(okButton, 'click', function() {me._okClick.apply(me, arguments); });
  10. }
Mar 4 '09 #17
gits
5,390 Expert Mod 4TB
ahh ... so i was right ;) ... what a strange expierience ... but sometimes i'm right indeed ;) ... so far for my first answers in a .NET forum *lol* ...

kind regards,
gits
Mar 4 '09 #18
Frinavale
9,735 Expert Mod 8TB
@gits
That article has to be the most confusing article ever.
If I didn't have the problem that I was having, it would have been pretty hard to determine what the apply method was based on their description:

Allows you to apply a method of another object in the context of a different object (the calling object).
Thank goodness they have a weak example on how to use it....
Mar 4 '09 #19
gits
5,390 Expert Mod 4TB
;) that is certainly something that is a matter of taste of the reader ... i have to admit that a lot of the MDC references are short and rely a bit on some more advanced JavaScript knowledge of the reader ... it is not a good point to start learning the language, but it is a good point to look for a reference when you need to have a look at the api-usage or similar things ... ;)

kind regards
Mar 4 '09 #20

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

2 posts views Thread by Chris Kettenbach | last post: by
3 posts views Thread by Not Me | last post: by
5 posts views Thread by Gui | last post: by
2 posts views Thread by =?Utf-8?B?VG9u?= | last post: by
3 posts views Thread by =?Utf-8?B?UnlhbiBTbWl0aA==?= | last post: by
4 posts views Thread by Peter | last post: by
reply views Thread by =?Utf-8?B?UGF1bA==?= | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.