reptile7's JavaScript blog
Sunday, February 11, 2007
 
Breakfast, Lunch, and Dinner Links
Blog Entry #66

A couple of points to chew on before we get rolling today:

(1) Needless to say, links play an essential role (some might say the essential role) in HTML. With respect to the "hypertext" aspect of HTML, the "What is HTML?" section of HTML Goodies' "Basic HTML: Introduction" tutorial explains:
Hyper is the opposite of linear. It used to be that computer programs had to move in a linear fashion. This before this, this before this, and so on. HTML does not hold to that pattern and allows the person viewing the World Wide Web page to go anywhere, any time they want.
JavaScript significantly enhances the linking facility of HTML via the location property/object. Who needs an anchor element? Almost any document body element can be coupled in some way with a window.location or location.href statement and turned into a link.

(2) By design, the select element and its optgroup/option element descendants are capable of packing more functionality into a smaller space than just about any other HTML element.

These considerations intersect in HTML Goodies' JavaScript Script Tips #38-41, our focus in this entry. Script Tips #38 and #39 offer a simple script that codes a menu of links whose URLs are the values of option elements of a select element. This type of link menu is very common on the Web, and we'll briefly look at a 'real-world example' later in the post. The Script Tips #38-39 Script is given below:

<script language="javascript">

function LinkUp( )
{
var number = document.DropDown.DDlinks.selectedIndex;
location.href = document.DropDown.DDlinks.options[number].value;
}
</script>

<form name="DropDown">
<select name="DDlinks">
<option selected>--> Choose a Link <--
<option value="scripttip1.html"> Page One
<option value="scripttip2.html"> Page Two
<option value="scripttip3.html"> Page Three
</select>

<input type="button" value="Click to Go!" onclick="LinkUp( );">
</form>

Overview of the Script Tips #38-39 Script

Joe goes over the DropDown form and its controls in Script Tip #38. I have a few comments to add to the mix:

• We won't be sending the DropDown form to a processing agent, so if preferred, you can
(a) remove the form element start-tag and end-tag,
(b) replace the select element's name="DDlinks" attribute with an id="DDlinks" attribute, and then
(c) reference the select element with document.getElementById("DDlinks")
à la recent entries.

The first [in source order] 'option' is the one that will display so we will not give that a VALUE. Even if we don't specify a value attribute for the zeroth option element, however, it would still seem to have a value; according to the W3C, If [the value] attribute [of an option element] is not set, the initial value is set to the contents of the OPTION element. In practice, I find on my iMac that document.DropDown.DDlinks.options[0].value returns an empty string and not --> Choose a Link <--.

• In HTML, the option element end-tag is optional; if you want the script to be XHTML-compliant, then </option> tags must be added.

• The XHTML purists in the audience should also formulate the selected Boolean attribute of the zeroth option element as selected="selected", granted that this may pose problems for older browsers.

