COUNT_DOWN_TIMER


Time is what makes the observation of change possible.

Time is what prevents all phenomena from being perceived as occurring simultaneously.


The single web page application featured in this tutorial web page substantiates a count-down timer which enables the application user to select a value for N (i.e. the natural number of seconds to elapse to zero). When the application user clicks the start button, the start button will disappear and the number of seconds remaining will decrement by 1 per second starting at N until the number of seconds remaining is 0. When the number of seconds remaining is decremented to zero, an alert sound effect will be played and the start button will re-appear.

To view hidden text inside each of the preformatted text boxes below, scroll horizontally.


SOFTWARE_APPLICATION_COMPONENTS


Hyper-Text-Markup-Language_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer.html

Cascading-Style-Sheet_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/karbytes_aesthetic.css

JavaScript_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer.js

JavaScript_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/time_stamp.js

Waveform-Audio-file_(GitHub): https://github.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/blob/main/alert_sound_effect.wav

Waveform-Audio-file_(Internet_Archive): https://archive.org/details/alert_sound_effect


Hyper-Text-Markup-Language Code


The following Hyper-Text-Markup-Language (HTML) code defines the user interface component of the COUNT_DOWN_TIMER web page application. Copy the HTML code from the source code file which is linked below into a text editor and save that file as count_down_timer.html. Use a web browser such as Firefox to open that HTML file (and ensure that the JavaScript and Cascading-Style-Sheet files are in the same file directory as the HTML file).

Note that the contents of the HTML file are not displayed in a preformatted text box on this web page due to the fact that the WordPress server makes no distinction between HTML code which is encapsulated inside of a preformatted text box and WordPress web page source code.

Hyper-Text-Markup-Language_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer.html

Portable-Network-Graphics_image_link: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer_html_code_screenshot.png



Cascading-Style-Sheet Code


The following Cascading-Style-Sheet (CSS) code defines a stylesheet which customizes the appearance of interface components of the COUNT_DOWN_TIMER web page application. Copy the CSS code from the source code file which is linked below into a text editor and save that file as karbytes_aesthetic.css.

Cascading-Style-Sheet_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/karbytes_aesthetic.css


/**
 * file: karbytes_aesthetic.css
 * type: Cascading-Style-Sheet
 * date: 10_JULY_2023
 * author: karbytes
 * license: PUBLIC_DOMAIN
 */

/** Make the page background BLACK, the text orange and monospace, and the page content width 800 pixels or less. */
body {
 	background: #000000;
 	color: #ff9000;
 	font-family: monospace;
 	font-size: 16px;
 	padding: 10px;
 	width: 800px;
}

/** Make input elements and select elements have an orange rounded border, a BLACK background, and orange monospace text. */
input, select {
	background: #000000;
	color: #ff9000;
	border-color: #ff9000;
	border-width: 1px;
	border-style: solid;
	border-radius: 5px;
	padding: 10px;
	appearance: none;  
 	font-family: monospace;
 	font-size: 16px;
}

/** Invert the text color and background color of INPUT and SELECT elements when the cursor (i.e. mouse) hovers over them. */
input:hover, select:hover {
	background: #ff9000;
	color: #000000;
}

/** Make table data borders one pixel thick and CYAN. Give table data content 10 pixels in padding on all four sides. */
td {
	color: #00ffff;
	border-color: #00ffff;
	border-width: 1px;
	border-style: solid;
	padding: 10px;
}

/** Set the text color of elements whose identifier (id) is "output" to CYAN. */
#output {
	color: #00ffff;
}

/** Set the text color of elements whose class is "console" to GREEN and make the text background of those elements BLACK. */
.console {
	color: #00ff00;
	background: #000000;
}

JavaScript Code


The following JavaScript (JS) code defines the functions which control the behavior of the COUNT_DOWN_TIMER web page application. Copy the JS code from the source code file which is linked below into a text editor and save that file as count_down_timer.js.

JavaScript_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer.js


/**
 * file: count_down_timer.js
 * type: JavaScript
 * author: karbytes
 * date: 10_JULY_2023
 * license: PUBLIC_DOMAIN
 */

/**
 * Generate the HTML code for the portion of the web page interface display
 * which outputs the quantity of temporal units elapsed starting at
 * the time at which the start button was clicked and ending at the 
 * time at which the selected number of time units is decremented
 * to zero.
 * 
 * @return {String} the HTML for defining a SPAN element whose id is "nonnegative_integer_display"
 */
function generate_nonnegative_integer_display_span() {
	return ('<' + 'span id="nonnegative_integer_display"' + '>') + '0' + ('<' + '/' + 'span' + '>');
}

