homepage Welcome to WebmasterWorld Guest from 54.161.202.106
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
How to define a global variable for all the functions
Rain_Lover




msg:4407665
 12:24 pm on Jan 17, 2012 (gmt 0)

Hi,

Here's a sample form:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Sample form</title>
<script type="text/javascript">
function displayResult() {
alert(document.myForm.myInput.value);
}
function getFocus() {
if (document.myForm.myInput.value == document.myForm.myInput.defaultValue) {
document.myForm.myInput.value = "";
}
}
function loseFocus() {
if (document.myForm.myInput.value == "") {
document.myForm.myInput.value = document.myForm.myInput.defaultValue;
}
}
</script>
</head>
<body>
<form name="myForm" method="get" onsubmit="return false;" action="">
<input name="myInput" value="Hello world!" onfocus="getFocus();" onblur="loseFocus();"><br>
<input type="button" onclick="displayResult();" value="Display input value">
</form>
</body>
</html>


It works with no problem, but the following doesn't:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Sample form</title>
<script type="text/javascript">
var x = document.myForm.myInput;
function displayResult() {
alert(x.value);
}
function getFocus() {
if (x.value == x.defaultValue) {
x.value = "";
}
}
function loseFocus() {
if (x.value == "") {
x.value = x.defaultValue;
}
}
</script>
</head>
<body>
<form name="myForm" method="get" onsubmit="return false;" action="">
<input name="myInput" value="Hello world!" onfocus="getFocus();" onblur="loseFocus();"><br>
<input type="button" onclick="displayResult();" value="Display input value">
</form>
</body>
</html>


What's wrong with it and how can I define a global variable to be used by all the functions?

Many thanks in advance!
Mike

 

penders




msg:4407672
 1:41 pm on Jan 17, 2012 (gmt 0)

You define a global variable exactly as you have done, outside of any functions.

However, the problem with your script is that you are assigning the INPUT control to your global variable before the INPUT control has actually been defined in the document (before it is part of the DOM). So it is 'undefined'.

You need to assign the INPUT control to your global variable after it has been defined. Either in the onload event or some point after it in the markup...

<form name="myForm" method="get" onsubmit="return false;" action=""> 
<input name="myInput" value="Hello world!" onfocus="getFocus();" onblur="loseFocus();"><br>
<input type="button" onclick="displayResult();" value="Display input value">
</form>
<script type="text/javascript">
var x = document.myForm.myInput;
</script>
</body>
</html>

Fotiman




msg:4407706
 2:39 pm on Jan 17, 2012 (gmt 0)

In general, it's best to place your scripts at the very end of your document, just before the closing </body> tag. In addition to having everything in the DOM available to you at that point, it's also better performing.

Rain_Lover




msg:4407791
 5:13 pm on Jan 17, 2012 (gmt 0)

Dear penders and Fotiman,

Thanks for the answers and clarification!

@Fotiman,

No disagreement, but I just wonder what you think of the following:

Functions can be defined both in the <head> and in the <body> section of a document. However, to assure that a function is read/loaded by the browser before it is called, it could be wise to put functions in the <head> section.


Source: [w3schools.com ]

rocknbil




msg:4407801
 5:26 pm on Jan 17, 2012 (gmt 0)

^^ @ Fotiman: you've said this often, how is it superior to window.onload = function() {};? Just curious.

I try to avoid globals altogether. Pass parameters. Here's another one to pick apart. :-)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Sample form</title>
<script type="text/javascript">
window.onload=function() { attachBehaviors(); }
// Attach behaviors and say NO to inline JS. :-)
function attachBehaviors() {
var obj = document.getElementById('myInput');
if (obj) {
obj.onfocus=function() {
if (obj.value==obj.defaultValue) { obj.value=''; }
}
obj.onblur=function() {
if (obj.value=='') { obj.value=obj.defaultValue; }
}
} // if obj
var frm = document.getElementById('myForm');
if (frm) {
frm.onsubmit=function() { return displayResult(); }
}
} // function
//
function displayResult() {
var obj = document.getElementById('myInput');
if (obj) {
alert((obj.value=='')?'No Value!':obj.value);
}
return false;
}
</script>
</head>
<body>
<form name="myForm" id="myForm" method="get" action="">
<p>When you move to the button you blur. So to see the effect of
&quot;no value&quot; click into the text field and press enter.</p>
<p><input name="myInput" id="myInput" value="Hello world!"></p>
<p><input type="submit" value="Display input value"></p>
</form>
</body>
</html>

Rain_Lover




msg:4407812
 5:38 pm on Jan 17, 2012 (gmt 0)

@rocknbil,

Works well, but harder to understand for a newbie like me!

Thanks anyway! :)

Fotiman




msg:4407845
 6:29 pm on Jan 17, 2012 (gmt 0)

@Rain_Lover, much of what is on w3schools is just terrible advice. :)

However, to assure that a function is read/loaded by the browser before it is called

If you avoid inline scripts (another good recommendation for maintaining separation of content and behavior), then this won't be an issue.

Fotiman




msg:4407864
 6:51 pm on Jan 17, 2012 (gmt 0)


^^ @ Fotiman: you've said this often, how is it superior to window.onload = function() {};? Just curious.

Because script elements will block the downloading of other page components (images, etc.) until the script has been loaded. Putting them in the head of your document means your page may have a less responsive feel to it. Including them as late as possible can improve the perceived and actual page loading time.

