Javascript event arguments

7 posts, 0 answers
  1. Peter Zolja
    Peter Zolja avatar
    119 posts
    Member since:
    Dec 2007

    Posted 01 May 2009 Link to this post

    When dealing with Telerik controls and having to wrap a JavaScript event the usual structure is OnClientXXXX="SomeMethod". The method expects a sender and eventArgs, and nothing else.

    Is there a way to pass other parameters to SomeMethod? Sometimes I'd prefer to write a single JS method that is called by several controls. To make these methods generic I usually need to pass some other information as well, like an ID of another control.

  2. Svetlina Anati
    Svetlina Anati avatar
    2795 posts

    Posted 04 May 2009 Link to this post

    Hello Peter,

    What I can suggest in your case is that you declare a global javascript variable and access it when needed. Please, test this suggestion and let me know whether it helps. In case it does not, please provide a detailed explanations why it does not and best - open a new support ticket and send us a sample reproduction demo along with explanations of the actual and the desired behavior and we will do our best to give you a reasonable solution.

    Sincerely yours,
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. Peter Zolja
    Peter Zolja avatar
    119 posts
    Member since:
    Dec 2007

    Posted 06 May 2009 Link to this post

    It's not a particular solution I'm looking for. From what I can tell, this is a design decision that affects a lot of Telerik products.

    The goal is to isolate and condense the JS. Here's an example: When dealing with the RadColorPicker I have a OnClientColorChange property I can use to wire up client-side events. The only thing I can pass to this property is the name of the JavaScript function, let's say ChangeColor. This JS function has to have two parameters: sender and eventArgs. This means that if I have 10 color pickers on a single page I would need 10 ChangeColor JavaScript functions; ChangeColor1, ChangeColor2, etc. 

    What I would like is to have a single ChangeColor function that I would be able to pass parameters to. So, in the ASPX/ASCX rather than writing OnClientColorChange="ChangeColor" it would help if I could write OnClientColorChange="ChangeColor(someid)" where "someid" would of course vary. If I pass the IDs and all the required information via parameters I can even move the JavaScript functions outside of ASPX/ASCX into dedicated .js files. A quick solution would be to have a OnClientColorChangeCustom property that would take precedence over OnClientColorChange if defined; just call that JS function. I'm not familiar with the Telerik internals so I don't know what would be the most elegant solution.

    I hope this make sense, not sure how else I could explain it :)
  4. ManniAT
    ManniAT avatar
    885 posts
    Member since:
    Nov 2003

    Posted 06 May 2009 Link to this post


    just an idea and how I solve this - event with other things than telerik controls since it is typical to have a "sender, args" combination.
    My handlers typical divide the calls depending on the sender (ID).

    I can understand your need (I've been also looking for something like this) but finally it is just a bit "turned around".
    One (your preferred) solution would be to call a handler like "OnSomething(this, MyInfo)" or if "args" has a meaning

    The other way is:
    function MyHandler(sender, args) {
    switch(    {
    case "xxxxx":
    case "rrr":
    FinalHandler(sender, args, thirdParam);

    I know switches and even "ifs" are not extra fast - further I add an extra function call to the scenario.
    BUT - in most cases theses handlers are fired when a user does something - so "hyper performance" is not really needed.

    Just my 2 cents

  5. Peter Zolja
    Peter Zolja avatar
    119 posts
    Member since:
    Dec 2007

    Posted 06 May 2009 Link to this post

    That will work for some specific cases. Here's an example, let's say you have 10 color pickers. When a color is picked I need to do something with that color, let's say I want to color a div. Each color picker is associated with a certain div. The question now is how do you "link" each color picker with the right div? Using what you suggest would involve writing a JS method with a big switch statement. By the way, I'm not worried at all about the switch performance issues. That's "slightly" less typing than making 10 separate functions, but still not ideal. If we could pass the ID of the div that needs to be colored to the method that the color pickers call we could eliminate the switch statement altogether. What's more, I could move that JS function outside of the page since now I don't need to worry about any page specific stuff, everything I need would come in via parameters.

    I can think of three ways to approach this problem:

    1) Give us a second "custom" property that we could use to override the non-custom property. Basically, if that property is not empty use that instead. The downside is that it may confuse some people about the order of importance if they actually provide both.

    2) Have a second "parameter" property. If this is present just append to the JS function. For example: OnClientColorChange="MyFunction" OnClientColorChangeParam="abc,def" and it would expect / call a JS function like this MyFunction(sender, eventArgs, abc, def). The upside is that we'll have access to the sender and eventArgs as well as our custom parameters. The downside is that there's even more magic involved than in #1, so harder to explain.

    3) The first option would be to analyze the property. If there's a "(" inside it means we're trying to call a custom function. 
    Example: If we write OnClientColorChange="MyFunction" then the JS would be MyFunction(sender, eventArgs). If we write OnClientColorChange="MyFunction(someid)" then, since there's a "(" in the string and "(" cannot be part of a function name it should just call MyFunction(someid) instead. The advantage is that we'd not pollute all the control is custom or param properties. The downside is that it'd be hard to discover unless you read the docs and we'd not have access to sender and eventArgs.

    There may be other ways; right now I'm leaning toward #3. So Telerik, what do you guys think?
  6. ManniAT
    ManniAT avatar
    885 posts
    Member since:
    Nov 2003

    Posted 07 May 2009 Link to this post

    Just another thought -- this is nothing "against" your wish for an extra parameter.
    You have - let's say 20 Color pickers - and you want them to change different "parts" of your page.
    So what you wanna do (I guess) is to pass the ID of that control to your function.

    Almost the same as with "my" switch idea - but there is one big difference - the function you thing about could be placed "anywhere" (it does not change) while my approach requires to modify that function.

    By the way - in WindowsForms there is something you think about - it's the Tag property every control has.
    And yes - I also sometimes wished that ASP controls would also have that property.

    Anyhow - even with your solution you make some kind of a contract. You say (just as a sample) Tag will hold the ID oft the control I want to change (the color of it).

    Now the problem arrives - the control ID is dynamic. Instead of "MyDivOne" you may get something like ctl00_MyDivOne.
    Normally you solve this with a little peace of server code <%# MyDivOne.ClientID %>. This will change with ASP.NET 4.0 where you have control over the ID generated. But at the moment it is like it is.

    Anyhow - assume there are ways to "forecast" the ID of the control.
    Back to your contract - "the colorpicker must hold the id of the control to change in it's tag" (or pass it as third parameter to the handler).

    How about a contract - "the colorpicker must have the same ID as the control to change except the first 3 letters which are different".
    So (for an example) the colorpicker for divRightUpperSection must have the name xxxRightUpperSection (copRightUpperSection).
    If you make that contract you can easily (with replace) build the name of the destination controls - and make your changes on it.

    An other contract could be something like "the divs have ids that end with a four digits number". So you could give your colorpicker also a name with 4 digits on the end. In you event handler you can iterate through all your divs and find the one with the same number.

    Or give your colorpickers a name like copMyPickerFORdivRightTop - search the word FOR - and separate the characters behind it.

    These approaches are something like "name decoration" (known from C++).
    And it is more or less "passing the ID of the control to be changed" - but not as an extra parameter - instead we code it into the id of the color picker.

    By the way - you can also turn this by 180 degrees - give your divs a name like divTopRightCHANGED_BYcopOne.

    You are right it may be interesting to have a possibility for adding extra information to a control (or an extra parameter to handlers).
    I'm also interested in what telerik thinks about it.
    BUT - meanwhile there are (more or less elegant) ways to achieve your solution with the currently available handlers.


  7. Peter Zolja
    Peter Zolja avatar
    119 posts
    Member since:
    Dec 2007

    Posted 08 May 2009 Link to this post

    True, either way you go about it you still have some kind of contract. I've actually not thought about relying on the control's name/id. With each approach you get pluses and minuses. My goal is to minimize the contract surface area as much as possible. Close as many gates where problems came come in as possible. If a new person can open a JS file and think "OK, so I receive a source ID and a destination ID, I take the value from source and put it in destination" that would be much simpler than worrying that changing the body of the JS function could break some parts of the application if the prefix length is changed.

    Yes, in my solution, I use and rely on the ClientID. The page is more or less built from zero dynamically from information coming from a database. A control can be a child of any parent and have any number of siblings. For this case the way ClientID works is perfect. The nice thing about <%# somecontrol.ClientID %> is that it's actually enforced by the compiler at runtime -- I'd love for it to be enforced at compile time but that's another story. 

    So if I have: OnClientColorChange='<%# "MyJsFunction('" + somecontrol.ClientID + "');"  %>' 
    It will actually let me know by throwing an exception if "somecontrol" doesn't exist. Yes, I know the example above won't compile, I'd have to actually move that in code behind. 

    If I rely on a human (i.e. myself) to ensure that those matching controls are named properly errors will creep in. You can definitely use your method, and it'll work just fine, but I personally don't trust myself :)
Back to Top