/**
 * Display a time-stamped message inside the DIV element whose identifier (id) 
 * is "application_status_messages_display".
 * which denotes the point in time at which the web page application was 
 * either opened or else reloaded by a web browser.
 *
 * Display "0" inside the SPAN element whose identifier is "seconds_elapsed_display".
 *
 * Set the input element whose identifier is "timer_session_start_button" 
 * to visible rather than to hidden.
 * 
 * Assume that this function is called when a web broswer opens count_down_timer.html 
 * or else reloads that web page.
 */
function initialize_application() {
	try {
		const message = ("The web page was opened at time: " + generate_time_stamp());
		console.log(message);
		document.getElementById("timer_start_button").style.visibility = "block";
		document.getElementById("seconds_elapsed_display").innerHTML = (('<' + 'p' + '>') + "seconds_remaining: " + generate_nonnegative_integer_display_span() + ('<' + '/' + 'p' + '>'));
		document.getElementById("application_status_messages_display").innerHTML = (('<' + 'p' + '>') + message + ('<' + '/' + 'p' + '>'));
	}
	catch(e) {
		console.log("An exception to normal functioning occurred during the runtime of initialize_application(): " + e);
	}
}

/**
 * Return the value of the selected menu OPTION of a SELECT menu element.
 * 
 * @param {String} select_menu_identifier is the id of a select HTML element.
 * 
 * @return {String} the value of the selected menu option.
 */
function get_selected_menu_option_value(select_menu_identifier) {
	try {
		let menu_object = {}, options_array = [], selected_option_index = 0, selected_option_object = {}, selected_option_value;
		menu_object = document.getElementById(select_menu_identifier);
		options_array = menu_object.options;
		selected_option_index = menu_object.selectedIndex;
		selected_option_object = options_array[selected_option_index];
		selected_option_value = selected_option_object.value
		return selected_option_value;
	}
	catch(e) {
		console.log("An exception to normal functioning occurred during the runtime of get_selected_menu_option(select_menu_identifier): " + e);
	}
}

/**
 * Play exactly one sound file exactly one time 
 * (i.e. for a finite duration of time there will 
 * be a sequence of auditory phenomena).
 *
 * Assume that the sound file, alert_sound_effect.wav, 
 * exists in the same file directory as this JavaScript file(s)
 * and the web page deploying this JavaScript file(s) and the
 * referenced audio file.
 */
function play_sound_file() {
	try {
		var audio = new Audio("alert_sound_effect.wav");
		audio.play();
	}
	catch(e) {
		console.log("An exception to normal functioning occurred during the runtime of play_sound_file(): " + e);
	}
}

/**
 * Terminate the timer session.
 * 
 * Assume that this function is called after the 
 * decrement_timer_display_by_one_second(simulation)
 * function is called N times.
 *
 * Print a time-stamped status message to the DIV element 
 * whose id is "application_status_messages_display"
 * which indicates that the timer session of N seconds 
 * is finished.
 * 
 * Attempt to play a sound which signifies that the timer
 * session has completed.
 */
function finish_simulation() {
	try {
		const message = ("The timed simulation finished at time: " + generate_time_stamp());
		console.log(message);
		document.getElementById("application_status_messages_display").innerHTML += (('<' + 'p' + '>') + message + ('<' + '/' + 'p' + '>'));
		document.getElementById("timer_start_button").style.display = "block";
		play_sound_file();
	}
	catch(e) {
		console.log("An exception to normal functioning occurred during the runtime of finish_simulation(): " + e);
	}
}

/**
 * Decrement the number of seconds remaining by one second.
 * If the number of seconds is less than one, then terminate the timer session.
 * 
 * Assume that there is a text HTML element whose id is "seconds_elapsed_display"
 * (and that the inner HTML of that element is an integer value).
 * 
 * @param {Object} simulation - an instance of some temporally finite process 
 */
function decrement_timer_display_by_one_second(simulation) {
	try {
		let timer_display, seconds_remaining;
		timer_display = document.getElementById("seconds_elapsed_display");
		seconds_remaining = parseInt(timer_display.innerHTML);
		seconds_remaining -= 1;
		timer_display.innerHTML = seconds_remaining;
 	    if (seconds_remaining < 1) {
 	    	/**
 	    	 * The native JavaScript clearInterval() function stops 
 	    	 * recurring function calls (such that the simulation object
 	    	 * represents a call to a particular function once per fixed
 	    	 * number of milliseconds).
 	    	 */
 	    	clearInterval(simulation);
 	    	finish_simulation();
 	    }
	}
	catch(e) {
		console.log("An exception to normal functioning occurred during the runtime of decrement_timer_display_by_one_second(simulation): " + e);
	}
}

