Global variable visible in different scripts?

S

Sal

I've been searching all over the Internet but can't seem to find an
answer to this simple question. Is is possible to set a global
variable in one script and subsequently access its value in another on
the same page/document/window? Something like:

<head>
<script type="text/javascript">
var myGlobalVar = "Hello, world";
</script>
</head>

<body>
<script type="text/javascript">
document.writeln( myGlobalVar );
</script>
</body>

I tried making the variable a property of the Window object as in
window.myGlobalVar, but that doesn't work either.
 
J

Jukka K. Korpela

I've been searching all over the Internet but can't seem to find an
answer to this simple question. Is is possible to set a global
variable in one script and subsequently access its value in another on
the same page/document/window?

Why wouldn't it be possible? As long as the definition appears before
access, I don't see what problems could arise.
Something like:

<head>
<script type="text/javascript">
var myGlobalVar = "Hello, world";
</script>
</head>

<body>
<script type="text/javascript">
document.writeln( myGlobalVar );
</script>
</body>

Works OK here. What did you get when you tested it?
I tried making the variable a property of the Window object as in
window.myGlobalVar, but that doesn't work either.

Here that works, too. Did you actually test with a more complicated
case? Then the problem is probably elsewhere. URL?
 
S

Sal

Why wouldn't it be possible? As long as the definition appears before
access, I don't see what problems could arise.




Works OK here. What did you get when you tested it?


Here that works, too. Did you actually test with a more complicated
case? Then the problem is probably elsewhere. URL?

I'm embarrassed that I didn't try it as a test case first. Yes, it's
part of a more complicated script. What did you mean by URL?

<head>
<script type="text/javascript">
<!--
var state_array =
{'AL':"Alabama",'AK':"Alaska",'AZ':"Arizona",'AR':"Arkansas",'CA':"California",'CO':"Colorado",'CT':"Connecticut",'DE':"Delaware",'DC':"District
Of
Columbia",'FL':"Florida",'GA':"Georgia",'HI':"Hawaii",'ID':"Idaho",'IL':"Illinois",
'IN':"Indiana", 'IA':"Iowa",
'KS':"Kansas",'KY':"Kentucky",'LA':"Louisiana",'ME':"Maine",'MD':"Maryland",
'MA':"Massachusetts",'MI':"Michigan",'MN':"Minnesota",'MS':"Mississippi",'MO':"Missouri",'MT':"Montana",'NE':"Nebraska",'NV':"Nevada",'NH':"New
Hampshire",'NJ':"New Jersey",'NM':"New Mexico",'NY':"New
York",'NC':"North Carolina",'ND':"North
Dakota",'OH':"Ohio",'OK':"Oklahoma",
'OR':"Oregon",'PA':"Pennsylvania",'RI':"Rhode Island",'SC':"South
Carolina",'SD':"South
Dakota",'TN':"Tennessee",'TX':"Texas",'UT':"Utah",'VT':"Vermont",'VA':"Virginia",'WA':"Washington",'WV':"West
Virginia",'WI':"Wisconsin",'WY':"Wyoming"};
document.forms['myform'].elements['state'].value ];
var window.message; // global variable
function lookupState( state ) {
window.message =
state_array[ document.forms['myform'].elements['state'].value ];
alert( message ); // global var message is visible inside this
function in this script only.
}
//-->
</script>
</head>

<body>
<form> ......
<select name="state" onChange="lookupState(this.form.state);"
style="cursor: pointer; background-color: #EEE"> ...
.....
.....
</form

<script type="text/javascript">
<!--
// global var "message" is not visible here
document.writeln( window.message );
//-->
</script>
</body>
 
E

Elegie

Le 17/06/2011 20:32, Sal wrote :

Hello,
I'm embarrassed that I didn't try it as a test case first. Yes, it's
part of a more complicated script. What did you mean by URL?

When you have an issue with some code, it is a generally-accepted
practice to post a test case demonstrating the issue, or a URL if the
test case appears to be too long to be posted.