I have three items to choose from. You can have fifty, or more, if you want. Here we see the advantage of the select element as noted at the outset of the post. Layoutwise, a selection list of 50 options occupies less than a line in a document; a corresponding link menu of, say, radio buttons would take up 50 lines (I suppose you could scrunch it into fewer lines, but it wouldn't look very nice).

DropDown's last control, a push button, triggers when clicked the LinkUp( ) function, which effects the script's linking action and is discussed in Script Tip #39.

So, the user makes a selection from the menu and then clicks the "Click to Go!" button. The value of the user's chosen option is a relative URL, scripttip#.html, that LinkUp( ) will assign to the href property of the location object, creating a link. LinkUp( ) determines that value via the method outlined in the "Determining user input: selection lists" section of Blog Entry #17:

var number = document.DropDown.DDlinks.selectedIndex;
location.href = document.DropDown.DDlinks.options[number].value;

(If the user doesn't make a selection and clicks the button, then assignment of the empty string (vide supra) value to location.href causes the page to reload.)

This is the simplest, but not the only, way to ascertain a user's select element input, as we'll see below in our discussion of Script Tip #41.

Some up-to-date reference links: in the DOM Level 2 HTML Specification,
(a) the HTMLSelectElement Interface is here,
(b) the HTMLOptionsCollection Interface is here, and
(c) the HTMLOptionElement Interface is here.

BTW, the square bracket characters in the location.href statement are (sigh) once again escaped to &#91; and &#93; in the Script Tips #38-39 source - moreover, my attempts to access scripttip1.html, scripttip2.html, and scripttip3.html pages in HTML Goodies' /beyond/javascript/stips/article.php/ subdirectory did not lead to Script Tips #1-3 (blank pages came up) - so you won't observe a script effect if you "Choose a Link" and then "Click to Go!" in Script Tips #38-39. However, a functioning Script Tips #38-39 Script demo can be found here.

One more minor comment before moving on: contra Script Tip #39, neither of LinkUp( )'s statements must be "on one written line":

function LinkUp( ) {
var number =
document.DropDown.DDlinks.selectedIndex;
location.href =
document.DropDown.DDlinks.options[number].value; }

executes just fine, for example.

Script Tip #40

Script Tip #40 slightly modifies the Script Tips #38-39 Script so that when the user chooses a DDlinks option, then the script automatically links to the destination document; towards this end, Script Tip #40 ditches the "Click to Go!" push button and instead triggers LinkUp( ) with an onchange select element attribute:

<select name="DDlinks" onchange="LinkUp(this.form);">

The interesting thing here is the LinkUp( ) function call's this.form argument, which references the DropDown form. (The this.form expression does not return [t]he output of the form, the index number of the user's choice - this.form.DDlinks.selectedIndex would do that.) Is the this.form parameter necessary? It ain't necessary - LinkUp( ) holds what it needs and doesn't need to be 'fed' anything. Nevertheless, a reformulated, parameterized LinkUp( ) that meaningfully accepts this.form is certainly possible, e.g.:

<script type="text/javascript">
function LinkUp(myForm) {
var number = myForm.DDlinks.selectedIndex;
location.href = myForm.DDlinks.options[number].value; }
</script>
<form name="DropDown">
<select name="DDlinks" onchange="LinkUp(this.form);"> <!--etc.-->

A functioning Script Tip #40 Script demo can be found here.

Script Tip #41

Script Tip #41 adapts the Script Tips #38-39 Script to a top-and-bottom two-frame page:

<frameset rows="30%,*">
<frame src="menuframes.html" />
<frame src="lookhere.html" />
</frameset>

Frames references
(1) HTML Goodies' "So, You Want Some Frames, Huh?" tutorial provides a gentle introduction to frames for those who might be new to this topic.
(2) The W3C discusses frames in Chapter 16 of the HTML 4.01 Specification.

The following code is loaded into the menuframes.html (top) frame document:

<script language="javascript">
function acrossFrames( ) {
if statement #1
if (document.FrameForm.DDFrameForm.options[0].selected)
parent.frames[0].location = 'menuframes.html';
if statement #2
if (document.FrameForm.DDFrameForm.options[1].selected)
parent.frames[1].location = 'scripttip1.html';
if statement #3
if (document.FrameForm.DDFrameForm.options[2].selected)
parent.frames[1].location = 'scripttip2.html';
if statement #4
if (document.FrameForm.DDFrameForm.options[3].selected)
parent.frames[1].location = 'scripttip3.html'; }
</script>
<form name="FrameForm">
<select name="DDFrameForm">
<option selected> --> Pick One <--
<option>Script Tip One
<option>Script Tip Two
<option>Script Tip Three
</select>
<input type="button" value="go there" onclick="acrossFrames( );">
</form>

The form element, the select element, and the linking function have all been renamed; much more importantly, note that the value attributes of options[1], options[2], and options[3] have been stripped out. The acrossFrames( ) function replaces LinkUp( )'s location=selectObject.options[selectObject.selectedIndex].value code with a series of four if statements, one for each DDFrameForm option. Let's look at if statement #2:

if (document.FrameForm.DDFrameForm.options[1].selected)
parent.frames[1].location = 'scripttip1.html';

(At last, an appropriate use of the parent property of the window object! Also, the frames[ ] array, as a property of the window object, is discussed here.)

This if statement says, "If it's true that the first [second in source order] option of the DDFrameForm selection list of the FrameForm form of the document is selected, then assign [the file] scripttip1.html to the value of the location property of the first [second in source order] frame of the parent frameset window," or in plain English, selecting the "Script Tip One" option will load scripttip1.html into the bottom frame (i.e., after clicking the "go there" button). Analogously, if statements #3 and #4 load scripttip2.html and scripttip3.html into the bottom frame if the "Script Tip Two" and "Script Tip Three" options are chosen, respectively.

If preferred, if statements #2-4 can be condensed via a for loop:

for (i=1; i<document.FrameForm.DDFrameForm.options.length; i++) {
if (document.FrameForm.DDFrameForm.options[i].selected)
parent.frames[1].location = "scripttip" + i + ".html"; }

For that matter, if we put the value="scripttip#.html" attributes back in the <option> tags, then we can, à la the LinkUp( ) function, replace if statements #2-4 with:

var number = document.FrameForm.DDFrameForm.selectedIndex;
parent.frames[1].location = document.FrameForm.DDFrameForm.options[number].value;

Script Tip #41's "See It In Action" link leads to a mostly functioning demo. The "Script Tip One", "Script Tip Two", and "Script Tip Three" selections respectively load Script Tips #1, #2, and #3 into the bottom frame successfully, but if you click "go there" without making a selection, then a "404 - File not found" page loads into the top frame. Checking the demo page's source, we see that the frame files have a .htm, and not a .html, extension; reloading the menuframes.htm page into the top frame, then, is a simple matter of replacing if statement #1's 'menuframes.html' with 'menuframes.htm'.

A real-world example

We wrap up this entry with a visit to CNN.com. Scrolling to the bottom of the page, we encounter a link menu, whose coding is:

<form>
<select title="CNN.com is available in different languages" name="languages" size="1" onchange="if (this.options[selectedIndex].value != '') location.href=this.options[selectedIndex].value;" class="cnnFormSelectSm">
<option value="" disabled selected>Languages</option>
<option value="" disabled>---------</option>
<option value="http://arabic.cnn.com/">Arabic</option>
<option value="http://www.CNN.co.jp/">Japanese</option>
<option value="http://www.joins.com/cnn/">Korean</option>
<option value="http://cnnturk.com/">Turkish</option>
</select>
</form>

Like Script Tip #40's code, this menu's select element start-tag contains an onchange event handler that creates a link by assigning the value of the user's selected option to location.href; no function is involved, or needed. Via the if conditional, no linking occurs if the selected option value is an empty string, as is the case for the zeroth and first options. Noteworthily, the onchange attribute is able to use selectedIndex, as opposed to this.selectedIndex, as an options[ ] index number.

The title attribute, used here with the select element and which is usable with most HTML elements, is discussed here in the HTML 4.01 Specification.

The select element's size="1" attribute and the disabling of the first two options (disabled is another Boolean attribute, and is defined by the W3C here) seem redundant to me, but perhaps there are user agents for which they are necessary. Moreover, no use is made of the select element's name="languages" attribute, but it doesn't hurt to have it there.

The select element's .cnnFormSelectSm CSS style block, detailed on this page, is:

.cnnFormSelectSm {
font-family: arial, verdana, sans-serif;
font-size: 10px;
color: #000; }

The multiple search engine script of Script Tips #42-44 also maps form controls onto URLs and we'll take it on in the next post.

reptile7

Labels:


Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)