rocknbil




msg:4408233
 5:59 pm on Jan 18, 2012 (gmt 0)

Works well, but harder to understand for a newbie like me!


Nothing is that difficult if you break it down into it's parts. Move the entire block to just before the </body> tag per Fotiman's advice. Good habit to form, but if the scripts are lightweight like this, it's a trivial savings. However . . . bad habits are hard to break (which is why I still head-drop scripts lol . . .)

window.onload=function() { attachBehaviors(); }

When the window loads, attach the behaviors to the objects. This means you don't have to wait for the page to load and put it all at the bottom, you're telling Javascript to do the wait for you. Even if you do put the code at the bottom, it's a good approach.

function attachBehaviors() {
}

In this function, we attach the behaviors to the page objects. We attach the onblur, onfocus, and onsubmit behaviors to their respective objects. So instead of

<form name="myForm" id="myForm" method="get" action="" onsubmit="return displayResult();">

you have a stock form and fields without inline Javascript clogging up the form. This gets a little important when you have links and other page objects - search engines don't have to sift through them to access your content, and you've gracefully separated page markup from programming.

var obj = document.getElementById('myInput');

We define the page object with the ID "myInput" and store it in a variable named "obj" that only has scope within this function. You'll see we re-use the name "obj" in the displayResult function too, but that variable's scope is also limited to that function and neither of these variables can affect each other. This is one reason globals are bad - when your program gets large, the globals may affect variables within functions and you have to chase down who's stomping on who. By limiting your variables to the functions in which they are used, passing any external values as parameters*, you make your work easier to debug.

if (obj) {
}

Probably one of the unsung heroes of good programming, check for the object in the page before we do anything at all. If we re-named the field and just operated on "obj" you'd get an undefined error and the program would fail. This prevents errors from being output - and - it allows you to put all your code in one place. For example, you may have many forms on the web site and may want to use a common function checkForm(). These forms could have different field names, and you could use a series of if constructs, or switches, to figure out which object you want to operate on without locking them to a given page or having many instances of almost the same code.

A caveat here: always use ID's for JS, not field names. the document.getElementById method is much easier to work with, and not all your objects will be form objects accessed by form.objectname.

obj.onfocus=function() {
if (obj.value==obj.defaultValue) { obj.value=''; }
}

You probably know what this does - same as your original, except we're attaching the onfocus as a function. It will only blank out the value IF it's the default value ('Hello World!').

obj.onblur=function() {
if (obj.value=='') { obj.value=obj.defaultValue; }
}

Ditto.

var frm = document.getElementById('myForm');
if (frm) {
frm.onsubmit=function() { return displayResult(); }
}

Same as above, except we're attaching the function displayResult() to the form's submit behavior. This is where we want it, too - not on the button, as many people just press enter and the button is never "clicked." Use a submit button instead of a button type. Why? If Javascript is disabled in the browser, the form won't submit. Buttons have no inherent action, submit buttons do. By returning false on submit, it allows Javascript to manage the form submit (you'd return true when there are no errors and you want it to submit.) In the case of your exercise, the point is moot, you don't want it to submit - but it's a good piece of info to learn in handling forms.


function displayResult() {
var obj = document.getElementById('myInput');
if (obj) {
alert((obj.value=='')?'No Value!':obj.value);
}
return false;
}


This is pretty much as you originally wrote it with two exceptions. The first is we get the object by ID as described above. The second is the alert line, which uses a ternary operator, also called "short circuit evaluation" nested in the alert.

alert((obj.value=='')?'No Value!':obj.value);

This is equivalent to the following two longer alternatives:

if (obj.value=='') { alert('No Value!'); }
else { alert(obj.value); }

var msg = obj.value;
if (msg=='') { alert('No Value!'); }
else { alert(msg); }

The ternary syntax in almost any language is

result = (condition is true)?do this:otherwise do that;

By nesting it inside the alert we have this gorgeous one liner:

alert((obj.value=='')?'No Value!':obj.value);

One last bit, relating to form handling: often you'll use JS to check for various conditions in the form. If those conditions are met, you'll want to return true (again, not useful for your exercise but a NTN.) An example that would check for myInput being empty before submitting:


function checkForm() {
var obj = document.getElementById('myInput');
var msg = '';
if (obj) {
if (obj.value=='') { msg = 'The My Input field is required.'); }
}
if (msg != '') { alert(msg); return false; }
return true;
}


So what happens there is that we start off with "msg" being a blank string. If the field is populated, msg will still be '' and we return true, which allows the form to submit. If the field is empty we populate message and it's no longer == '', so we alert the message and return false which stops the form from submitting. There's no need for an "else" to return true, it will bail at that point if there's an error.

This approach always allows you to use a submit button - and if you want a custom button, there's no reason to use input type="image", either. See the CSS forum for details. :-)



* Parameters: off topic, but you'd pass a parameter like this

var myvar = 123;

var mynewvar = do_something(myvar);
alert(mynewvar);

function do_something(param) {
// do something with the parameter - increment it
param++;
alert(param);
// return a value, or not
return param;
}

Rain_Lover




msg:4408259
 6:43 pm on Jan 18, 2012 (gmt 0)

@rocknbil,

I really appreciate your time and detailed explanation! Now it's much clearer to me.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved