Forum Moderators: open

Message Too Old, No Replies

Javascript within <select> element

How can I validate this code?

         

WebWalla

2:40 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have some javascript within a <select> element of a form....


<select name="ad" onChange="amadChange(document.dateTemplate.am, this, document.dateTemplate.dm, document.dateTemplate.dd)">
<script type="text/javascript">
<!--

for (i=1; i<=31; i++) {
document.write("<option " + (ad == i? ' selected' : '""') + " value=" + i + ">" + i + "<\/option>\n");

}

//-->
</script>
</select>

This code doesn't validate as HTML 4.01 Transitional due to the following error:-

document type does not allow element "SCRIPT" here

Anybody know how to get round this?

thanks.

Dabrowski

3:03 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can put your <script> tag anywhere on the page. The normal place is in the <head>.

WebWalla

3:17 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for your answer, but I'm still not sure what I should do to validate the code.

Can you tell me what exactly I should put in the head, and how should I declare the javascript code within the SELECT element?

Thanks.

tedster

3:36 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What is the full error message? You may be in the middle of an error cascade here, and the rest of the error message may give you a clue as to what earlier error is triggering this message - what element was left open accidentally and so on.

WebWalla

3:41 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The rest of the error message is this ...


The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements -- such as a "style" element in the "body" section instead of inside "head" -- or two elements that overlap (which is not allowed).

The page has only this form and the form has only this element as per the previous code - this was done to eliminate all other error possibilities.

Apologies, it also gives this error ...


end tag for "SELECT" which is not finished.
</select>

[edited by: WebWalla at 3:46 pm (utc) on Nov. 12, 2007]

WebWalla

3:49 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The SELECT error no longer appears, since I have added 2 Select element options to the code.

[edited by: WebWalla at 4:44 pm (utc) on Nov. 12, 2007]

Fotiman

6:49 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



First, let me say that I would *NEVER* recommend this method since it uses document.write. But here's where I *think* your problem is:

document.write("<option " + (ad == i? ' selected' : '""') + " value=" + i + ">" + i + "<\/option>\n");

If you remove those double quotes, that might fix your problem.

WebWalla

7:23 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It still doesn't validate. I appreciate that the javascript is currently nonsense, but I've taken almost everything out to try to get to the bottom of the problem. So, the entire page currently stands as this ...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
<meta http-equiv="Content-Language" content="en" >
<title>Form test</title>

</head>
<body>
<form name="dateTemplate" method="post" action="" >
<select size="1" name="D1">
<script type="text/javascript">
<!--
for (i=1; i<=31; i++) {
document.write("<option " + (ad == i? ' selected' : '') + " value=" + i + ">" + i + "<\/option>\n");
}
//-->
</script>
<option value="1">Jan</option>
<option value="2">Feb</option>
</select>
</form>
</body>
</html>

The full validation error is as follows:-


Line 11, Column 41: document type does not allow element "SCRIPT" here.
<script type="text/javascript">&#9993;
The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements -- such as a "style" element in the "body" section instead of inside "head" -- or two elements that overlap (which is not allowed).

One common cause for this error is the use of XHTML syntax in HTML documents. Due to HTML's rules of implicitly closed elements, this error can create cascading effects. For instance, using XHTML's "self-closing" tags for "meta" and "link" in the "head" section of a HTML document may cause the parser to infer the end of the "head" section and the beginning of the "body" section (where "link" and "meta" are not allowed; hence the reported error).

Anybody else have any ideas? Thanks.

Fotiman

8:53 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Try something like this. Move the script functionality to occur when the page has loaded, and then create the new Options instead of using document.write.

<script type="text/javascript">
window.onload = function() {
// Append options to select element
var s = document.forms["dateTemplate"].D1;
for (var i = 1; i <= 31; i++) {
// Check the global var ad to see which option
// is selected
var selected = (ad == i? true: false);
s.options[s.options.length] = new Option(i, i, selected, selected);
}
};
</script>
<form name="dateTemplate" method="post" action="" >
<select size="1" name="D1">
<option></option>
</select>

Dabrowski

9:07 pm on Nov 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ok, it is definately complaining about the script being there. So...for what I can see you want to insert options for all the days, with today being selected. I've written a piece of code that does this.

First, in your <head> put this code:

<script> 
window.onload = function() {
var today = new Date();
var day = today.getDate();
var sel = document.getElementById( "dateselect");

for( var i = 1; i <= 31; i++) {

// Check if month actually has this many days
today.setDate( i);
if( today.getDate()!= i)
break;

// Create Option
var elem = document.createElement( "OPTION");

elem.value = i;

if( typeof( elem.innerText))elem.innerText = i;
if( typeof( elem.textContent))elem.textContent = i;

// Add option to select
sel.appendChild( elem);
}

// Select today's date
sel.selectedIndex = day -1;
};
</script>

