reptile7's JavaScript blog
Saturday, January 28, 2006
 
Confirm It, or Else
Blog Entry #28

So far, we've discussed two types of JavaScript pop-up message/dialog boxes:

(1) Alert boxes (introduced in the Primer #4 Assignment and in "The end-of-primer assignment and its answer" section of Blog Entry #7), popped up by the alert( ) method of the window object:


(2) Prompt boxes (introduced in Primer #6 and in Blog Entry #11), popped up by the prompt( ) method of the window object:


In this entry, we examine HTML Goodies' JavaScript Primers #13, which introduces a third such type of box: the confirm box, which is popped up by the confirm( ) method of the window object. The syntax of the confirm( ) method is identical to that of the alert( ) method:

window.confirm("This is the confirm box message.");
// this command can be placed in a script or assigned to an event handler

Output:

Unlike an alert box but like a prompt box, a confirm box solicits input from the user. Specifically, a confirm box presents to the user a Boolean true/false choice with respect to its message: clicking the "OK" button represents true, whereas clicking the "Cancel" button represents false. We can verify this directly with the following code:

var bool = window.confirm("This is the confirm box message.");
window.alert(bool);
/* the alert box displays "true" or "false" depending on whether the user chooses "OK" or "Cancel" on the confirm box */

As is done in the Primer #13 Script, we can tie the confirm box's true/false choice to the execution of JavaScript code with an if...else statement, a conditional whose "if" part, corresponding to true, executes one unit (≥1 commands) of code, and whose "else" part, corresponding to false, executes an alternate unit of code, via the following syntax:

if (an expression that can be true or false)
// if the expression is true
{
command_statement_A;
command_statement_B; etc.
}
else
// if the expression is false
{
command_statement_X;
command_statement_Y; etc.
}

Note the function-like use of punctuating enclosure marks: the if/else commands are delimited by braces (which, à la functions, do not need to be on their own lines), whereas the conditional expression itself is surrounded by parentheses - "Because in reality, they [if and else] are functions," Joe tells us in the primer. Upon reading this, I initially thought, "No, Joe, they are not functions." And then I recalled Wikipedia's subroutine definition (which has been recently updated) from Blog Entry #23 - "a sequence of code that performs a specific task, as part of a larger program, and is grouped as one or more statement blocks" - which applies rather accurately to an if...else statement. If...else blocks of code are not necessarily "called" as are functions, but on the other hand, a function can be followed by a calling function_name( ); command that enables the function to execute without any input on the user's part. So perhaps I am splitting hairs here.

As should be clear at this point, an if...else statement serves as a type of branching technique within a script. For example, consider the Primer #13 Script below:

<SCRIPT type="text/javascript">
if (confirm("Are you sure you want to enter HTML Goodies?") )
{
parent.location='http://www.htmlgoodies.com';
alert("Good choice");
}
else
{
alert("Then you'll stay right here");
}
</SCRIPT>

We can illustrate the script's effect, and the if...else concept more generally, with the following flowchart:


With respect to if...else branching, note in the syntax on DevGuru's if...else statement page

if (condition) {statements1} [else {statements2}]

that the "else" part is in square brackets, indicating that it is optional. Indeed, we'll see later in the HTML Goodies JavaScript Primers series examples of "if...else" statements consisting only of one or more "if" units of code.

Joe's take on the "if" conditional statement:

It means, If (Here is your chance to make a choice)

is correct as far as the Primer #13 Script goes, because the confirm( ) method does require the user to make a true/false choice. In fact, if...else statements are much more commonly used to compare two expressions and determine whether they are equal (=true) or not (=false), as we'll again see in future primers.

In case you were wondering, the "OK" and "Cancel" buttons of a prompt box do not also correspond respectively to true and false. When I substituted "prompt" for "confirm" in the Primer #13 Script:

if (prompt("Are you sure you want to enter HTML Goodies?") )

the "OK" and "Cancel" buttons of the resulting prompt box both triggered the "else" part of the script; clicking "OK" did not take me to the HTML Goodies home page.

A couple of niggling points relating to the "Deconstructing the Script" section of Primer #13:

(1) "If you remember back a couple of primers [actually, it was eight primers ago, in "The onSubmit Command" section of Primer #5], 'parent.location' is the command that creates a link." Uh, "parent.location" is A command that creates a link, and is OK as a substitute for "window.location" outside of a frames situation, but either window.location='http://www.htmlgoodies.com'; or location.href='http://www.htmlgoodies.com'; would be better form than parent.location='http://www.htmlgoodies.com'; in the Primer #13 Script.

(2) "Please notice the semicolons." I was going to mention, per Blog Entry #5, that command statements that do not share their source code lines with other commands do not need to end with semicolons; nonetheless, it's good form to follow a command with a semicolon, so scratch that.

We wrap up this entry with a few remarks about...

The end-of-primer assignment and its answer

In the Primer #13 Assignment, Joe asks the reader to functionize the Primer #13 Script, write a message ("Chicken!") to the status bar in the "else" part of the script, and open the HTML Goodies home page link in the "if" part of the script in a new window. Joe's assignment answer is uneventful until we get to its ending bullet point, which reads:

• If you wanted to get fancy and have the page open in a new window, you only had to change out two words. Exchange "parent.location" with "window.open" and you're done.

Red flag! I instantly wondered, "Is window.open='http://www.htmlgoodies.com'; really a legitimate command?" I tried it out; it didn't work. As one would expect, you'll need to use:

window.open("http://www.htmlgoodies.com");

for this part of the answer.

As noted above, we'll see other applications of if...else statements in due course. Meanwhile, in the next post we'll forge on to HTML Goodies' JavaScript Primers #14, in which we'll use JavaScript to carry out some simple arithmetic calculations. You're keen on math, aren't you? I am too, or at least I was until I hit the second semester of calculus...

reptile7

Tuesday, January 17, 2006
 
Opening New Windows, Part 3
Blog Entry #27

Greetings, my fellow Weekend Silicon Warriors...we conclude our series of entries on opening new browser windows by checking over HTML Goodies' JavaScript Primers #12. Primer #12 is ill-fittingly named "Opening a Window with a Function" on the HTML Goodies JavaScript Primers page; we'll see below that the function part of the Primer #12 Script is little more than 'excess baggage' with respect to the script's execution. In accord with Joe Burns' promise at the end of Primer #11 - "Next primer, we'll get into a very slick way of making one page into two" - let's give Primer #12 a better title: "Opening New Windows: Coding the Openee Window in the Opener Document." As an aside, Primer #12 mirrors the "Page Inside A Page" section of Joe's separate "So You Want To Open A Window, Huh?" tutorial - it's not clear which was written first.

The Primer #12 Script is largely an application of the "Variabilizing an 'openee' window" methodology that we outlined in the previous post; it appears below:

<SCRIPT type="text/javascript">
function openindex( )
{
var OpenWindow=window.open("", "newwin",
"height=300,width=300"); // function command #1
OpenWindow.document.write("<HTML>") // function command #2
OpenWindow.document.write("<TITLE>New Window</TITLE>") // function command #3
OpenWindow.document.write("<BODY BGCOLOR='00ffff'>") // function command #4
OpenWindow.document.write("<CENTER>") // function command #5
OpenWindow.document.write("<font size=+1>
New Window</font><P>") // function command #6
OpenWindow.document.write("<a href=
'http://www.htmlgoodies.com' target='main'>
This will open<BR> in the main window</a><p>") // function command #7
OpenWindow.document.write("<P><HR WIDTH='60%'><P>") // function command #8
OpenWindow.document.write("<a href=''
onClick='self.close( )'>
This closes the window</a><p>") // function command #9
OpenWindow.document.write("</CENTER>") // function command #10
OpenWindow.document.write("</HTML>") // function command #11
}
</SCRIPT>
...and in the BODY command:
onLoad="openindex( )"

As shaped above, the script does not execute but throws errors, which can be eliminated by getting rid of the line breaks in function commands #6, #7, and #9.

Once corrected, the script, via the onLoad-triggered openindex( ) function, pops up a small window, named "newwin", that is similar to the "joe" window of Primer #11. Function command #1 opens the window with a window.open( ) command whose URL parameter is left blank via empty quotes, and assigns the window to the OpenWindow variable, which serves to reference "newwin" for the rest of the function. The remaining function commands then 'fill in the blank,' so to speak; specifically, a series of OpenWindow.document.write( ) commands writes text and HTML to the "newwin" page display in a normal manner.

Function commands #2-#11 can be rolled into a single OpenWindow.document.write( ) command:

OpenWindow.document.write("<html><title>New Window</title>...</center></html>");

in much the same way that an HTML document can be written as one long, continuous line; however, the use of 10 OpenWindow.document.write( ) commands makes the code easier to follow, obviously.

Other code notes

(1) If desired, function command #3 can be replaced with:

OpenWindow.document.title = "New Window";

(2) Joe centers the "newwin" document body with a <center> tag, which was deprecated with the advent of HTML 4.0; if we want to be a bit more up-to-date, then we can delete function commands #5 and #10 and instead retool function command #4 as:

OpenWindow.document.write("<body bgcolor='00ffff' style='text-align: center;'>");

(3) Function command #6's "New Window" text string is marked up with a <font> tag, which also was deprecated with the advent of HTML 4.0; a near-equivalent and more permissible formulation would be:

OpenWindow.document.write("<h3>New Window </h3>");
// use of the <h3> tag allows us to ditch the <p> tag after the closing </font> tag

(4) Function command #7 repeats the target='main' mistake of Primer #11; per the previous post, we'll need to add:

window.name = "main";

to the beginning of the script, either before or inside of the openindex( ) function, to ensure that the link destination page loads in the opener window.

My attempts to replace target='main' with a window.opener command were mostly successful, but not glitch-free; the following code:

OpenWindow.document.write("<a href='' onclick='window.opener.location=\"http://www.htmlgoodies.com\";'>This will open<br> in the main window</a><p>");

reliably loads the HTML Goodies home page into the opener window, but a separate 300×300 window holding the opener document also pops up; I was able to suppress this by setting href='#' (as though it were an internal link, but without an anchor to jump to) when using MSIE, not so when using Netscape.

(5) Either the <p> tag at the end of function command #7's OpenWindow.document.write( ) instance or the <p> tag at the beginning of function command #8's OpenWindow.document.write( ) instance should be eliminated (alternately, we could replace these tags with <br> tags); Joe notes in the "Adding Blank Lines" section of his "So, You Want To Align Text, Huh?" tutorial that a series of n consecutive <p> tags gives no more whitespace than a single <p> tag. Moreover, the <p> tag at the end of function command #9's OpenWindow.document.write( ) instance serves no purpose and can also be dropped. (I wouldn't be me if I didn't carp about these kinds of things.)

(6) It would be good form to precede the </html> tag in function command #11's OpenWindow.document.write( ) instance with a closing </body> tag:

OpenWindow.document.write("</body></html>");

however, this is optional.

(7) Finally, the use of a function here is totally unnecessary. Comment out the function openindex( ), {, and } lines, and remove onLoad="openindex( )" from the <body> tag, and the shape-corrected script works A-OK.

Quick comments on the Primer #12 Assignment

In the Primer #12 Assignment, Joe asks the reader to "create...using a function" a pop-up window that, inter alia, incorporates the user's name, to be solicited priorly by a prompt( ) box, in the window title bar. If we follow the 'letter of the assignment,' then there's no reason why we can't use the two windows-two documents approach of Primer #11 in crafting an answer:

In the opener document:
<script type="text/javascript">
function P12A( ) {
window.open("openee.html", "", "width=300,height=300"); }
P12A( );
</script>

openee.html code:
<html><head><title></title>
<script type="text/javascript">
var fn = window.prompt("Kindly tell us your first name:");
document.title = "Hello " + fn + " - Here is your window!";
</script></head>
<body bgcolor="green">
Click <a href="" onclick="window.close( );">here</a> to close the window.
</body></html>

But of course, Joe really wants you to use the two windows-one document approach of Primer #12. I have but one comment on Joe's assignment answer, which closely follows the Primer #12 Script and in which "...[t]he TITLE command was broken into three parts so that the variable 'name' [to which the prompt( ) output is assigned] could be added":

OpenWindow.document.write("<title>");
OpenWindow.document.write("Hello " + name + " Here is your window!");
OpenWindow.document.write("</title>");

Without loss of clarity, there's no reason why the above can't be a single line of code:

OpenWindow.document.write("<title>Hello " + name + " Here is your window!</title>");
(or OpenWindow.document.title = "Hello " + name + " Here is your window!";)

I originally planned to do a 'tour of review' through HTML Goodies' "Opening New Windows With JavaScript" tutorials in this entry. In particular, I was going to readdress the "no title bar" topic - I had sloppily failed to notice on MSDN's window.open( ) page that the titlebar new window feature is not Netscape-specific, but can be set to "no" when using MSIE under specialized conditions - and I was going to revisit the coding of images in openee windows in light of/response to the bizarre script that appears in Joe's "Remote Image" tutorial. On second thought, however, I think our time is better spent pushing on in the HTML Goodies JavaScript Primers series, so in the next post we'll discuss Primer #13, which covers the confirm( ) method of the window object and will also introduce us to if...else statements, a very important and ubiquitously used part of the JavaScript toolbox.

reptile7

Monday, January 09, 2006
 
Opening New Windows, Part 2
Blog Entry #26

We return now to HTML Goodies' JavaScript Primers #11, "Opening New Windows." Having detailed the fundamentals of the window.open( ) command in the last entry, we pick up the conversation at the "Tags In The New Window" subsection of the "Deconstructing the Script" section of Primer #11. Via the Primer #11 Script:

<script type="text/javascript">
window.open("opened.html", "joe", config="height=300,width=300")
</script>

Joe pops up a small window, named "joe", containing two hyperlinks:

<a href="http://www.htmlgoodies.com" target="main">If you click this, you'll get <br>HTML Goodies in the main window.</a><p><hr width=60%><p>

<a href="" onclick="window.close( );">Click this to close the window.</a>

Here's "joe":

The name='joe' window

Joe seeks to use the smaller "joe" window as a 'remote control' to load the HTML Goodies home page into the larger preexisting window. However, Joe's code above does not work as advertised, at least on my computer; with either MSIE or Netscape, the first "joe" link opens http://www.htmlgoodies.com in a third, separate browser window. Why might this be?

The Problem, and Solution #1

The problem here is easy to identify. Joe claims, "Whether you knew it or not, the big window has a name, 'main'...[I]t's the default name." Nope. DevGuru's HTML anchor tag page notes that there are four "reserved names" that can serve as values for the target attribute in an <a> tag: "_blank" (which opens the link in a separate window, as noted at the outset of the previous post), "_parent", "_self", and "_top" (outside of a frames situation, these three open the link in the same window) - "main" isn't one of them. I have no idea why the target="main" attribute/value behaves like target="_blank"; I would have predicted that the browser would ignore target="main" and then load the link into the "joe" window.

More generally, a browser window object does not have a "name" (i.e., its name property does not have a value) unless you give it one. With respect to an unnamed window, consider the following script:

<script type="text/javascript">
window.alert(window.name);
</script>

Up pops a blank alert box - try it yourself.

At this point, you may be thinking, "Well, why don't we name the big window 'main' with a window.name='main' command in the Primer #11 Script, and see if that works?" Ah, splendid - this does indeed set things to right! Once we've done that, "joe" smoothly loads the HTML Goodies home page into "main", although on my computer the implementation thereof is somewhat browser-dependent: with Netscape, focus remains with "joe" (it's still on top) after http://www.htmlgoodies.com has loaded, but with MSIE, focus is transferred to "main" ("joe" falls behind), which might not bother some people, but it bugged me...after a bit of experimentation, I found that putting onUnload="window.blur( );" in the <body> tag of the "main" window document allows focus to remain with "joe", regardless of browser. (Conversely, if you want focus to be transferred to the preexisting window, then you can ensure this by putting onUnload="window.focus( );" in the <body> tag of its document.)

(Let's cut Joe some slack here - perhaps he was writing Primer #11 at the same time he was writing his "So You Want To Open A Window, Huh?" and "Remote Control JavaScript" tutorials, each containing a script with a self.name="main" command, that appear in the "Opening New Windows With JavaScript" section of HTML Goodies, and he somehow got them all mixed up.)

In reciprocal fashion, the "main" window's document can use the following code to open a link in the "joe" window:

Click <a href="http://www.some_web_page.com" target="joe">here</a> to load a new page into the smaller window.

Lastly, contra Primer #11, loading a new file into the "joe" window via a link in the "joe" window document ("opened.html" in this case) does not require target="joe" in the anchor tag, which by default opens the destination page in the same window, and thus no 'targeting' is necessary.

From a JavaScript/DOM standpoint, the target="window_name" approach to communication between the "main" and "joe" windows, mediated by HTML hyperlinks, is limited to assigning new values to the href properties of these windows' location objects. It would be nice, and more generally useful, if we could from a new window reference a preexisting window, and vice versa, allowing us to access and manipulate each window's document and body elements therein, and it turns out that we can do just that...

Solution #2: the opener property

Briefly mentioned in the "Referencing a Window" section of Blog Entry #18, the window object has an opener property by which a newly opened window can reference the preexisting window that opened it. The window.opener reference can be used in all manner of relevant command statements to affect the opening window and the document it holds. For example, if the "opened.html" document of the "joe" window contains:

window.opener.location = "http://www.htmlgoodies.com";
we can load the HTML Goodies home page into the "main" window;

window.opener.document.title = "Opening New Windows";
we can change the "main" window document title from "JavaScript Primers #11" to "Opening New Windows";

window.opener.document.forms[3].elements[0].value = "Let's review, shall we?";
we can change Primer #11's "Click Here For What You've Learned" button into a "Let's review, shall we?" button.

You get the idea. As usual, such commands can be either placed normally in a script or assigned to a suitable event handler.

Now, if the "opened.html" document of the "joe" window were to open a third window, "burns":

window.open("opened1.html", "burns", "width=500,height=200");

then the "opened1.html" document can use window.opener commands to affect the "joe" window and "opened.html" document. Continuing "[i]n this way, you can end up with a chain of opened windows, each of which has an opener property pointing to the window that opened it," quoting Netscape. Relatedly, the "main" window does not itself have an opener window, and the use of window.opener commands in the "main" window document would throw errors.

Now then: what about referencing an opened window from the opener window? We can do that, too...

Variabilizing an 'openee' window

Using a syntax recalling that of the prompt( ) method, we can assign a window.open( ) command to a variable; this variable can then be used to reference the newly opened window:

var zork = window.open("http://www.some_web_page.com", "new_window_name", "new_window_features");

The statement above should be placed in a script; if it is assigned to an event handler, then the zork variable will not be recognized subsequently in the document source code.

It is tempting to think of zork as the name of the new window, but just to be clear, zork variabilizes/references the new window object as a whole, with all its properties, including its name property.

We can now construct zork command statements, to be placed in the opener window's document, to affect the zork window and its document:

zork.status = "Jai guru deva om";
zork.document.bgColor = "blue"; etc.

I've put together a demo that illustrates some window.opener and zork commands. We'll see more variabilized-openee-window commands in action in the Primer #12 Script.

<title>This is the opener pane.</title>



Try the buttons below first; their code includes zork.focus( ) commands that will rebring the zork window to the front.




Now that we have that all sorted out, what about that second "joe" window link, huh?

Closing a window

Complementing the open( ) method, the window object has a close( ) method, taking no parameters, that can be used to close a window, very much like selecting the Close command under the File menu. As shown above, the "joe" window assigns a window.close( ) command to an onClick event handler in an anchor tag, giving a link for closing the "joe" window; this code, taken from the "joe" source, is a bit different than the code appearing in the "Closing The Window" subsection of Primer #11, however:

<A HREF="" onClick="self.close">Click To Close</A>

Note that "close" is not followed by parentheses - mere sloppiness, one would assume - but then Joe says, "The command 'close' is a property that does the dirty work," granted that close( ) is listed as a method on the "Click Here For What You've Learned" page. (Actually, the window object does have a read-only Boolean closed property "that determines if a window has been closed," quoting DevGuru.) The use of "self" instead of "window" is OK, even as Joe strangely states that "...'self' is a property of whatever it happens to be sitting on"; as discussed in the aforelinked "Referencing a Window" section of Blog Entry #18, the "self" property of the window object is synonymous with "window" in referring to the currently active window.

Joe leaves the href attribute value blank "...so that the link points to nothing prevent[ing] another page from loading." On my computer, and when using either MSIE or Netscape, I find that the href attribute value in this case doesn't matter - for example, href can alternately be set to the current document or to any other Web page - when the link is clicked, the window.close( ) command overrides the default linking action, and the window closes. However, empty quotes are easy to type, so good enough.

If desired, the second "joe" link can be retooled to close the "main" window via assigning "window.opener.close( );" to the onClick attribute.

The "Opening New Windows With JavaScript" section of HTML Goodies has a "Hello Goodbye" tutorial with a (leaves-room-for-improvement) script for a self-closing pop-up window. The script uses the setTimeout( ) method of the window object to set a 3000-millisecond delay before executing a self.close( ) command; we can clean up and summarize the relevant setTimeout( ) lines of code as follows:

pop.setTimeout("self.close( )", 3000);
// The self-closing window is assigned to a pop variable.



We'll wrap up our discussion on opening new windows with the next post, in which we'll briefly look at HTML Goodies' JavaScript Primers #12 and possibly also do a bit of window.open( ) reviewing.

reptile7


Powered by Blogger

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