By the way, the test case has to be runnable, otherwise readers cannot
reproduce the error, and tell what is an error from a simplification.
document.writeln( window.message );

The document.write method simply writes content to the page. If the page
is being loaded, then it writes the content at the point it is defined,
otherwise (if the page is already loaded) it starts writing a new page.

In your case, the "message" variable is empty when document.write is
called, so it writes a glaring empty string. Your listener, which sets
the "message" variable, is called when a user changes the value of the
select box, way after the document.write call (to put it differently:
the view is not reloaded with your listener, so document.write is not
called again).

What do you want to do? Write some text dynamically on the current page?
If so, have a look at:
<URL:http://www.jibbering.com/faq/#updateContent>. If you want to keep
some state between client views, then consider using cookies (though
other client-side techniques exist, cookies are the simplest way).

HTH,
Elegie.
 
S

Sal

Le 17/06/2011 20:32, Sal wrote :

The document.write method simply writes content to the page. If the page
is being loaded, then it writes the content at the point it is defined,
otherwise (if the page is already loaded) it starts writing a new page.

In your case, the "message" variable is empty when document.write is
called, so it writes a glaring empty string. Your listener, which sets
the "message" variable, is called when a user changes the value of the
select box, way after the document.write call (to put it differently:
the view is not reloaded with your listener, so document.write is not
called again).

Thank you for an excellent explanation. I originally had this as a PHP
script and was trying to avoid a server call with $_SERVER["PHP_SELF"].
 
T

Thomas 'PointedEars' Lahn

Stefan said:
Here's how I would write it:

<!DOCTYPE html>
<html>
<head>
<title>Testing state selection</title>
<script>
var stateMap = {
AL: "Alabama",
// etc
WY: "Wyoming"
};
function lookupState (stateCode) {
alert(stateMap[stateCode]);
}
</script>
</head>
<body>
<form name="myform">
<select name="state" onchange="lookupState(this.value)">
<option>AL</option>
<!-- etc -->
<option>WY</option>
</select>
</form>
</body>
</html>

This form does not need a name. Passing `this' to lookupState() instead of
`this.value' conveniently allows to use `stateCode.value' in place of
`stateCode', and `stateCode.form' to refer to the control's form (so the
argument should probably be renamed then).

Besides, `this.value' is not compatible; use
`this.options[this.selectedIndex].value' instead, and be sure that
this.selectedIndex is greater than or equal to 0. (Which means that the
`option' elements should have a `value' attribute each, which would also
facilitate a more accessible display of the state names.)

Proper indentation (whereas 2 spaces should be sufficient, and more suitable
for a newsgroup posting) would suggest indenting the `script' and `select'
element content, too. An exception may be made in the case of the `html'
root element.


PointedEars
 
D

Denis McMahon

Denis and Stefan, thank you so much for all your help. Denis, I don't
know what you're doing in your setup() function. Can you explain or
point me toward a tutorial? Thanks again guys.

Ok, quick explanation:

This html:

<body onload="setup()">

calls the setup function after the document has loaded.

The select list starts out with a single option:

<select id="state" onchange="lookupState();">
<option value="00">Please Choose</option>
</select>

Note that I have given the select element an id property, this makes
referring to it easier.

elId() is shorthand for document.getElementById()

function elId(id) {
return document.getElementById(id);
}

The setup function does two things. It creates the option list for the
html select element based on the properties of the state_array object,
and then it sets the currently selected item to index 0 (first option in
the list):

function setup() {
var v, t, o; // declare variables
for (v in state_array) { // loop through state_array props
t = state_array[v]; // get value of property v
o = document.createElement("option"); // create an option element
o.text = t; // set new option text to t
o.value = v; // set new option value to property name
elId("state").add(o,null); // add new option o at end of select
// element with id "state"
}
elId("state").selectedIndex = 0; // set select element with id
// "state" to first option
}

It could actually be shorter, there's no need to assign t, so the
statement:

t = state_array[v];

can be removed, and the statement

o.text = t;

can be replaced with:

o.text = state_array[v];

This change also means that "t" can be removed from the variable
declaration.

There is also an optimisation that can be made. If you add a declaration
for s to the var statement, and define s before the for loop as:

var s, v, o;
s = elId("state");
for .......

then inside the loop, you can replace:

elId("state").add(o, null);

with:

s.add(o, null);

which saves two function calls for each time through the loop: the call
to elId(), and the wrapped call to document.getElementById(). Not likely
to be a performance issue with 50 odd iterations of the loop, but worth
considering for larger objects.

Rgds

Denis McMahon
 
S

Sal

Denis and Stefan, thank you so much for all your help. Denis, I don't
know what you're doing in your setup() function. Can you explain or
point me toward a tutorial? Thanks again guys.

Ok, quick explanation:

This html:

<body onload="setup()">

calls the setup function after the document has loaded.

The select list starts out with a single option:

<select id="state" onchange="lookupState();">
<option value="00">Please Choose</option>
</select>

Note that I have given the select element an id property, this makes
referring to it easier.

elId() is shorthand for document.getElementById()

function elId(id) {
    return document.getElementById(id);
    }

The setup function does two things. It creates the option list for the
html select element based on the properties of the state_array object,
and then it sets the currently selected item to index 0 (first option in
the list):

function setup() {
    var v, t, o; // declare variables
    for (v in state_array) { // loop through state_array props
        t = state_array[v]; // get value of property v
        o = document.createElement("option"); // create an option element
        o.text = t; // set new option text to t
        o.value = v; // set new option value to property name
        elId("state").add(o,null); // add new option o at end of select
                                   //element with id "state"
        }
    elId("state").selectedIndex = 0; // set select element with id
                                     // "state" to first option
    }

It could actually be shorter, there's no need to assign t, so the
statement:

t = state_array[v];

can be removed, and the statement

o.text = t;

can be replaced with:

o.text = state_array[v];

This change also means that "t" can be removed from the variable
declaration.

There is also an optimisation that can be made. If you add a declaration
for s to the var statement, and define s before the for loop as:

var s, v, o;
s = elId("state");
for .......

then inside the loop, you can replace:

elId("state").add(o, null);

with:

s.add(o, null);

which saves two function calls for each time through the loop: the call
to elId(), and the wrapped call to document.getElementById(). Not likely
to be a performance issue with 50 odd iterations of the loop, but worth
considering for larger objects.

Rgds

Denis McMahon

Thanks Denis, for a great explanation. This is exactly what I was
trying to accomplish in my original flawed script.
 
M

MC

Denis,
Doesn't this accomplish the same thing much simpler? Or did I miss
something?
MC

com.mySpace.StateUSCd = [ ["",""], ["AL","Alabama"], ["AK","Alaska"],
["AR","Arkansas"],....];
for (var j=0; j<com.mySpace.StateUSCd.length; j++) {
document.myForm.myElement.options[j+1] = new
Option(com.mySpace.StateUSCd[j][1],com.mySpace.StateUSCd[j][0]);
 
D

Denis McMahon

Denis,
Doesn't this accomplish the same thing much simpler? Or did I miss
something?
MC

com.mySpace.StateUSCd = [ ["",""], ["AL","Alabama"], ["AK","Alaska"],
["AR","Arkansas"],....];
for (var j=0; j<com.mySpace.StateUSCd.length; j++) {
document.myForm.myElement.options[j+1] = new
Option(com.mySpace.StateUSCd[j][1],com.mySpace.StateUSCd[j][0]);

What form?

The example I gave has no form element, you should only need[1] a form if
you're submitting with get or post.

The following works,

function setup() {
var s, v, o;
s = elId("state");
for (v in state_array) s.add(new Option(state_array[v], v), null);
elId("state").selectedIndex = 0;
}

but other complexes changes you suggest require converting the
state_array object into an array of arrays. At the moment, state_array is
an object with properties of the form

state_array.XX = "name of state with abbrev XX"

rather than an array of arrays with

state_array[x][0] = abbrev state name of state number x
state_array[x][1] = full state name of state number x

Rgds

Denis McMahon

[1] And even then, it can be done[2] in javascript without it.
[2] For some values of done.
 
M

MC

Denis McMahon said:
Denis,
Doesn't this accomplish the same thing much simpler? Or did I miss
something?
MC

com.mySpace.StateUSCd = [ ["",""], ["AL","Alabama"], ["AK","Alaska"],
["AR","Arkansas"],....];
for (var j=0; j<com.mySpace.StateUSCd.length; j++) {
document.myForm.myElement.options[j+1] = new
Option(com.mySpace.StateUSCd[j][1],com.mySpace.StateUSCd[j][0]);

What form?

The example I gave has no form element, you should only need[1] a form if
you're submitting with get or post.

The following works,

function setup() {
var s, v, o;
s = elId("state");
for (v in state_array) s.add(new Option(state_array[v], v), null);
elId("state").selectedIndex = 0;
}

but other complexes changes you suggest require converting the
state_array object into an array of arrays. At the moment, state_array is
an object with properties of the form

state_array.XX = "name of state with abbrev XX"

rather than an array of arrays with

state_array[x][0] = abbrev state name of state number x
state_array[x][1] = full state name of state number x

Rgds

Denis McMahon

[1] And even then, it can be done[2] in javascript without it.
[2] For some values of done.

Denis,

Its not really complex.
1. I have just given the state array a namespace for clarity. Some websites
might use different versions of a state array such that
com.sellCarsInUS.StateUSCd vs com.sellCarsInCA.StateCACd (Cd indicates a
list in some language notations).
2. I reference the element in the form directly so that I don't have the hit
on performance of looking the element up every iteration.
3. A multi-demensioned array such as ["AL","Alabama"], is giving me the
abreviaton AND the state. Not always needed true. It also allows me to do
validations such as adding ["AL","Alabama","minPostalCode","maxPostalCode"].
Returning a state abbreviation such as 'MO' is much more descriptive than
say '17'.
4. This is the days of HTML 5 dynamicity and many websites will be using
multiple forms per page, such as if (iPhone) do formIPhone else do
(flashForm). I have one web page that has over 15 forms in a single page.

MC
 
D

Dr J R Stockton

In comp.lang.javascript message <9675e6cd-7a01-4777-88be-77bcb9ceef24@22
g2000prx.googlegroups.com>, Fri, 17 Jun 2011 09:58:37, Sal
I've been searching all over the Internet but can't seem to find an
answer to this simple question. Is is possible to set a global
variable in one script and subsequently access its value in another on
the same page/document/window? Something like:

<head>
<script type="text/javascript">
var myGlobalVar = "Hello, world";
</script>
</head>

<body>
<script type="text/javascript">
document.writeln( myGlobalVar );
</script>
</body>

I tried making the variable a property of the Window object as in
window.myGlobalVar, but that doesn't work either.

The code posted, transferred by copy'n'paste to a file $1.htm, works in
Win XP sp3 Firefox 3.6.17, Opera 11.11, Chrome 12.0, Safari 5.0.5, IE 8.
It also works in Firefox (others not tried) with window.myGlobalVar.

I do it all the time with scripts in the body, and with an include
script and a body script. Indeed, I set a var at the end of each
include file, and check it at the start of each page using it. That
saves a lot of confusion if the include file gets damaged.
 
D

Denis McMahon

function setup() {
var s, v, o;
s = elId("state");
for (v in state_array) s.add(new Option(state_array[v], v), null);
elId("state").selectedIndex = 0;
}
Its not really complex.

When I re-read it, complex may have been the wrong word.
1. I have just given the state array a namespace for clarity.

The OP has a single object called state_array. He probably doesn't need
to worry about namespaces. Examples are best kept simple. My example
isn't about using namespaces, it's about achieving what I believe the OP
wants in as browser-compatible as possible a manner as I can.
2. I reference the element in the form directly so that I don't have the
hit on performance of looking the element up every iteration.

Yes, but you can avoid that by moving the lookup outside the loop. The
trade-off tends to be memory vs performance. In the case of the OP's
requirement, both are probably in plentiful supply on almost any platform
his page is likely to be displayed on.
3. A
multi-demensioned array such as ["AL","Alabama"], is giving me the
abreviaton AND the state. Not always needed true. It also allows me to
do validations such as adding
["AL","Alabama","minPostalCode","maxPostalCode"]. Returning a state
abbreviation such as 'MO' is much more descriptive than say '17'.

See my reply to #1.
4. This is the days of HTML 5 dynamicity and many websites will be using
multiple forms per page, such as if (iPhone) do formIPhone else do
(flashForm). I have one web page that has over 15 forms in a single
page.

See my reply to #1.

I don't dispute the points that you're making, but in the context of the
OP's request, I suspect that such a level of complexity (and maybe
complex was the right word after all) is not needed. There's no need to
over-engineer the OP's requirement. Let's get him crawling across the
room before we make him run marathons.

Rgds

Denis McMahon
 
E

Evertjan.

Stefan Weiss wrote on 03 jul 2011 in comp.lang.javascript:
Stefan Weiss wrote:
<select name="state" onchange="lookupState(this.value)"> ...
Besides, `this.value' is not compatible; use
`this.options[this.selectedIndex].value' instead

Not compatible with what? Which browser doesn't support select.value?

I'm honestly interested in this. I remember that in the Olden Days, I
used to use the form you recommend -

selectOne.options[this.selectedIndex].value

- to get the value of the selected option. At some point, I realized
that every browser of interest also returned the correct value with the
much simpler form

selectOne.value

I haven't run into any problems with this. Is there a case for still
using the verbose form today? (Was there ever?)
<select
onchange="alert(this.value);
alert(this.options[this.selectedIndex].innerHTML);"
<option>AL</option>
<option>WY</option>
</select>

Fine on Chrome, first alert() empty on IE9 [local]
 
S

Stanimir Stamenkov

03 Jul 2011 16:19:34 GMT, /Evertjan./:
Stefan Weiss wrote on 03 jul 2011 in comp.lang.javascript:
selectOne.value

I haven't run into any problems with this. Is there a case for still
using the verbose form today? (Was there ever?)

<select
onchange="alert(this.value);
alert(this.options[this.selectedIndex].innerHTML);" >
<option>AL</option>
<option>WY</option>
</select>

Fine on Chrome, first alert() empty on IE9 [local]

Fine on IE9 here. First alert() is empty in any other than the IE9
default mode (e.g. IE8, IE7, Quirks). I've noticed if <option>s get
explicit value="..."s, it works with other IE modes, also.
 
R

RobG

Stefan Weiss wrote:
          <select name="state" onchange="lookupState(this.value)"> ...
Besides, `this.value' is not compatible; use
`this.options[this.selectedIndex].value' instead
Not compatible with what? Which browser doesn't support select.value?

I'm honestly interested in this. I remember that in the Olden Days, I
used to use the form you recommend -

   selectOne.options[this.selectedIndex].value

- to get the value of the selected option. At some point, I realized
that every browser of interest also returned the correct value with the
much simpler form

   selectOne.value

I haven't run into any problems with this. Is there a case for still
using the verbose form today? (Was there ever?)

I think the use of select.options[select.selectedIndex] dates back to
a version of Netscape, and perhaps IE 5 or similar. Any browser
equivalent to IE 6 or later seems to support. A bigger issue is IE's
not sending back the text when no value attribute or property has been
set.

But that's really only an issue for general purpose libraries (which
must also deal with the case of an empty value attribute), it can be
avoided by always providing a value attribute.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top