Coding for "forms" results in browser looping

The code is taken from an application that list an array sorted. I was attempting to replace the use of “prompt” with “forms”. The version with “prompt” does not have the problem. I am, admittedly, a neophyte.

When opened in Firefox this bit of code works but results in Firefox being in a loop. Does not do the same in IE.

<html>
<head>
 <script type="text/javascript"> 
 <!--
// Get the Start and End years
function getYears (form) 
{
    var years = myform.inputbox.value;
    start_year=years.slice(0,2);
	end_year=years.slice(3);
 
document.write('Start Year ='+' '+start_year+'<br/>');
document.write('End Year ='+'  '+end_year+'<br/>');

}  // 'function getYears (form) ''

// -->
</script>
 
</head>
<body>

<FORM NAME="myform" ACTION="" METHOD="GET">Enter Beginning and Ending years separated by a comma <BR><BR><BR>
<INPUT TYPE="text" NAME="inputbox" VALUE=""><P>
<INPUT TYPE="button" NAME="button" Value="Click" onClick="getYears(this.form)">
</FORM>
 
</body>
</html>

You are passing the form as an object to the function. The argument name in the function is “form”, yet you are trying to access “myform”, which (at this point) doesn’t exist.

Not sure what you’re trying to do with slice.

document.write is antiquated, and will overwrite the page contents that are already loaded. Never use document.write. Put a div in there, give it an ID, and use the DOM to show content.

Then why does this code produce two paragraphs:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo document.write</title>
</head>
<body>
    <p>This is an HTML-coded paragraph.</p>
    <script>document.write('<p>This is a JS-coded paragraph.</p>')</script>
</body>
</html>

Live demo here.

Then why does this code produce two paragraphs:

Because the page still hasn’t finished loading.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo document.write</title>
</head>
<body>
    <p>This is an HTML-coded paragraph.</p>
</body>
<script>
setTimeout(function(){document.write('<p>This is a JS-coded paragraph.</p>')},3000);
</script>
</html>

http://stackoverflow.com/questions/18789190/why-not-document-write

http://javascript.about.com/od/hintsandtips/a/nodocwrite.htm

https://developer.mozilla.org/en-US/docs/Web/API/document.write

http://www.vijaywebsolutions.com/everything-about-javascript-incredible-javascripting-document-write/

http://www.codingforums.com/javascript-programming/301717-ie10s-treatment-document-write.html

I can find more for you, if you like.

OK! Thanks.

OK Wolf’, I’ve used the argument (form) in lieu of “myform”. It works; but, the Firefox browser still loops. As to the slice, that’s just my way to get at the “beginning” and “ending” years. I’m sure there is a better way.

Thanks for the comments about “document.write”. I’ll read up on that. As mentioned, I’m a neophyte programmer (at 78).

var years = form.inputbox.value;
var yearList = years.split(‘,’);
var start_year = yearList[0], end_year = yearList[1];

This assumes some kind of validation to make sure that only two years are entered. You should also make sure that they are proper four-digit years.

Did you replace the document.write lines?

I haven’t used document.write for quite a while, but I remember Firefox choking on it before I changed my ways.

I _just_now noticed OP state “neophyte programmer (at 78).”

Dude! Welcome to the coding community, regardless of your age. But I do hope that you enjoy writing code as much as I do. It’s my creative outlet (since I suck at music, painting, poetry, etc.)

I love the challenge of how to get something done; I love seeing how other people do certain things; not a huge fan of troubleshooting, but I know how to do it.

Best of luck in all your learning.

Wolf’, this seems to work and the looping is gone. Have no idea what eliminated the looping. Anyway, you have any further suggestions? My education is mostly by example/imitation; so, suggestions are very welcome.

<html>
<head>
<script type=“text/javascript”>
<!–
// Get the Start and End years
function getYears (form)
{
var years = form.inputbox.value;
var yearList = years.split(‘,’);
var start_year = yearList[0], end_year = yearList[1];

document.getElementById(“prtyears”).innerHTML = start_year+‘<br>’+end_year;

} // 'function getYears (form) ‘’

// –>
</script>

</head>
<body>

<FORM NAME=“myform” ACTION=“” METHOD=“GET”>Enter Beginning and Ending years separated by a comma <BR><BR><BR>
<INPUT TYPE=“text” NAME=“inputbox” VALUE=“”><P>
<INPUT TYPE=“button” NAME=“button” Value=“Click” onClick=“getYears(this.form)”>
</FORM>

<div id=‘prtyears’></div>
</body>
</html>

Looks pretty good. I’ll copy/paste with some notes.


<html>
<head>
 <script type="text/javascript"> 
 <!--  These are obsolete with modern browsers
// Get the Start and End years
function getYears (form) 
{
<!-- Use RegEx to make sure input is in proper format (ie, "xxxx,yyyy") -->
var inputMask = /^\\d{4},\\d{4}$/;

    var years = form.inputbox.value;

if(inputMask.test(years)){// It matches format, finish as expected.
        var yearList = years.split(',');
    	var start_year = yearList[0], end_year = yearList[1];
 
    document.getElementById("prtyears").innerHTML = start_year+'<br>'+end_year;
    }
else{
   document.getElementById("prtyears").innerHTML = "Input value must be xxxx,yyyy (ie '1999,2010')";
   }
}  // 'function getYears (form) ''

// -->These are obsolete with modern browsers
</script>

</head>
<body>

<FORM NAME="myform" ACTION="" METHOD="GET">Enter Beginning and  Ending years separated by a comma <BR><BR><BR>
<INPUT TYPE="text" NAME="inputbox" VALUE=""><P>
<INPUT TYPE="button" NAME="button" Value="Click" onClick="getYears(this.form)">
</FORM>
 
 <div id='prtyears'></div>
</body>
</html>

Not much I can add to or suggest an edit for. Looks good.

Whoa Wolf’ ! Now, you’ve thrown me some hieroglyphics. I’ve read some on RegEx but didn’t find much basic. Do you know a good reference? And, a brief explanation for " var inputMask = /^\d{4},\d{4}$/; " would be outstanding. Hope that is not too big a request.

^ start of a string

\d a digit character 0 - 9

{n} match n times

so

\d{4} match a 4 digit number

, matches a comma

\d{4} again match a 4 digit number

$ end of string

some variations

{n,} matches at least n times

\d{4,} match 4 or more digits

or

{x,y} match x times, but no more than y times.

\d{4,8} match a 4-8 digit number

There are a few good books on the subject by O’Reilly. Mastering Regular Expression, The Regular Expression Cookbook and there’s a pocket reference which is handy.

I have also found this site useful in the past

http://www.regular-expressions.info/quickstart.html

Sorry for missing your most recent question, @RegisVonWagner. I normally don’t peruse the forums over the weekend. But @RLM2008 nailed it. That is precisely what my suggested string does. When that ‘mask’ is used with test(), it checks the format. In this instance, it is specifically checking to make sure that the value entered in the field is “xxxx,yyyy” where x and y are both numbers. So, “1990,2010” is valid, or anything like it (even “2001,1990”, so it’s not checking for numeric order), but anything not in that format will fail.

The way I wrote the code, it would be very simple to use the values post-slice() to check for numeric order:

if ((Number(start_year) <= Number(end_year)){ alert("Start Year cannot be earlier than End Year");}

I just realized that I had that last code backwards (start_year is normally less than end_year).

if ((Number(start_year) >= Number(end_year)){ alert(“Start Year must be prior to End Year”);}

Thanks RLM2008 and WolfShade. I had sort of drifted away during the weekend. The one thing RLM2008 didn’t include in his explanation was the first and last forward slashes /^\d{4},\d{4}$/. I assume they are needed always to open and close?

The forward slashes at both end is the regex equivalent of " or ’ for strings - they indicate the beginning and end of the regex expression. Also, in regex, after the last forward slash you can put certain ‘flags’ - g for global, i for case-insensitive, m for multi-line.

So, as an example, if you wanted to write a function that will trim whitespace from the beginning AND end of a string, you could do:


function trimThis(str){
   return str.replace(/^\\s+|\\s+$/g,'');
}

The first forward slash indicates beginning of the regex expression.
^ means “from the beginning of the string”
\s is whitespace (space, tab, carriage return, newline).

  • means “one or more of the previous character”.
    | means “or”.
    $ means “at the end of the string”.
    The last forward slash indicates end of the expression.
    g is “global”.

The global flag is important, because without it the regex engine would remove only the first encountered instance of whitespace. If there are two spaces at the beginning and end of the string, without the global flag the engine would only replace the first two spaces and ignore the last two. The global flag says, “Hey, if you find spaces at the END of the string, replace those with blanks, too.”

Thanks wolf’ .