Then in your <body> you just need a 'blank' select tag like:

<select id='dateselect' size="1" name="D1"> </select>

You can easily use the same thing to create current date/year fields.

This code works well, but you should consider non-javascript clients, hard code the dates, all 31 days, then use JS to delete the days you don't need, and select the current date.

WebWalla

7:53 am on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Wow, thanks for taking the time to address this.

Back to the drawing board, it seems, because the real page includes much more code within that form and the same validation error was coming up several times.

I'm not a javascript expert - I had simply adapted some code to serve my needs - so I may have to compromise on 100% validation. Thanks a lot anyway.

phranque

9:52 am on Nov 13, 2007 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



webwalla:

to answer your question more generally, you should define your javascript functions using script tags within the head of the document.
the javascript code itself can be inline in the document or in an externally included (by the browser) file.
then you can invoke these functions by using event triggers.
example of event triggers include body onload, form onsubmit, select onchange.

Dabrowski

1:17 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



the real page includes much more code within that form

If it's the same kinda thing that code can easily be extended. Why don't post the code (just the form section), or just tell us what you'd like the form to include I'm sure it can be easily solved.

WebWalla

1:58 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, you asked for it :-)
Seriously - I appreciate your looking at this.
Here goes the full code, with all formatting, tables, etc. taken out ...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
<meta http-equiv="Content-Language" content="en" >
<title>Webmasterworld.com</title>
<script language="JavaScript" type="text/javascript" src="http://www.example.com/example.js"></script>
</head>
<body>
<form name="dateTemplate" method="post" action="" >
<strong>Arrival</strong>&nbsp;
<select name="am" size="1" onChange="amadChange(this, document.dateTemplate.ad, document.dateTemplate.dm, document.dateTemplate.dd)">
<script>
<!--
//alert(dw);
document.write("<option " + (am == 1? 'selected' : '""') + " value=1>January<\/option>\n");
document.write("<option " + (am == 2? ' selected' : '""') + " value=2>February<\/option>\n");
document.write("<option " + (am == 3? ' selected' : '""') + " value=3>March<\/option>\n");
document.write("<option " + (am == 4? ' selected' : '""') + " value=4>April<\/option>\n");
document.write("<option " + (am == 5? ' selected' : '""') + " value=5>May<\/option>\n");
document.write("<option " + (am == 6? ' selected' : '""') + " value=6>June<\/option>\n");
document.write("<option " + (am == 7? ' selected' : '""') + " value=7>July<\/option>\n");
document.write("<option " + (am == 8? ' selected' : '""') + " value=8>August<\/option>\n");
document.write("<option " + (am == 9? ' selected' : '""') + " value=9>September<\/option>\n");
document.write("<option " + (am == 10? ' selected' : '""') + " value=10>October<\/option>\n");
document.write("<option " + (am == 11? ' selected' : '""') + " value=11>November<\/option>\n");
document.write("<option " + (am == 12? ' selected' : '""') + " value=12>December<\/option>\n");
//-->
</script>
</select>
<select name="ad" onChange="amadChange(document.dateTemplate.am, this, document.dateTemplate.dm, document.dateTemplate.dd)">
<script type="text/javascript">
<!--
for (i=1; i<=31; i++) {
document.write("<option " + (ad == i? ' selected' : '""') + " value=" + i + ">" + i + "<\/option>\n");
}
//-->
</script>
</select>
<br>
<strong>Departure</strong>&nbsp;
<select name="dm" onChange="dmddChange(this,document.dateTemplate.dd)">
<script type="text/javascript">
<!--
document.write("<option " + (dm == 1? ' selected' : '""') + " value=1>January<\/option>\n");
document.write("<option " + (dm == 2? ' selected' : '""') + " value=2>February<\/option>\n");
document.write("<option " + (dm == 3? ' selected' : '""') + " value=3>March<\/option>\n");
document.write("<option " + (dm == 4? ' selected' : '""') + " value=4>April<\/option>\n");
document.write("<option " + (dm == 5? ' selected' : '""') + " value=5>May<\/option>\n");
document.write("<option " + (dm == 6? ' selected' : '""') + " value=6>June<\/option>\n");
document.write("<option " + (dm == 7? ' selected' : '""') + " value=7>July<\/option>\n");
document.write("<option " + (dm == 8? ' selected' : '""') + " value=8>August<\/option>\n");
document.write("<option " + (dm == 9? ' selected' : '""') + " value=9>September<\/option>\n");
document.write("<option " + (dm == 10? ' selected' : '""') + " value=10>October<\/option>\n");
document.write("<option " + (dm == 11? ' selected' : '""') + " value=11>November<\/option>\n");
document.write("<option " + (dm == 12? ' selected' : '""') + " value=12>December<\/option>\n");
//-->
</script>
</select>
<select name="dd" onChange="dmddChange(document.dateTemplate.dm,this)">
<script type="text/javascript">
<!--
for (i=1; i<=31; i++) {
document.write("<option " + (dd == i? ' selected' : '""') + " value=" + i + ">" + i + "<\/option>\n");
}
//-->
</script>
</select>
<br>
<input type=button style="BACKGROUND-COLOR: #3a4f98; COLOR: #ffffff; FONT-FAMILY: Verdana; FONT-SIZE: x-small" value="Check" onClick="JavaScript:processForm(this.form);" name="button">
</form>
</body>
</html>

