...

View Full Version : Variable function call



Badman3k
02-23-2007, 12:59 PM
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.


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,

BarrMan
02-23-2007, 01:13 PM
Create global variables to pass information between functions.
ie:

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.

Badman3k
02-23-2007, 01:31 PM
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?

Arty Effem
02-23-2007, 02:14 PM
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:
var aItems = new Array( Array("Item1", fnOne), Array("Items", fnTwo));
.
.
aItems[i][1]( this.id );

glenngv
02-23-2007, 11:19 PM
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.

Arbitrator
02-23-2007, 11:42 PM
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:


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);
}
}


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.

glenngv
02-24-2007, 05:18 AM
Not sure if this is a poor way of going about it, but you can use eval() to do this:

Yes it is (http://www.codingforums.com/showthread.php?t=20143). Javascript square bracket notation is the most efficient and appropriate solution.

Arbitrator
02-24-2007, 06:42 AM
Yes it is (http://www.codingforums.com/showthread.php?t=20143). 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:


// 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]();
}


<!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>

glenngv
02-26-2007, 07:52 AM
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.


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);
}
}

Arbitrator
02-27-2007, 01:57 AM
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.


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:

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);
}
}

Pyth007
03-01-2007, 01:09 AM
I believe you can also solve your closure problem using something like:


oDiv.onclick = function(myVar) {
window[aItems[myVar][1]]();
} (i);


Check out my earlier thread (http://www.codingforums.com/showthread.php?t=93648) on a similar question (after re-reading it, I may have misspoken above by calling this a "closure problem"...)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum