~~SLIDESHOW~~
Contact Hour 13: To be discussed on Tuesday 26th February, 2013.
Lecturer: Dr Chris P. Jobling.
Concluding our description of the objects, methods and properties that allow scripts to interact with HTML documents.
Based on Chapter 5 of Robert W. Sebasta, Programming the World-Wide Web, 3rd Edition, Addison Wesley, 2006 and Chapter 7 of Chris Bates, Web Programming: Building Internet Applications, 3rd Edition, John Wiley, 2006.
More on the event model, using events for form validation, and the DOM 2 event model.
At the end of this lecture you should be able to answer these questions:
onsubmit
event returns false
? At the end of this lecture you should be able to answer these questions:
addEventListener
method. At the end of this lecture you should be able to answer these questions:
clientX
and clientY
properties store? Used HTML event attributes
var dom = document.getElementById("myForm") for (index = 0; i < dom.planeButton.length; index++) { dom.planeButton[index].onclick = planeChoice; }
This works because form elements that have the same name are automatically coerced into a JavaScript array with that name.
To ensure correct assignment of even handlers, the script must either be the last thing that the browser loads or the execution of the registration code must be deferred until the document is ready.
planeButton
:var dom = document.getElementById("myForm"); for (var index = 0; index < dom.planeButton.length; index++) { if (dom.planeButton[index].checked) { plane = dom.planeButton[index].value; break; } }
<!DOCTYPE html> <!-- radio_click2.hmtl An example of the use of the click event with radio buttons, registering the event handler by assigning an event property --> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Illustrate messages for radio buttons</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="css/main.css"> </head> <body> <div class="container"> <h1>Illustrate messages for radio buttons</h1> <h2> Cessna single-engine airplane descriptions </h2> <form id="myForm" action="/cgi-bin/echo_params.cgi"> <fieldset> <legend>Types of Plane</legend> <label class="radio"> <input type="radio" name="planeButton" value="152" />Model 152</label> <label class="radio"> <input type="radio" name="planeButton" value="172" />Model 172 (Skyhawk)</label> <label class="radio"> <input type="radio" name="planeButton" value="182" />Model 182 (Skylane)</label> <label class="radio"> <input type="radio" name="planeButton" value="210" />Model 210 (Centurian)</label> </fieldset> <p> <input class="btn" type="reset" value="Cancel"> <input class="btn btn-primary" type="submit"> </p> </form> </div> <!-- /container --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.0.min.js"><\/script>')</script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/plugins.js"></script> <!-- Any external JS loaded here --> <script src="radio_click2.js"></script> </body> </html>
Code: JavaScript
var planeChoice = function() { // Put the DOM address of the elements array in a local variable var dom = document.getElementById("myForm"); // Determine which button was pressed for (var index = 0; index < dom.planeButton.length; index++) { if (dom.planeButton[index].checked) { plane = dom.planeButton[index].value; break; } } // Produce an alert message about the chosen airplane switch (plane) { case "152": alert("A small two-place airplane for flight training"); break; case "172": alert("The smaller of two four-place airplanes"); break; case "182": alert("The larger of two four-place airplanes"); break; case "210": alert("A six-place high-performance airplane"); break; default: alert("Error in JavaScript function planeChoice"); break; } }; // Register event handlers var dom = document.getElementById("myForm") for (index = 0; index < dom.planeButton.length; index++) { dom.planeButton[index].onclick = planeChoice; }
<!DOCTYPE html> <!-- template HTML file --> <html class="no-js" lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Accessing Radio Buttons</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="css/main.css"> <script src="js/vendor/modernizr-2.6.2-respond-1.1.0.min.js"></script> </head> <body> <div class="container"> <h1>The Focus Event</h1> <h2> Coffee Order Form </h2> <form class="horizontal-form" method="post" action="/cgi-bin/echo_params.cgi"> <!-- A bordered table for item orders --> <table class="table table-striped" border="1" summary="order form for coffee"> <!-- First, the column headings --> <thead> <th>Product Name</th> <th>Price</th> <th>Quantity</th> </thead> <!-- Now, the table data entries --> <tbody> <tr class="control-group"> <td> <label for="french">French Vanilla (500 g.)</label> </td> <td>$3.49</td> <td> <!-- Note use of the pattern attribute to ensure quantity is an integer For browsers that don't support the pattern attribute, you would need to include a JavaScript validation script that does the same thing --> <input class="span1" type="text" id="french" name="french" size="2" pattern="^\d{1,}$" /> </td> </tr> <tr class="control-group"> <td> <label for="hazlenut">Hazlenut Cream (500 g.)</label> </td> <td>$3.95</td> <td> <input class="span1" type="text" id="hazlenut" name="hazlenut" size="2" /> </td> </tr> <tr class="control-group"> <td> <label for="columbian">Columbian (500 g.)</label> </td> <td>$4.59</td> <td> <input class="span1" type="text" id="columbian" name="columbian" size="2" /> </td> </tr> </tbody> </table> <!-- Button for precomputation of the total cost --> <div class="input-append"> <input class="input-small" type="text" id="cost" onfocus="this.blur();" /> <input class="btn btn-info" type="button" value="Total cost"/> </div> <!-- The submit and reset buttons --> <p> <input class="btn btn-primary" type="submit" value="Submit Order" /> <input class="btn" type="reset" value="Clear Order Form" /> </p> </form> </div> <!-- /container --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.0.min.js"><\/script>')</script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/plugins.js"></script> <!-- Any external JS loaded here --> <script src="nochange.js"></script> </body> </html>
Code: JavaScript
// The event handler function to compute the cost var computeCost = function() { var french = document.getElementById("french").value; var hazlenut = document.getElementById("hazlenut").value; var columbian = document.getElementById("columbian").value; // Compute the cost document.getElementById("cost").value = totalCost = french * 3.49 + hazlenut * 3.95 + columbian * 4.59; }; document.getElementById("total_cost").onclick = computeCost;
focus
function) select
function) <note>
focus
function puts the element in focus, which puts the cursor in the element:document.getElementById("phone").focus();
select
function highlights the text in the element</note>
false
focus
and select
only work if the handler is registered by assigning it to the element event
property focus
does not false
false
true
<!DOCTYPE html> <!-- pswd_chk.html An example of input password checking, using the onsubmit event --> <html class="no-js" lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Illustrate password checking</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="css/main.css"> <script src="js/vendor/modernizr-2.6.2-respond-1.1.0.min.js"></script> </head> <body> <div class="container"> <h1> Illustrate password checking </h1> <h2> Choose a Password </h2> <form id = "myForm" method="post" action = "/cgi-bin/echo_params.cgi"> <p> <label for="initial">Your password: </label> <input type="password" name="password" id="password" /> <label for="second">Verify password: </label> <input type="password" name="password_confirmation" id="password_confirmation" /> </p> <p> <input class="btn" type = "reset" name = "reset" /> <input class="btn btn-primary" type = "submit" name = "submit" /> </p> </form> </div> <!-- /container --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.0.min.js"><\/script>')</script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/plugins.js"></script> <!-- Any external JS loaded here --> <script src="pswd_chk.js"></script> </body> </html>
// The event handler for password checking var chkPasswords = function () { var password = document.getElementById("password"); var confirmation = document.getElementById("password_confirmation"); if (password.value === "") { alert("You did not enter a password \n" + "Please enter one now"); password.focus(); return false; } if (password.value !== confirmation.value) { alert("The two passwords you enterd are not the same \n" + "Please re-enter both now"); password.focus(); password.select(); return false; } else { return true; } }; // Set submit button onsubmit property to the event handler document.getElementById("password_confirmation").onblur = chkPasswords; document.getElementById("myForm").onsubmit = chkPasswords;
<!DOCTYPE html> <!-- validator.html An example of input validation using the change and submit events --> <html class="no-js" lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Illustrate form input validation</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="css/main.css"> <script src="js/vendor/modernizr-2.6.2-respond-1.1.0.min.js"></script> </head> <body> <div class="container"> <h1>Illustrate form input validation</h1> <h2>Customer Information</h2> <form method="post" action = "/cgi-bin/echo_params.cgi"> <Label for="custName">Name</Label> <div class="control-group"> <input class="span4" type = "text" id = "custName" name="custName" placeholder="Last name, First name, Middle initial"> <span class="help-block">Please enter your name as 'Last name, First name, Middle initial'.</span> </div> <div class="control-group"> <label for="phone">Phone number</label> <input class="span4" type = "text" id = "phone" name="phone" placeholder="123-456-7890"> <span class="help-block">Please enter your telephone number matching pattern '123-456-7890'.</span> </div> <p> <input class="btn" type = "reset" id = "reset" /> <input class="btn btn-primary" type = "submit" id = "submit" /> </p> </form> </div> <!-- /container --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.0.min.js"><\/script>')</script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/plugins.js"></script> <!-- Any external JS loaded here --> <script src="validator.js"></script> </body> </html>
// The event handler function for the name text box var chkName = function() { var myName = document.getElementById("custName"); // Test the format of the input name // Allow the spaces after the commas to be optional // Allow the period after the initial to be optional var pos = myName.value.search(/^[A-Z][a-z]+, ?[A-Z][a-z]+, ?[A-Z]\.?$/); if (pos != 0) { alert("The name you entered (" + myName.value + ") is not in the correct form. \n" + "The correct form is: " + "Last name, First name, Middle initial \n" + "Please go back and fix your name"); myName.focus(); myName.select(); return false; } else return true; }; // The event handler function for the phone number text box var chkPhone = function() { var myPhone = document.getElementById("phone"); // Test the format of the input phone number var pos = myPhone.value.search(/^\d{3}-\d{3}-\d{4}$/); if (pos != 0) { alert("The phone number you entered (" + myPhone.value + ") is not in the correct form. \n" + "The correct form is: ddd-ddd-dddd \n" + "Please go back and fix your phone number"); myPhone.focus(); myPhone.select(); return false; } else return true; }; var validate_form = function() { return (chkName() && chkPhone()); }; // Set form element object properties to their // corresponding event handler functions document.getElementById("custName").onchange = chkName; document.getElementById("phone").onchange = chkPhone; document.getElementById("submit").onclick = validate_form;
blur
, change
, etc.) and MouseEvent (click
, mouseup
, etc.) load
and unload
)stopPropagation
method of the Event
object Event
object method, preventDefault
, to stop default operations, such as submission of a form, if an error has been detected addEventListener
methodnode.addEventListener("change", chkName, false);
<note> The perceptive reader will see many parallels between DOM 2 event handling and the Java event model. </note>
removeEventListener
currentTarget
property of Event
always references the object on which the handler is being executed MouseEvent
interface (a sub-interface of Event
) has two properties, clientX
and clientY
, that have the x and y coordinates of the mouse cursor, relative to the upper left corner of the browser window // validator2.js // An example of input validation using the change and submit // events, using the DOM 2 event model // Note: This document does not work with IE6 var chkName = function(event) { // Get the target node of the event var myName = event.currentTarget; // Test the format of the input name // Allow the spaces after the commas to be optional // Allow the period after the initial to be optional var pos = myName.value.search(/^[A-Z][a-z]+, ?[A-Z][a-z]+, ?[A-Z]\.?$/); if (pos != 0) { alert("The name you entered (" + myName.value + ") is not in the correct form. \n" + "The correct form is: " + "Last name, First name, Middle initial \n" + "Please go back and fix your name"); myName.focus(); myName.select(); } }; // The event handler function for the phone number text box var chkPhone = function(event) { var myPhone = event.currentTarget; // Test the format of the input phone number var pos = myPhone.value.search(/^\d{3}-\d{3}-\d{4}$/); if (pos != 0) { alert("The phone number you entered (" + myPhone.value + ") is not in the correct form. \n" + "The correct form is: ddd-ddd-dddd \n" + "Please go back and fix your phone number"); myPhone.focus(); myPhone.select(); } }; // Set form element object properties to their // corresponding event handler functions // Get the DOM addresses of the elements and register // the event handlers var customerNode = document.getElementById("custName"); var phoneNode = document.getElementById("phone"); customerNode.addEventListener("change", chkName, false); phoneNode.addEventListener("change", chkPhone, false); // Challenge ... how would you check both name and telephone number on submit?
<note> DOM 0 and DOM 2 event handling can be mixed in a document </note>
appName
property has the browsers name appVersion
property has the version number
<note>
The properties appName
and appVersion
are not as informative as you'd expect!
appVersion
of IE6 and IE7 to 4.0 (?) appName
of Firefox 2.x to “Nestcape” and the appVersion
to 5.0 (?) Moral: don't rely on these to adjust behaviour! </note>
<!DOCTYPE html> <!-- navigate.html An example of using the navigator object --> <html lang="en"> <head> <meta charset="utf-8" /> <title> Using navigator </title> <script> // The event handler function to display the browser name // and its version number function navProperties() { alert("The browser is: " + navigator.appName + "\n" + "The version number is: " + navigator.appVersion + "\n"); } </script> </head> <body onload = "navProperties()"></body> </html>
More on the event model, using events for form validation, and the DOM 2 event model.
At the end of this lecture you should be able to answer these questions:
onsubmit
event returns false
? At the end of this lecture you should be able to answer these questions:
addEventListener
method. At the end of this lecture you should be able to answer these questions:
clientX
and clientY
properties store? There are some more review questions available.
onclick
event handler. These handlers must add the cost of their fruit to the total cost. An event handler for the Submit button must produce an alert window with the message "Your total cost is xxx p,"
where xxx is the total cost of the chosen fruit plus 17.5 percent VAT. This handler must return false
(to avoid actual submission of the form data).