CD-312 Part VI ✦ Appendixes Listing 16-40 (continued) function checkEnter() { if (window.event.keyCode == 13) { handleOK() } } </SCRIPT> </HEAD> <BODY BGCOLOR=”#eeeeee” onLoad=”init()”> <H2>Web Site Preferences</H2> <HR> <TABLE BORDER=0 CELLSPACING=2> <FORM NAME=”prefs” onSubmit=”return false”> <TR> <TD>Enter your first name:<INPUT NAME=”name” TYPE=”text” VALUE=”” SIZE=20 onKeyDown=”checkEnter()”> </TR> <TR> <TD>Select a background color: <SELECT NAME=”bgColor”> <OPTION VALUE=”beige”>Beige <OPTION VALUE=”antiquewhite”>Antique White <OPTION VALUE=”goldenrod”>Goldenrod <OPTION VALUE=”lime”>Lime <OPTION VALUE=”powderblue”>Powder Blue <OPTION VALUE=”slategray”>Slate Gray </SELECT> </TR> <TR> <TD>Select a text color: <SELECT NAME=”textColor”> <OPTION VALUE=”black”>Black <OPTION VALUE=”white”>White <OPTION VALUE=”navy”>Navy Blue <OPTION VALUE=”darkorange”>Dark Orange <OPTION VALUE=”seagreen”>Sea Green <OPTION VALUE=”teal”>Teal </SELECT> </TR> <TR> <TD>Select “Welcome” heading font point size: <SELECT NAME=”h1Size”> <OPTION VALUE=”12”>12 <OPTION VALUE=”14”>14 <OPTION VALUE=”18”>18 windowObject.showModalDialog() CD-313 Appendix F ✦ Examples from Parts III and IV <OPTION VALUE=”24”>24 <OPTION VALUE=”32”>32 <OPTION VALUE=”48”>48 </SELECT> </TR> </TABLE> </FORM> <DIV STYLE=”position:absolute; left:200px; top:220px”> <BUTTON STYLE=”width:80px” onClick=”handleOK()”>OK</BUTTON> <BUTTON STYLE=”width:80px” onClick=”handleCancel()”>Cancel</BUTTON> </DIV> </BODY> </HTML> One last convenience feature of the dialog box window is the onKeyPress event handler in the text box. The function it invokes looks for the Enter key. If that key is pressed while the box has focus, the same handleOK() function is invoked, as if the user had clicked the OK button. This feature makes the dialog box behave as if the OK button is an automatic default, just as “real” dialog boxes. You should observe several important structural changes that were made to turn the modal approach into a modeless one. Listing 16-41 shows the version of the main window modified for use with a modeless dialog box. Another global variable, prefsDlog, is initialized to eventually store the reference to the modeless window returned by the showModelessDialog() method. The variable gets used to invoke the init() function inside the modeless dialog box, but also as conditions in an if construction surrounding the generation of the dialog box. The reason this is needed is to prevent multiple instances of the dialog box being created (the button is still alive while the modeless window is showing). The dialog box won’t be created again as long as there is a value in prefsDlog, and the dialog box window has not been closed (picking up the window.closed property of the dialog box window). The showModelessDialog() method’s second parameter is a reference to the func- tion in the main window that updates the main document. As you see in a moment, that function is invoked from the dialog box when the user clicks the OK or Apply buttons. Listing 16-41: Main Page for showModelessDialog() <HTML> <HEAD> <TITLE>window.setModelessDialog() Method</TITLE> <SCRIPT LANGUAGE=”JavaScript”> var currPrefs = new Array() Continued windowObject.showModalDialog() CD-314 Part VI ✦ Appendixes Listing 16-41 (continued) var prefsDlog function getPrefsData() { if (!prefsDlog || prefsDlog.closed) { prefsDlog = showModelessDialog(“lst16-42.htm”, setPrefs, “dialogWidth:400px; dialogHeight:300px”) prefsDlog.init(currPrefs) } } function setPrefs(prefs) { if (prefs[“bgColor”]) { document.body.style.backgroundColor = prefs[“bgColor”] currPrefs[“bgColor”] = prefs[“bgColor”] } if (prefs[“textColor”]) { document.body.style.color = prefs[“textColor”] currPrefs[“textColor”] = prefs[“textColor”] } if (prefs[“h1Size”]) { document.all.welcomeHeader.style.fontSize = prefs[“h1Size”] currPrefs[“h1Size”] = prefs[“h1Size”] } if (prefs[“name”]) { document.all.firstName.innerText = prefs[“name”] currPrefs[“name”] = prefs[“name”] } } function init() { document.all.firstName.innerText = “friend” } </SCRIPT> </HEAD> <BODY BGCOLOR=”#eeeeee” STYLE=”margin:20px” onLoad=”init()”> <H1>window.setModelessDialog() Method</H1> <HR> <H2 ID=”welcomeHeader”>Welcome, <SPAN ID=”firstName”> </SPAN>!</H2> <HR> <P>Use this button to set style preferences for this page: <BUTTON ID=”prefsButton” onClick=”getPrefsData()”> Preferences </BUTTON> </BODY> </HTML> windowObject.showModalDialog() CD-315 Appendix F ✦ Examples from Parts III and IV Changes to the dialog box window document for a modeless version (Listing 16-42) are rather limited. A new button is added to the bottom of the screen for an Apply button. As in many dialog box windows you see in Microsoft products, the Apply but- ton lets current settings in dialog boxes be applied to the current document but with- out closing the dialog box. This approach makes experimenting with settings easier. The Apply button invokes a handleApply() function, which works the same as handleOK(), except the dialog box is not closed. But these two functions communi- cate back to the main window differently than a modal dialog box. The main window’s processing function is passed as the second parameter of showModelessDialog() and is available as the window.dialogArguments property in the dialog box win- dow’s script. That function reference is assigned to a local variable in both functions, and the remote function is invoked, passing the results of the getFormData() func- tion as parameter values back to the main window. Listing 16-42: Document for the Modeless Dialog Box <HTML> <HEAD> <TITLE>User Preferences</TITLE> <SCRIPT LANGUAGE=”JavaScript”> // Close the dialog function closeme() { window.close() } // Handle click of OK button function handleOK() { var returnFunc = window.dialogArguments returnFunc(getFormData()) closeme() } // Handle click of Apply button function handleApply() { var returnFunc = window.dialogArguments returnFunc(getFormData()) } // Handle click of Cancel button function handleCancel() { window.returnValue = “” closeme() } // Generic function converts form element name-value pairs // into an array Continued windowObject.showModalDialog() CD-316 Part VI ✦ Appendixes Listing 16-42 (continued) function getFormData() { var form = document.prefs var returnedData = new Array() // Harvest values for each type of form element for (var i = 0; i < form.elements.length; i++) { if (form.elements[i].type == “text”) { returnedData[form.elements[i].name] = form.elements[i].value } else if (form.elements[i].type.indexOf(“select”) != -1) { returnedData[form.elements[i].name] = form.elements[i].options[form.elements[i].selectedIndex].value } else if (form.elements[i].type == “radio”) { returnedData[form.elements[i].name] = form.elements[i].value } else if (form.elements[i].type == “checkbox”) { returnedData[form.elements[i].name] = form.elements[i].value } else continue } return returnedData } // Initialize by setting form elements from passed data function init(currPrefs) { if (currPrefs) { var form = document.prefs if (currPrefs[“name”]) { form.name.value = currPrefs[“name”] } if (currPrefs[“bgColor”]) { setSelected(form.bgColor, currPrefs[“bgColor”]) } if (currPrefs[“textColor”]) { setSelected(form.textColor, currPrefs[“textColor”]) } if (currPrefs[“h1Size”]) { setSelected(form.h1Size, currPrefs[“h1Size”]) } } } // Utility function to set a SELECT element to one value function setSelected(select, value) { for (var i = 0; i < select.options.length; i++) { if (select.options[i].value == value) { select.selectedIndex = i break } } return } windowObject.showModalDialog() CD-317 Appendix F ✦ Examples from Parts III and IV // Utility function to accept a press of the // Enter key in the text field as a click of OK function checkEnter() { if (window.event.keyCode == 13) { handleOK() } } </SCRIPT> </HEAD> <BODY BGCOLOR=”#eeeeee” onLoad=”init()”> <H2>Web Site Preferences</H2> <HR> <TABLE BORDER=0 CELLSPACING=2> <FORM NAME=”prefs” onSubmit=”return false”> <TR> <TD>Enter your first name:<INPUT NAME=”name” TYPE=”text” VALUE=”” SIZE=20 onKeyDown=”checkEnter()”> </TR> <TR> <TD>Select a background color: <SELECT NAME=”bgColor”> <OPTION VALUE=”beige”>Beige <OPTION VALUE=”antiquewhite”>Antique White <OPTION VALUE=”goldenrod”>Goldenrod <OPTION VALUE=”lime”>Lime <OPTION VALUE=”powderblue”>Powder Blue <OPTION VALUE=”slategray”>Slate Gray </SELECT> </TR> <TR> <TD>Select a text color: <SELECT NAME=”textColor”> <OPTION VALUE=”black”>Black <OPTION VALUE=”white”>White <OPTION VALUE=”navy”>Navy Blue <OPTION VALUE=”darkorange”>Dark Orange <OPTION VALUE=”seagreen”>Sea Green <OPTION VALUE=”teal”>Teal </SELECT> </TR> <TR> <TD>Select “Welcome” heading font point size: <SELECT NAME=”h1Size”> <OPTION VALUE=”12”>12 <OPTION VALUE=”14”>14 Continued windowObject.showModalDialog() CD-318 Part VI ✦ Appendixes Listing 16-42 (continued) <OPTION VALUE=”18”>18 <OPTION VALUE=”24”>24 <OPTION VALUE=”32”>32 <OPTION VALUE=”48”>48 </SELECT> </TR> </TABLE> </FORM> <DIV STYLE=”position:absolute; left:120px; top:220px”> <BUTTON STYLE=”width:80px” onClick=”handleOK()”>OK</BUTTON> <BUTTON STYLE=”width:80px” onClick=”handleCancel()”>Cancel</BUTTON> <BUTTON STYLE=”width:80px” onClick=”handleApply()”>Apply</BUTTON> </DIV> </BODY> </HTML> The biggest design challenge you probably face with respect to these windows is deciding between a modal and modeless dialog box style. Some designers insist that modality has no place in a graphical user interface; others say that there are times when you need to focus the user on a very specific task before any further processing can take place. That’s where a modal dialog box makes perfect sense. sizeToContent() NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓ Example Use The Evaluator (Chapter 13) in NN6 to try the sizeToContent() method. Assuming that you are running The Evaluator from the Chap13 directory on the CD-ROM (or the directory copied as-is to your hard disk), you can open a subwin- dow with one of the other files in the directory, and then size the subwindow. Enter the following statements into the top text box: a = window.open(“lst13-02.htm”,””) a.sizeToContent() The resized subwindow is at the minimum recommended width for a browser win- dow, and at a height tall enough to display the little bit of content in the document. windowObject.sizeToContent() CD-319 Appendix F ✦ Examples from Parts III and IV Event handlers onAfterPrint onBeforePrint NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ Example The following script fragment assumes that the page includes a DIV element whose style sheet includes a setting of display:none as the page loads. Somewhere in the Head, the print-related event handlers are set as properties: function showPrintCopyright() { document.all.printCopyright.style.display = “block” } function hidePrintCopyright() { document.all.printCopyright.style.display = “none” } window.onbeforeprint = showPrintCopyright window.onafterprint = hidePrintCopyright onBeforeUnload NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example The simple page in Listing 16-43 shows you how to give the user a chance to stay on the page. Listing 16-43: Using the onBeforeUnload Event Handler <HTML> <HEAD> <TITLE>onBeforeUnload Event Handler</TITLE> Continued windowObject.onBeforeUnload CD-320 Part VI ✦ Appendixes Listing 16-43 (continued) <SCRIPT LANGUAGE=”JavaScript”> function verifyClose() { event.returnValue = “We really like you and hope you will stay longer.” } window.onbeforeunload = verifyClose </SCRIPT> </HEAD> <BODY> <H1>onBeforeUnload Event Handler</H1> <HR> <P>Use this button to navigate to the previous page: <BUTTON ID=”go” onClick=”history.back()”> Go Back </BUTTON> </BODY> </HTML> onHelp NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example The following script fragment can be embedded in the IE5-only modeless dialog box code in Listing 16-44 to provide context-sensitive help within the dialog box. Help messages for only two of the form elements are shown here, but in a real applica- tion you add messages for the rest. function showHelp() { switch (event.srcElement.name) { case “bgColor” : alert(“Choose a color for the main window\’s background.”) break case “name” : alert(“Enter your first name for a friendly greeting.”) break default : alert(“Make preference settings for the main page styles.”) } windowObject.onHelp CD-321 Appendix F ✦ Examples from Parts III and IV event.returnValue = false } window.onhelp = showHelp Because this page’s help focuses on form elements, the switch construction cases are based on the name properties of the form elements. For other kinds of pages, the id properties may be more appropriate. FRAME Element Object Properties borderColor NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example Although you may experience problems (especially in IE5) changing the color of a single frame border, the W3C DOM syntax would look like the following if the script were inside the framesetting document: document.getElementById(“contentsFrame”).borderColor = “red” The IE-only version would be: document.all[“contentsFrame”].borderColor = “red” These examples assume the frame name arrives to a script function as a string. If the script is executing in one of the frames of the frameset, add a reference to parent in the preceding statements. contentDocument NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓ FRAME.contentDocument . VALUE=”beige”>Beige <OPTION VALUE=”antiquewhite”>Antique White <OPTION VALUE=”goldenrod”>Goldenrod <OPTION VALUE=”lime”>Lime <OPTION VALUE=”powderblue”>Powder Blue <OPTION. showModelessDialog() <HTML> <HEAD> <TITLE>window.setModelessDialog() Method</TITLE> <SCRIPT LANGUAGE= JavaScript > var currPrefs = new Array() Continued windowObject.showModalDialog() CD-314 Part VI ✦ Appendixes Listing 16-41 (continued) var. VALUE=”beige”>Beige <OPTION VALUE=”antiquewhite”>Antique White <OPTION VALUE=”goldenrod”>Goldenrod <OPTION VALUE=”lime”>Lime <OPTION VALUE=”powderblue”>Powder Blue <OPTION