pageoneresults

2:29 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hmmm, I've validated thousands of pages and I can't say I can remember the last time I had a <script> element within a <select> element. Typically, those <script> elements need to be wrapped in <div>s for validation purposes, yes?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

You are using a shortened DTD which causes the browser to go into Quirks mode. You may want to change that the full DTD which is...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

What if you were to move the opening and closing <script> elements to before and after the <select> elements?

WebWalla

2:45 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A <div> also won't validate within a <select>

Fotiman

3:03 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



A select element can only contain option or optiongroup elements.

Here is a reworked example. I've stripped out all of the inline JavaScript. This gives you much cleaner markup. If you want to modify the "behaviors", you only need to work in the JavaScript files. If you want to modify "presentation" you should only work in the CSS files. If you want to modify the "content", you should modify the HTML. This separation will give you a better development environment. For more, look up "unobtrussive JavaScript".


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!-- 1. Include a full DOCTYPE to prevent the browser from going into
Quirks mode. You'll have better cross-browser results. -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
<meta http-equiv="Content-Language" content="en" >
<!-- 2. Styles should really be defined in a separate file, but I'll include
then here for now. -->
<style type="text/css">
#button {
/* 3. Use lowercase, that's the convention. */
background-color: #3a4f98;
color: #ffffff;
/* 4. Don't forget a generic family in case verdana isn't available */
font-family: Verdana, sans-serif;
/* 5. Note, if verdana is not installed on the client, then this is going
to make their font size so small that they might not be able to read it.
In general, it's not a good idea to use Verdana. */
font-size: x-small;
</style>
<title>Webmasterworld.com</title>
<!-- 6. Don't include the "language" attribute on script tags. It's invalid
and doesn't give you anything. -->
<script type="text/javascript" src="http://www.example.com/example.js"></script>
<!-- 7. Put this in a separate file as well. I only include it inline so you
can see the code. -->
<script type="text/javascript">
window.onload = function() {
// Presumably, we already have JavaScript variables am, ad, dm, and dd.
// I'm guessing those are defined in the "exmample.js" file?
// Get the elements we want to work with
var amEl = document.getElementById("am");
var adEl = document.getElementById("ad");
var dmEl = document.getElementById("dm");
var ddEl = document.getElementById("dd");
var button = document.getElementById("button");
var i;
// Mark the selected values. This should really be done with a server
// side technology (PHP, ASP, JSP, etc.) because none of this will work
// if the user has JavaScript disabled.
for (i = 0; i < amEl.options.length; i++) {
if (amEl.options[i].value == am) {
amEl.options[i].selected = true;
break;
}
}
for (i = 0; i < adEl.options.length; i++) {
if (adEl.options[i].value == ad) {
adEl.options[i].selected = true;
break;
}
}
// Attach onchange handlers
amEl.onchange = function() {
amadChange(amEl, adEl, dmEl, ddEl);
};
adEl.onchange = function() {
amadChange(amEl, adEl, dmEl, ddEl);
};
dmEl.onchange = function() {
dmddChange(dmEl, ddEl);
};
ddEl.onchange = function() {
dmddChange(dmEl, ddEl);
};
button.onclick = function() {
processForm(this.form);
};
};
</script>
</head>
<body>
<form name="dateTemplate" method="post" action="" >
<strong>Arrival</strong>&nbsp;
<!-- 8. I added ids to make it easier work with in script. -->
<select name="am" id="am" size="1">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select name="ad" id="ad">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
<br>
<strong>Departure</strong>&nbsp;
<select name="dm" id="dm" onChange="">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select name="dd" id="dd">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
<br>
<!-- 9. You should be using a submit button and processing this form server
side. Otherwise, visitors with JavaScript disabled (including some users with
disabilities that need to use a screen reader) will not be able to use your
form. Since I don't know your situation, I'm going to leave this as button. -->
<input type="button" value="Check" name="button" id="button">
</form>
</body>
</html>

Dabrowski

3:30 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yeah what he said. You still need to delete erroneous dates though, what if it's Febuary?

Ideally you need to generate these option boxes on the server side.

WebWalla

3:37 pm on Nov 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Then it's back to the drawing board again, for a PHP solution. *sigh*

Thanks a lot for all your help, though.