Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Converting object name to string for eval and innertext

Status
Not open for further replies.

linchat

Programmer
Mar 22, 2008
7
0
0
US
In the below code I have "mainTable" which is the name of an object I am using in my code. This code as it is, works fine. But.....

cell.innerHTML = '<a href="#" onclick="eval(\'fillNewCol(mainTable,1)\')">Add More +</a>';

If I change it to this obj.tablename, I am getting errors. It as if obj.tablename itself is being passed instead of its string value.

obj.tablename = mainTable;

cell.innerHTML = '<a href="#" onclick="eval(\'fillNewCol('+obj.tablename+',1)\')">Add More +</a>';
 
First of all, I would strongly recommend not using eval as many experienced javascript programmers would advise. I'm not sure I understand what your saying, but it sounds like your trying to pass an object as a parameter to a function. In that case:
Code:
cell.innerHTML = '<a href="#" onclick="fillNewCol(obj.tablename,1)">Add More </a>';
should work.
 
When I do that, I get an error saying obj is not defined. Maybe I should have clarified.

var mainTable = new objTable1();
mainTable.tablename = "grid";
mainTable.intRowSize = 2;
mainTable.intColSize = 2;

/*
* obj.tablename contains the name of a table.
*/
function test(obj)
{
cell.innerHTML = '<a href="#" onclick="fillNewCol(obj,1)">Add More +</a>';
}

function fillNewCol(obj)
{
alert('I now have the mainTable object');
}

So with this, I would load the page and in the body onload=test(mainTable). (There would be other coad in "test" which innerHTML would know where to write the innerHTML.)

1. Load page onload=test(mainTable)
2. User would click the on "onclick" statement and function fillnewcol would be called, sending a reference of the mainTable object.

Problem, seems to be around the innerHTML statement, it is screwing things up. When I check the variable, it is not passing obj.tablename (which would be mainTable) it is passing the name 'obj' not as a reference, but as a value.
 
One more thing, basically I want the result of the innerHTML statment, if you could see it on a page... To look like this.

EXAMPLE:
<a href="#" onclick="fillNewCol(mainTable,1)">Add More +</a>


This below would give me the above statement.

cell.innerHTML = '<a href="#" onclick="fillNewCol('mainTable',1)">Add More +</a>';

This will fail even though obj.tablename = mainTable

cell.innerHTML = '<a href="#" onclick="fillNewCol('+obj.tablename+',1)">Add More +</a>';

It is treating obj.tablename is a variable I suppose instead of a strong. I do not know how else to explain it. I just want the above statment to produce the EXAMPLE at the top of this post. For some reason, with the innerHTML, where a variable is used to suppy the value js is conking out. It thiks I am trying to pass a variable or something. I need obj.tablename as a string.
 
I messed up on the above post, part of it should read:


This below would give me the above statement.

cell.innerHTML = '<a href="#" onclick="fillNewCol(mainTable,1)">Add More +</a>';
 
Hey, I think I understand the problem. You're trying to use a reference to a local variable in your innerHTML. When the function test(obj) finishes, that obj variable no longer exist, so javascript searches for a global variable of that name; it doesn't exist and thats where your running into problems. Heres a quick example:
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "[URL unfurl="true"]http://www.w3.org/TR/html4/strict.dtd">[/URL]
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<title>Image Scroller</title>
<script type="text/javascript">
var mainTable = new objTable1();
mainTable.tablename = "grid";
mainTable.intRowSize = 2;
mainTable.intColSize = 2;

function objTable1() {

}

/*
* obj.tablename contains the name of a table.
*/
function test(obj)
{
   var a = document.createElement('a');
   a.setAttribute('href', '#');
   a.onclick = function() {
      fillNewCol(obj.tablename, 1);
   }
   a.appendChild(document.createTextNode('Add More +'));

   document.body.appendChild(a);
}

function fillNewCol(obj, num) {
   alert(obj);
}
</script>
</head>
<body onload="test(mainTable);">

</body>
</html>
There may be other ways to do this, but hopefully it's something similar to what your looking for.
 
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script>

	function objTable1()
	{
		this.tablename = "testTag";
		this.intRowSize = 2;
		this.intColSize = 2;
	}

	var mainTable = new objTable1();
		
	
	function makeTestTag(obj)
	{
		document.getElementById(obj.tablename).innerHTML = '<a href="#" onclick="printNewLine('+obj.tablename+')">Check object</a>';
	}
	
	function printNewLine(obj)
	{
		alert(obj.tablename + ' You should have \'testTag\' for obj.tablename');
	}
</script>
</head>

<body>
<div id="testTag" onclick="makeTestTag(mainTable)">Click me</div>
</body>
</html>

Your previous post helps a great deal. It solves another problem. How can I make this one work, this is where I am trying to get to. To pass the object.
 
I tweaked your code for my project and everything works out great. Object will pass, question is, why?

Why did your code:

Code:
a.onclick = function() {
      fillNewCol(obj.tablename, 1);
   }

Versus my code

Code:
innerHTML = '<a href="#" onclick="fillNewCol(obj,1)">Add More +</a>';

Are they not essentially the same? Why would your code pass the object and my code would not?

I can change yours just to pass the complete object (obj) and everything works fine. Is it something with innerHTML?
 
The reason that code works is because of closures. It is somewhat of a confusing concept but Google 'javascript closures'. Essentially, if you declare an inner function, that is, a function inside a function, the inner function has access to the variables in the outside function. Because of this, the variables in the outside function do not get destroyed when the function ends. The way you were doing it, the obj parameter was destroyed when your function ended, and thus that reference no longer exist. So it would look for a global variable with the name obj, and wouldn't find it.

I'm still learning this concept, so if anyone sees something wrong, please feel free to correct me.
 
The simplest way to see why some variations of directly assigning a string containing html fragment cannot set up the passing of "object" itself is this.

[1]>cell.innerHTML = '<a href="#" onclick="fillNewCol(obj,1)">Add More +</a>';
Here obj is within a string. It set up the anchor onclick with passing something called obj to the handler. But obj there has nothing to do with the obj in the function test(obj).

[2] A variation of passing successfully obj.tablename is this: the variation is trying to pass the obj itself.
[tt]cell.innerHTML = '<a href="#" onclick="fillNewCol('+obj+',1)">Add More +</a>';
} //wrong
[/tt]
In this format, obj is recognized as the obj in the function test(obj) passed in as an argument. But, the right-hand-side is a string concatination. Any object at that position will be converted to string. How? The object will inherit the .toString() method from its superclass to do the conversion. Hence it is equivalent at its place to be scripted like:
[tt] ... + obj.toString() + ...[/tt]
But the obj.toString() actually is becoming
[tt] ... + [object Object] + ...[/tt]
Hence, any reference to obj itself is lost.

Directly assign the <a href=... onclick=...>...</a> to cell.innerHTML will be successful if the arguments to the onclick handler be a string (such as "mainTable" the name of the global variable - quite non-generic way to do thing, or obj.tablename, here testTag, etc...), but the syntax would not allow passing "object" directly for the above reason.

[3] As an aside, after you successfully set up an anchor inside the div, the onclick event will bubble: even though you probably won't notice it. The anchor is every time redrawn which is probably not what you intend to do. Hence, to make it conceptually neat, you have to eliminate the onclick handler of the div itself. Hence, the setup should start with eliminate the div's onclick handler. The easiest and more graphic way is to do it like this.
[tt]
function makeTestTag(obj)
{
[blue]document.getElementById("testTag").onclick=function(){};[/blue]
//continue the rest...
}
[/tt]
 
Wasn't your very original example missing a set of quotes? String values must always be quoted... Your hard-coded one ('mainTable') was, but the one you were passing was not:

Code:
cell.innerHTML = '<a href="#" onclick="eval(\'fillNewCol([!]\'[/!]' + obj.tablename + '[!]\'[/!], 1)\')">Add More +</a>';

I'm guessing that unless "fillNewCol" returns any JS code, you don't need the eval, either:

Code:
cell.innerHTML = '<a href="#" onclick="fillNewCol([!]\'[/!]' + obj.tablename + '[!]\'[/!], 1)">Add More +</a>';

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top