/**
 * Print a time-stamped message to the web browser console window 
 * and to the web page element whose identifier is "seconds_elapsed_display" which
 * indicates the time at which the start() button was clicked.
 *
 * Hide the start() button to prevent overlapping timer processes.
 *
 * Set the span element whose identifier is "seconds_elapsed_display" 
 * to display the nonnegative integer, N, which was most recently selected
 * inside of the select menu whose identifier is "nonnegative_integer_interval_selector".
 *
 * If no menu option was selected, set N to 30 by default.
 *
 * For N consecutive seconds, decrement the nonnegative integer value stored
 * in the span element whose identifier is "seconds_elapsed_display"
 * by exactly 1 until that value becomes 0.
 *
 * After the N-second timer interval completes, display the hidden start()
 * button so that it can be clicked again.
 */
function start() {
	try {
		// Display the time at which the START button was clicked on the web page and in the browser console.
		let message = ("The start() button was clicked at time: " + generate_time_stamp()), N = 0, simulation = undefined;
		console.log(message);
		document.getElementById("application_status_messages_display").innerHTML += (('<' + 'p' + '>') + message + ('<' + '/' + 'p' + '>'));

		// Disable the start() button by hiding it until the simulation is finished.
		document.getElementById("timer_start_button").style.display = "none";

		N = parseInt(get_selected_menu_option_value("nonnegative_integer_interval_selector"));

		// Ensure that N is an Number type datum, integer, and value no smaller than 30 and no larger than 999.
		N = ((typeof N !== "number") || (N !== Math.floor(N)) || (N < 30) || (N > 999)) ? 30 : N;

		// Display the selected menu option on the web page and in the browser console.
		message = ("The selected value of N is " + N + ".");
		console.log(message);
		document.getElementById("application_status_messages_display").innerHTML += (('<' + 'p' + '>') + message + ('<' + '/' + 'p' + '>'));

		// Set the timer interval to N seconds and begin the incremental count down to 0 (in increments 1 second in length).
		document.getElementById("seconds_elapsed_display").innerHTML = N;

		// Begin updating the timer display once per second (and 1 second is equal to 1000 milliseconds).
		simulation = setInterval( function() { decrement_timer_display_by_one_second(simulation); }, 1000);
	}
	catch(e) {
		// Note: try-catch blocks are for "exception handling" (i.e. runtime error detection).
		console.log("An exception to normal functioning occurred during the runtime of start(): " + e);
	}
}

JavaScript Code


The following JavaScript (JS) code defines one function which controls the behavior of the COUNT_DOWN_TIMER web page application; namely the function which returns the number of milliseconds elapsed since the Unix Epoch concatenated to the string ” milliseconds since midnight on 01_JANUARY_1970″. Copy the JS code from the source code file which is linked below into a text editor and save that file as time_stamp.js.

JavaScript_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/time_stamp.js


/**
 * file: time_stamp.js
 * type: JavaScript
 * date: 10_JULY_2023
 * author: karbytes
 * license: PUBLIC_DOMAIN
 */

/**
 * Get the Number of milliseconds which have elapsed since the Unix Epoch.
 * The Unix Epoch is 01_JANUARY_1970 at midnight (Coordinated Universal Time (UTC)).
 * 
 * @return {String} message displaying the time at which this function was called.
 */
function generate_time_stamp() {
 	const milliseconds_elapsed_since_unix_epoch = Date.now();
 	return  milliseconds_elapsed_since_unix_epoch + " milliseconds since midnight on 01_JANUARY_1970.";
}

COUNT_DOWN_TIMER Interface (Initial)


The screenshot image below depicts what the COUNT_DOWN_TIMER web page interface is supposed to look like when the web page is initially loaded by a web browser.

image_link: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer_interface_initial.png



COUNT_DOWN_TIMER Interface (Progress)


The screenshot image below depicts what the COUNT_DOWN_TIMER web page interface could look like after the end user selects a value for N from the expandable menu before clicking on the start() button to initiate a count-down timer interval lasting N consecutive seconds.

(Notice that the start() button is hidden while the count-down timer session is in progress).

image_link: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer_interface_progress.png



COUNT_DOWN_TIMER Interface (Final)


The screenshot image below depicts what the COUNT_DOWN_TIMER web page interface could look like after N consecutive seconds elapse after the start() button is clicked.

(Notice that the start() button is unhidden after the count-down timer session finishes).

image_link: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_summer_2023_starter_pack/main/count_down_timer_interface_final.png



This web page was last updated on 10_JULY_2023. The content displayed on this web page is licensed as PUBLIC_DOMAIN intellectual property.