Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    Regular Coder
    Join Date
    Jun 2002
    Location
    Edinburgh, UK
    Posts
    402
    Thanks
    2
    Thanked 1 Time in 1 Post

    Variable function call

    I want to be able to have an array of items, which I add to the DOM. One of the values in the multi-dimension array is a string that I want to use to call a different function. How do I go about doing this?

    This example may help to make things more clear, if they aren't already.

    Code:
    var aItems = new Array(
          Array("Item1", "fnOne"),
          Array("Items", "fnTwo")
    );
    
    function initialise() {
          for (i = 0; i < aItems.length; i++) {
                oDiv = document.createElement('div');
                oDiv.id = aItems[i][0];
                oDiv.onclick = function () {
                      aItems[i][1]();
                }
                document.body.appendChild(oDiv);
          }
    }
    Then to top it off, how do I pass variables to the called function?! i.e. the simple hard coded way would be to do something like: fnOne(this.id);

    Many thanks in advance,
    Rich

    "An expert is a person who has made all the mistakes that can be made in a very narrow field."

  • #2
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Create global variables to pass information between functions.
    ie:
    Code:
    var myText = "hello";
    function changeText()
    {
    myText = "world";
    }
    function writeText()
    {
    alert(myText);
    }
    Once you call changeText, the value of myText is changed and when you call writeText, you'll get the new value of it.

  • #3
    Regular Coder
    Join Date
    Jun 2002
    Location
    Edinburgh, UK
    Posts
    402
    Thanks
    2
    Thanked 1 Time in 1 Post
    Thanks for replying, but I don't think you've understood the problem. I don't want to pass a variable to different functions, I want the basically use the value within the variable and call it as if it were a function:

    aVariable = "fnOne";
    //now call the function:
    aVariable();
    //...
    //...
    fnOne() {
    // Do some stuff in here
    }

    Does that make any more sense?
    Rich

    "An expert is a person who has made all the mistakes that can be made in a very narrow field."

  • #4
    Banned
    Join Date
    May 2006
    Location
    England
    Posts
    664
    Thanks
    0
    Thanked 84 Times in 84 Posts
    Quote Originally Posted by Badman3k View Post
    I want to be able to have an array of items, which I add to the DOM. One of the values in the multi-dimension array is a string that I want to use to call a different function. How do I go about doing this?
    Store a reference to the function, i.e. its name:
    Code:
    var aItems = new Array( Array("Item1", fnOne), Array("Items", fnTwo));
    .
    .
    aItems[i][1]( this.id );

  • #5
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,042
    Thanks
    0
    Thanked 251 Times in 247 Posts
    Code:
    oDiv.onclick = function () {
        window[aItems[i][1]]();
    }
    Global functions and variables can be accessed via the global window object. See square bracket notation link in my sig for more info on this.

  • #6
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by Badman3k View Post
    One of the values in the multi-dimension array is a string that I want to use to call a different function. How do I go about doing this?
    Not sure if this is a poor way of going about it, but you can use eval() to do this:

    Code:
    function initialise() {
      for (var i = 0; i < aItems.length; i++) {
        oDiv = document.createElement('div');
        oDiv.id = aItems[i][0];
        eval("oDiv.onclick = function() {"\
          + aItems[i][1] + "();\
          }");
        document.body.appendChild(oDiv);
        }
      }
    Quote Originally Posted by Badman3k View Post
    Then to top it off, how do I pass variables to the called function?!
    The this variable is automatic for a function called by a registered event (if not registered inline); whatever element that the event is associated with automatically gets the this keyword. If you need to pass other variables, just pass them normally using the code above.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #7
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,042
    Thanks
    0
    Thanked 251 Times in 247 Posts
    Quote Originally Posted by Arbitrator View Post
    Not sure if this is a poor way of going about it, but you can use eval() to do this:
    Yes it is. Javascript square bracket notation is the most efficient and appropriate solution.

  • #8
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by glenngv View Post
    Yes it is. Javascript square bracket notation is the most efficient and appropriate solution.
    Well, I’m interested in how this works, but it doesn’t seem to make sense; how does the associative array make the variable i static for the generated output? Inserting the code you provided in your last post, you get the following (see end of post) and it doesn’t seem to work.

    I expect to have the following events registered, but i is still sitting there (as an undefined variable), so the script fails:

    Code:
    // Template
    oDiv.onclick = function() {
      window[aItems[i][1]]();
      }
    
    // Expected (Effective) Output
    oDiv.onclick = function() { // Associated with oDiv A
      aItems[0][1]();
      }
    oDiv.onclick = function() { // Associated with oDiv B
      aItems[1][1]();
      }
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
      "http://www.w3.org/TR/html4/strict.dtd">
    
    <html lang="en-US">
      <head>
    
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
        <title>HTML 4.01 Strict Document</title>
    
        <style type="text/css">
          * { margin: 0; }
          html { padding: 1em; }
        </style>
    
        <script type="text/javascript">
          var aItems = [["Item1", "fnOne"], ["Items", "fnTwo"]];
          function initialise() {
            for (var i = 0; i < aItems.length; i++) {
              var oDiv = document.createElement('div');
              oDiv.id = aItems[i][0];
              oDiv.onclick = function() {
                window[aItems[i][1]]();
                }
              oDiv.appendChild(document.createTextNode("Hello " + i));
              document.body.appendChild(oDiv);
              }
            }
          function fnOne() {
            alert("f1");
            }
          function fnTwo() {
            alert("f2");
            }
        </script>
    
      </head>
      <body onload="initialise()">
    
        <p>Test</p>
    
      </body>
    </html>
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #9
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,042
    Thanks
    0
    Thanked 251 Times in 247 Posts
    I didn't realize there was a variable inside the onclick handler. The easiest solution for this is to attach the i as a custom attribute in the div.
    Code:
    function initialise() {
            for (var i = 0; i < aItems.length; i++) {
              var oDiv = document.createElement('div');
              oDiv.id = aItems[i][0];
              oDiv.ctr = i; //create a custom attribute named ctr
              oDiv.onclick = function() {
                alert(this.ctr  + "\n" + aItems[this.ctr][1]); //test
                window[aItems[this.ctr][1]]();
                }
              oDiv.appendChild(document.createTextNode("Hello " + i));
              document.body.appendChild(oDiv);
              }
            }

  • #10
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by glenngv View Post
    I didn't realize there was a variable inside the onclick handler. The easiest solution for this is to attach the i as a custom attribute in the div.
    That works, though I’m still not quite sure why it only works when the associative array is used.

    I changed the initialise function a bit to make it so that the DTD need not be altered to accommodate a custom attribute. It gets more complicated if you use multiple class names on the element though.

    Code:
    function initialise() {
      for (var i = 0; i < aItems.length; i++) {
        var oDiv = document.createElement('div');
        oDiv.id = aItems[i][0];
        oDiv.className = "a" + i;
        oDiv.onclick = function() {
          window[aItems[this.className.charAt(1)][1]]();
          }
        oDiv.appendChild(document.createTextNode("Hello " + i));
        document.body.appendChild(oDiv);
        }
      }
    Or W3C DOM-Compliant:
    Code:
    function initialise() {
      for (var i = 0; i < aItems.length; i++) {
        var oDiv = document.createElement('div');
        oDiv.id = aItems[i][0];
        oDiv.className = "a" + i;
        oDiv.addEventListener("click", function() {
          document.defaultView[aItems[this.className.charAt(1)][1]]();
          }, false);
        oDiv.appendChild(document.createTextNode("Hello " + i));
        document.body.appendChild(oDiv);
        }
      }
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #11
    Regular Coder
    Join Date
    Sep 2005
    Posts
    535
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I believe you can also solve your closure problem using something like:
    Code:
    oDiv.onclick = function(myVar) {
      window[aItems[myVar][1]]();
    } (i);
    Check out my earlier thread on a similar question (after re-reading it, I may have misspoken above by calling this a "closure problem"...)
    Last edited by Pyth007; 03-01-2007 at 12:17 AM. Reason: Connecting to earlier thread
    If you want answers, write a smart question.

    Yes, someone probably does know how...

    Oh, and if you want to learn, STFW!


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •