javascript variables public or private?

J

jimmygoogle

OK I want to create a menu from an XML file. I am parsing it with JS.
Now it seems to be working fine until it comes time to build the menu.
I am building arrays in JS and the arrays are inside a function. How
can I make these arrays been seen by other functions? Or cant I?

here is an abridged snippet:

var xmlDoc;

if (document.implementation &&
document.implementation.createDocument){
alert ("MOZ");
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.onload = readXML;
}

else if (window.ActiveXObject){
alert ("IE");
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.onreadystatechange = function () {
if (xmlDoc.readyState == 4) readXML()
};
}

else{
alert('Your browser cannot handle this script');
//return;
}

xmlDoc.load("http://brewdente.homedns.org/yellowstone/js/menu.xml");

function readXML(){

.....

eval(parentmenu + '= new Array(' + '"' + labelTxt + '"' + ',' +
'"' + linkTxt + '"' + ',"",' + childrenTxt + ',' + heightTxt + ',' +
widthTxt + ');');

//will look like this
//Menu1=new Array("something","http://","",0,20,225);


} //end readXML

then the rest of the functions are down below. I 'alert' all values
and everything is ok and I even am able to access different elements of
my array inside this function. How can get to these arrays outside of
this function? My code then says 'Menu1' not defined and I believe
scope is the problem. Any ideas?
 
R

RobG

jimmygoogle said:
OK I want to create a menu from an XML file. I am parsing it with JS.
Now it seems to be working fine until it comes time to build the menu.
I am building arrays in JS and the arrays are inside a function. How
can I make these arrays been seen by other functions? Or cant I?

here is an abridged snippet: [...]

function readXML(){

.....

eval(parentmenu + '= new Array(' + '"' + labelTxt + '"' + ',' +

Why eval?

Presuming you have parsed the XML file and put values into the variables
somewhere above, then why not add them to a global object declared
elsewhere (say where you declared xmlDoc):

MenuData[parentmenu] = [labelTxt, linkTxt, childrenTxt,
heightTxt, widthTxt];


Or try something like this:

var MenuData = {};

function parseXML()
{
var pNodes = oLoadedXML.getElementsByTagName("menuitem"),
pNode, cNode, cNodes,
i, j, m, n;

for (i=0, m=pNodes.length; i<m; ++i){
cNodes = pNodes.childNodes;
MenuData['menuitem_' + i] = {};
pNode = MenuData['menuitem_' + i];

for (j=0, n=cNodes.length; j<n; ++j){
cNode = cNodes[j];
if (cNode.tagName){
pNode[cNode.tagName] = (cNode.firstChild
&& cNode.firstChild.nodeValue) || '';
}
}
}

// Debug - show the contents of MenuData
var tmp0, txt = '';
for (var prop in MenuData){
txt += prop + ':\n';
tmp0 = MenuData[prop];
for (var prop0 in tmp0){
txt += prop0 + ': ' + tmp0[prop0] + '\n';
}
}
alert(txt);
// End Debug
}


MenuData contains the data loaded from the XML file and is available
globally, use for..in to get at it. The MenuData object could be
created more generically, over to you.

Have you considered creating DOM elements as you parse the XML and add
them directly to the document? All the stuff in the XML file will then
exist in the DOM which is presumably what the functions 'down below' are
about to do.

You could put your data into a JSON structure, then eval that to get
your object (light on security if cross-domain, read up on the issues) -
check out <URL:http://www.crockford.com/JSON/index.html>

You could also add methods to the MenuData object to get and set
internal properties to hold the data.


[...]
 
R

RobG

RobG wrote:

[...]
You could put your data into a JSON structure, then eval that to get
your object (light on security if cross-domain, read up on the issues) -
check out <URL:http://www.crockford.com/JSON/index.html>

Haven't seen any simple JSON examples, so here's one (I hope...):

[ menu_jsontxt.xml ]

<?xml version='1.0'?>
<jsontext>
{ "menuitem_1" : {
"name" : "1",
"node" : 1,
"parent" : 0,
"label" : "stuff",
"link" : "/about/hobbies/computing.html",
"children" : 0,
"subchildren": 0,
"height" : 20,
"width" : 100
},
"menuitem_2" : {
"name" : "2",
"node" : 2,
"parent" : 0,
"label" : "Computing",
"link" : "/about/hobbies/computing.html",
"children" : 0,
"subchildren": 0,
"height" : 20,
"width" : 100
},
"menuitem_3" : {
"name" : 3,
"node" : 3,
"parent" : 0,
"label" : "things",
"link" : "/about/hobbies/computing.html",
"children" : 0,
"subchildren": 0,
"height" : 20,
"width" : 100
}
}
</jsontext>

[ menu_json.html ]

<script type="text/javascript">

var oLoadedXML;

function loadXML(sImportXML)
{
if( document.implementation &&
document.implementation.createDocument ) {
oLoadedXML = document.implementation.createDocument("","",null);
oLoadedXML.async=false;
var loaded = oLoadedXML.load(sImportXML);
if (loaded) {
parseXML();
}
} else if( window.ActiveXObject && /Win/.test(navigator.userAgent) ) {
oLoadedXML = new ActiveXObject("Msxml.DOMDocument");
oLoadedXML.async = false;
oLoadedXML.onreadystatechange = function () {
if (oLoadedXML.readyState == 4) parseXML();
}
oLoadedXML.load(sImportXML);

} else {
alert("I'm not clever enough to make this script "
+ "work in your browser.");
return;
}
}

var MenuData = {};

function parseXML()
{
var jsonText = oLoadedXML.getElementsByTagName('jsontext');
if ( !jsonText.length ) { return; }

MenuData = eval('(' + jsonText[0].firstChild.nodeValue + ')';

// Just to show the contents of MenuData
var tmp0, txt = '';
for (var prop in MenuData){
txt += prop + ':\n';
tmp0 = MenuData[prop];
for (var prop0 in tmp0){
txt += prop0 + ': ' + tmp0[prop0] + '\n';
}
}
alert(txt);
// End 'just to show'
}

loadXML("menu_jsontxt.xml")

</script>
 
J

jimmygoogle

thanks for input - am i basically making an array of arrays? now if i
want access this array outside the parseXML function how would i? i
need to have an array defined which is accessable by other functions
that reads like

Menu1=new Array("menu1","http://","",0,20,225);
Menu2=new Array("menu2","http://","",0,20,225);

.......
loadXML("menu_jsontxt.xml")
alert( -how would i acces it -)
</script>
 
R

RobG

jimmygoogle said:
thanks for input - am i basically making an array of arrays? now if i

The code I posted creates an object that contains one object for each
menuitem (objects can contain anything, including other objects). I
think you are better to put all the data into one object, rather than
having some unknown number of global variables floating around.

The structure of the object is exactly the same as the menu_jsontxt.xml
file in my second post.

want access this array outside the parseXML function how would i? i

MenuData is a global variable, so you can access it from anywhere once
you create it. It would probably be better for it not to be a global
and for references to be passed around - but without seeing the rest of
your application, I can't say for sure.

need to have an array defined which is accessable by other functions
that reads like

Menu1=new Array("menu1","http://","",0,20,225);
Menu2=new Array("menu2","http://","",0,20,225);

If you load the script I posted and use your menu.xml file, it will show
an alert with the structure of the object.

You can get the data back out using a for..in loop, like the debug part
of my script that displays the contents of the object.

You can get the data explicitly using dot notation:

MenuData.menuitem_1.label is 'stuff'
MenuData.menuitem_1.link is '/about/hobbies/computing.html'

and so on.

......
loadXML("menu_jsontxt.xml")
alert( -how would i acces it -)

alert(MenuData.menuitem_1.label); // shows 'stuff'


[...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,779
Messages
2,569,606
Members
45,239
Latest member
Alex Young

Latest Threads

Top