<html> <head> <style type="text/css"> div.guess { border: thick double black; padding: 1em; width: 50%; font-family: Arial, Helvetica, sans-serif; } div.guess h2 { margin: 0; padding: 0; text-align: center; margin-left: 1em; margin-right: 1em; } div.guess input { font-size: 100%; } div.guess p.input { margin: 0; padding: 0; font-size: 150%; margin-top: .5em; margin-bottom: .5em; text-align: center; margin-left: 1em; margin-right: 1em; } div.guess input.button { margin: 0; padding: 0; display: inline; padding-left: .5em; padding-right: .5em; padding-top: .25em; padding-bottom: .25em; } div#alert1 { position: absolute; width: 25%; border:medium solid black; display: none; background-color: white; color: black; text-align: center; padding-bottom: 1em; font-family: Arial, Helvetica, sans-serif; } div#alert1 p.title { margin: 0; padding: 0; color: white; background-color: black; text-align: center; font-weight: bold; border-top: thin solid white; border-left: thin solid white; border-right: thin solid white; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function () { var guess1 = new guess(1, 10, 'guess1', 'guess1_text', 'guess1_check', 'guess1_again', 'alert1'); }); // // keyCodes is an object that defines keycodes for the key handlers // function keyCodes () { // Define values for keycodes this.tab = 9; this.enter = 13; this.esc = 27; this.space = 32; } // // alertDlg() is a class to implement a modal alert dialog // // @param (alert_id string) alert_id is the id of the dialog to create // // @param (game_id string) game_id is the id to attach the dialog to // @return N/A // function alertDlg(alert_id, game_id) { var dlg = '<div id="' + alert_id + '" role="alertdialog" tabindex="-1" aria-hidden="true" aria-labeledby="' + alert_id + '_title"><p id="' + alert_id + '_title" class="title">Alert Box</p><p id="' + alert_id + '_message">No Message</p><input id="' + alert_id + '_close" type="button" value="Close" /></div>'; // append the dialog to the document $('div#' + game_id).append(dlg); // Define the object properties this.$dlg = $('#' + alert_id); // the object pointer of the dialog this.$game = $('#' + game_id); // the object pointer of the containing div for the game this.$msg = $('#' + alert_id + '_message'); // the object pointer of the alert message area this.$button = $('#' + alert_id + '_close'); // the object pointer of the alert close button this.$focus; // the object pointer of a page element to give focus to on dialog dismissal this.keys = new keyCodes(); // bind handlers this.bindHandlers(); } // end alertDlg constructor // // showMsg() is a member function to set the message text of the alertDlg // // @param (msg string) msg is the message to display in the dialog box. // // @param (focusId string) focusId is the id of the element to give focus to when the dialog is dismissed. // // @return N/A // alertDlg.prototype.showMsg = function (msg, $focus) { // Store the focus ID this.$focus = $focus; // Set the message text this.$msg.html(msg); // Show the dialog this.showDlg(); } // end showMsg() // // bindHandlers() is a member function to bind event handlers to the modal alert dialog // // @return N/A // alertDlg.prototype.bindHandlers = function () { var thisObj = this; // store the this pointer // bind a keydown handler this.$dlg.keydown(function(e) { return thisObj.handleDlgKeyDown(e); }); // bind a keypress handler this.$dlg.keypress(function(e) { return thisObj.handleDlgKeyPress(e); }); // bind a click handler this.$button.click(function(e) { return thisObj.handleCloseClick(e); }); } // end bindhandlers() // // handleDlgKeyDown() is a member function to process keydown events for the alert dialog // // @param (evt obj) evt is the event object associated with the keydown event // // @return (boolean) true if propagating; false if consuming event // alertDlg.prototype.handleDlgKeyDown = function(evt) { if (evt.ctrlKey || evt.AltKey) { // do nothing return true; } switch (evt.keyCode) { case this.keys.tab: { // Consume the tab event and do nothing evt.stopPropagation; return false; } case this.keys.enter: case this.keys.esc: case this.keys.space: { // hide the dialog this.hideDlg(); evt.stopPropagation; return false; break; } } // end switch return true; } // end handleDlgKeyDown() // // handleDlgKeyPress() is a member function to consume keypress events for the alert dialog // // @param (evt obj) evt is the event object associated with the keydown event // // @return (boolean) true if propagating; false if consuming event // alertDlg.prototype.handleDlgKeyPress = function(evt) { if (evt.ctrlKey || evt.AltKey) { // do nothing return true; } switch (evt.keyCode) { case this.keys.tab: case this.keys.enter: case this.keys.esc: case this.keys.space: { evt.stopPropagation; return false; break; } } // end switch return true; } // end handleDlgKeyPress() // // handleCloseClick() is a member function to process click events for the alert dialog close button // // @param (evt obj) evt is the event object associated with the click event // // @return (boolean) true if propagating; false if consuming event // alertDlg.prototype.handleCloseClick = function(evt) { if (evt.shiftKey || evt.ctrlKey || evt.AltKey) { // do nothing return true; } // Hide the dialog this.hideDlg(); evt.stopPropagation; return false; } // end handleCloseClick() // // showDlg() is a member function to show the alert dialog and give it focus // // @return N/A // alertDlg.prototype.showDlg = function() { var thisObj = this; // Bind an event listener to the document to capture all mouse events to make dialog modal $(document).bind('click mousedown mouseup mousemove mouseover', function(e) { //ensure focus remains on the dialog thisObj.$dlg.focus(); // Consume all mouse events and do nothing e.stopPropagation; return false; }); // Position the dialog centered in the containing div this.$dlg.css('left', (this.$game.width() - this.$dlg.width()) / 2 + this.$game.offset().left + 'px'); this.$dlg.css('top', (this.$game.height() - this.$dlg.height()) / 2 + this.$game.offset().top + 'px'); // Display the dialog this.$dlg.show(); this.$dlg.attr('aria-hidden', 'false'); // Give the dialog focus this.$dlg.attr('tabindex', '0'); this.$dlg.focus(); } // end showDlg() // // hideDlg() is a member function to hide the alert dialog and return focus to the page // // @return N/A // alertDlg.prototype.hideDlg = function() { // set aria hidden attribute and remove dialog from tab order this.$dlg.attr('aria-hidden', 'true'); this.$dlg.attr('tabindex', '-1'); // hide the dialog this.$dlg.hide(); // Unbind the document mouse event listeners $(document).unbind('click mousedown mouseup mousemove'); // return focus to the specified page element if (this.$focus) { this.$focus.focus(); } } // end hideDlg() /////////////////////////////////////////////////////////////////////////////////////////// // // guess() is a class to implement a simple number guessing game // // @param (game_id) game_id is the id to attach the instance of the game to. // // @param (max integer) min is the maximum number to guess. // // @param (text_id string) text_id is the id of the text box where player enters a guess. // // @param (check_id string) check_id is the id of the check guess button. // // @param (again_id string) again_id is the id of the play again button. // // @param (alertObj) alertObj is the modal dialog object where game messages will be printed. // // @return N/A // function guess(min, max, game_id, text_id, check_id, again_id, alert_id) { // define class properties this.minGuess = min; // the minimum number to guess this.maxGuess = max; // the maximum number to guess this.$text = $('#' + text_id); // the jQuery object pointer to the text box this.$check = $('#' + check_id); // the jQuery object pointer to the check guess button this.$again = $('#' + again_id); // the jQuery object pointer to the play again button this.alertDlg = new alertDlg('alert1', game_id); // the modal alert dialog to be displayed during the game this.guessVal = -1; // the number for the player to guess this.guessCount = 0; // the number of attempts the player has made this.keys = new keyCodes(); // bind event handlers this.bindHandlers(); // initialize the game this.newGame(); } // end guess object constructor // // newGame() is a member function to set up a new game. The function chooses a number // between 1 and the max number specified at instantiation, sets the guess count to 0, and // show the user a message to make a guess. // // @return N/A guess.prototype.newGame = function () { // get a new random number for the player to guess this.guessVal = Math.floor(Math.random()*(this.maxGuess - this.minGuess + 1)) + this.minGuess; // reset the guess count this.guessCount = 0; // reset the guess text box this.$text.val(''); this.$text.attr('aria-invalid', 'false'); // Re-enable the buttons this.$text.removeAttr('disabled'); this.$check.removeAttr('disabled'); // Set focus on the guess text box this.$text.focus(); } // end newGame // // bindHandlers() is a function to bind the event handlers for the game controls // // @return N/A // guess.prototype.bindHandlers = function () { var thisObj = this; // Store the this pointer // bind a focus handler for the guess text box this.$text.focus(function (e) { thisObj.handleTextFocus(e); return true; }); // bind a keydown handler for the guess text box this.$text.keydown(function (e) { return thisObj.handleTextKeyDown(e); }); // bind a keypress handler for the guess text box this.$text.keypress(function (e) { return thisObj.handleTextKeyPress(e); }); // bind a click handler for the check guess button this.$check.click(function (e) { return thisObj.handleCheckClick(e); }); // bind a click handler for the play again button this.$again.click(function (e) { return thisObj.handleAgainClick(e); }); } // end bindHandlers() // // handleTextFocus() is a member function to process focus events for the guess text box // // @input (evt obj) evt is the event object associated with the keydown event // // @return N/A // guess.prototype.handleTextFocus = function(evt) { // Select any text in the text box this.$text.select(); } // end handleTextFocus() // // handleTextKeyDown() is a member function to process keydown events for the guess text box // // @input (evt obj) evt is the event object associated with the keydown event // // @return (boolean) false if consuming event, true if propagating // guess.prototype.handleTextKeyDown = function(evt) { // do nothing if shift, alt, or ctrl key pressed. if (evt.shiftKey || evt.altKey || evt.ctrlKey) { return true; } if (evt.keyCode == this.keys.enter) { // validate the guess if (this.validateGuess() == true) { // increment the guess count this.guessCount++; // see if the player has won if (this.checkGuess() == true) { // disable the guess text box and the check guess button this.$text.attr('disabled', 'true'); this.$check.attr('disabled', 'true'); } } evt.stopPropagation; return false; } return true; } // end handleTextKeyDown() // // handleTextKeyPress() is a member function to process keypress events for the guess text box. This function // is included to handle browsers that perform window scrolling, etc. on keypress rather than keydown. // // @input (evt obj) evt is the event object associated with the keypress event // // @return (boolean) false if consuming event, true if propagating // guess.prototype.handleTextKeyPress = function(evt) { // do nothing if shift, alt, or ctrl key pressed. if (evt.shiftKey || evt.altKey || evt.ctrlKey) { return true; } if (evt.keyCode == this.enterKey) { // consume the event evt.stopPropagation; return false; } return true; } // end handleTextKeyPress() // // handleCheckClick() is a member function to process click events for the check guess button // // @input (evt obj) evt is the event object associated with the click event // // @return (boolean) false if consuming event, true if propagating // guess.prototype.handleCheckClick = function(evt) { // do nothing if shift, alt, or ctrl key pressed. if (evt.shiftKey || evt.altKey || evt.ctrlKey) { return true; } // validate the guess if (this.validateGuess() == true) { // increment the guess count this.guessCount++; // see if the player has won if (this.checkGuess() == true) { // disable the guess text box and the check guess button this.$text.attr('disabled', 'true'); this.$check.attr('disabled', 'true'); } } evt.stopPropagation; return false; } // end handleCheckClick() // // handleAgainClick() is a member function to process click events for the play again button // // @input (evt obj) evt is the event object associated with the click event // // @return (boolean) false if consuming event, true if propagating // guess.prototype.handleAgainClick = function(evt) { // do nothing if shift, alt, or ctrl key pressed. if (evt.shiftKey || evt.altKey || evt.ctrlKey) { return true; } // Setup a new game this.newGame(); evt.stopPropagation; return false; } // end handleTextKeyDown() // // validateGuess() is a member function to validate a player's guess. If the guess is not a number, is less than // the minimum allowed guess, or is greater than the maximum allowed guess, the user is warned that the guess is invalid // // @return (boolean) true if guess is valid; false if guess is invalid // guess.prototype.validateGuess = function() { var val = this.$text.val(); if (this.$text.val() == '') { // guess is empty this.$text.attr('aria-invalid', 'true'); this.alertDlg.showMsg('You must enter a number!', this.$text); return false; } else if (isNaN(val) == true) { // guess is not a number this.$text.attr('aria-invalid', 'true'); this.alertDlg.showMsg('\'' + this.$text.val() + '\' is not a number!', this.$text); return false; } else if (val < this.minGuess || val > this.maxGuess) { // guess is out of range this.$text.attr('aria-invalid', 'true'); this.alertDlg.showMsg('You must choose a number between ' + this.minGuess + ' and ' + this.maxGuess + '!', this.$text); return false; } this.$text.attr('aria-invalid', 'false'); return true; } // end validateGuess() // // checkGuess() is a member function to check the player's guess to see if he or she has won the game // // @return (boolean) true if the player has won; false if not guess.prototype.checkGuess = function() { var guess = this.$text.val(); if (guess == this.guessVal) { // The player has won. Tell the player how many tries it took if (this.guessCount == 1) { this.alertDlg.showMsg('\'' + guess + '\' is right. You got it on your first try!', this.$again); } else { this.alertDlg.showMsg('\'' + guess + '\' is right. It only took you ' + this.guessCount + ' tries!', this.$again); } return true; } // Player did not guess the correct number. Tell the player if he or she is too high or too low if (guess < this.guessVal) { this.alertDlg.showMsg('\'' + guess + '\' is too low. Try a higher number.', this.$text); } else { this.alertDlg.showMsg('\'' + guess + '\' is too high. Try a lower number.', this.$text); } return false; } // end checkGuess() </script> </head> <body> <div role="application"> <div id="guess1" class="guess"> <h2>Number Guessing Game</h2> <p><strong>Instructions:</strong> In this game you guess a number between 1 an 10 and then press the "Check My Guess" button to check your responses. An <abbr title="Accessible Rich Internet Application">ARIA</abbr> dialog box will display the results of your guess. To start over again to press the "Play Again" button.</p> <p class="input"> <label id="guess1_label" for="guess1_text">Guess a number between 1 and 10</label> <input type="text" id="guess1_text" size="3" aria-labelledby="guess1_label" aria-invalid="false"> </p> <p class="input"> <input class="button" id="guess1_check" type="button" value="Check My Guess"/> <input class="button" id="guess1_again" type="button" value="Play Again"/> </p> </div> </div> </body> </html>