The following sub-sections describe and explain useful user-defined functions that have been written in JavaScript and used throughout this book.
The following function can be used to create HTML tables that have alternating row colors (the default colors are white and gray):
var rowNumber = 1; function getColor() { var color; if( rowNumber > 2 ) { rowNumber = 1; } if( rowNumber == 1 ) color = "gray"; else color = "white"; rowNumber++; return( color ); }
This function would be very useful if you wanted to display a large amount of data in a table.
The following is an example of using the getColor() function that shows just how easy it is to create an HTML table with alternating row colors:
<html> <head> <title> JavaScript Professional Projects - Functin Example </title> <script language="JavaScript"> <!-- var rowNumber = 1; function getColor() { var color; if( rowNumber > 2 ) { rowNumber = 1; } if( rowNumber == 1 ) color = "gray"; else color = "white"; rowNumber++; return( color ); } // --> </script> </head> <body> <table width="85%" border="1"> <script language="JavaScript"> <!-- for( i = 0 ; i < 25 ; i++ ) { document.write( "<tr bgcolor='" + getColor() + "'>" ); document.write( "<td>Row #" + i + "</td>" ); document.write( "</tr>" ); } // --> </script> </table> </body> </html>
This code example creates an HTML table with 25 rows and alternating colors.
The getColor() function could be simplified slightly by using the ternary operator, like this:
var rowNumber = 0; function getColor() { return( rowNumber++ % 2 == 0 ? "gray" : "white" ); }
Using the ternary operator would reduce the number of characters required for download, but would decrease the readability of the program.
The following very simple function will return the proper numeral postfix for any number:
function getEnding( number ) { if( number > 10 && number < 20 ) return( "th" ); switch( number % 10 ) { case 0: case 4: case 5: case 6: case 7: case 8: case 9: return( "th" ); case 1: return( "st" ); case 2: return( "nd" ); case 3: return( "rd" ); } }
This function would be very useful if you wanted to display a calendar with multiple days on it. Creating a calendar is the focus of Chapter 15
The linked list -insertAt-( index, value ) function was presented in Chapter 2, and is one of two functions that the Array object requires in order to be used as a fully functional linked list.
function insertAt( index, value ) { var part1 = this.slice( 0, index ); var part2 = this.slice( index ); part1.push( value ); return( part1.concat( part2 ) ); } Array.prototype.insertAt = insertAt;
This function, in combination with the linked list – removeAt, would provide all the functionality needed to use a regular array as a linked list.
The linked list - removeAt function is the second function the Array object requires in order to be used as a fully functional linked list.
function removeAt( index ) { var part1 = this.slice( 0, index ); var part2 = this.slice( index ); part1.pop(); return( part1.concat( part2 ) ); } Array.prototype.removeAt = removeAt;
This function, in combination with the linked list – insertAt function, would provide all the functionality needed to use a regular array as a linked list.
An example of using the linked list functions follows:
<html> <head> <title> JavaScript Professional Projects - Example Function </title> <script language="JavaScript"> <!-- function insertAt( index, value ) { var part1 = this.slice( 0, index ); var part2 = this.slice( index ); part1.push( value ); return( part1.concat( part2 ) ); } Array.prototype.insertAt = insertAt; function removeAt( index ) { var part1 = this.slice( 0, index ); var part2 = this.slice( index ); part1.pop(); return( part1.concat( part2 ) ); } Array.prototype.removeAt = removeAt; // --> </script> </head> <body> <p> <b>Before:</b><br> <script language="JavaScript"> <!-- var numbers = new Array( 8888, 3561, 0, 4133, 5555, 62, 1 ); document.write( numbers.join( "<br>" ) ); // --> </script> <br><br> <b>After:</b><br> <script language="JavaScript"> <!-- numbers = numbers.removeAt( 5 ); numbers = numbers.insertAt( 2, 666 ); document.write( numbers.join( "<br>" ) ); // --> </script> </p> </body> </html>
This function compares two strings lexicographically and returns a value specifying which string should come first alphabetically.
function compareTo( s ) { var len1 = this.length; var len2 = s.length; var n = ( len1 < len2 ? len1 : len2 ); for( i = 0 ; i < n ; i++ ) { var a = this.charCodeAt( i ); var b = s.charCodeAt( i ) if( a != b ) { return( a - b ); } } return( len1 - len2 ); } String.prototype.compareTo = compareTo;
The comparison is based on the Unicode value of each character in the strings. If there is a difference in either of the strings, a return value that demonstrates that difference is generated. If the function returns a value less than zero and a return value that is greater than zero, then this occurs lexicographically before ‘s’.
The sort() function recursively sorts an array of strings into alphabetical order. It makes extensive use of the compareTo() function above.
function sort( s ) { if( s.length == 1 ) return; else { var a = new Array( parseInt( s.length / 2 ) ); var b = new Array( s.length - a.length ); for( i = 0 ; i < a.length ; i++ ) a[i] = s[i]; for( i = 0 ; i < b.length ; i++ ) b[i] = s[i+a.length]; sort( a ); sort( b ); var ai = 0, bi = 0, i = 0; while( ai < a.length || bi < b.length ) { if( bi >= b.length ) s[i++] = a[ai++]; else if( ai >= a.length ) s[i++] = b[bi++]; else if( a[ai].compareTo( b[bi] ) <= 0 ) s[i++] = a[ai++]; else if( a[ai].compareTo( b[bi] ) > 0 ) s[i++] = b[bi++]; } } }
This is an extremely useful function, not only for sorting strings, but also for sorting the items in a list form element.
Following is an example of using this function with an array of strings:
<head> <title> JavaScript Professional Projects - Example Function </title> <script language="JavaScript"> <!-- var months = new Array( "January", "February", "March", "April", "June", "July", "August", "September", "October", "November", "December" ); function display() { for( i = 0 ; i < this.length ; i++ ) { document.write( this[i] + "<br>" ); } } Array.prototype.display = display; function sort( s ) { if( s.length == 1 ) return; else { var a = new Array( parseInt( s.length / 2 ) ); var b = new Array( s.length - a.length ); for( i = 0 ; i < a.length ; i++ ) a[i] = s[i]; for( i = 0 ; i < b.length ; i++ ) b[i] = s[i+a.length]; sort( a ); sort( b ); var ai = 0, bi = 0, i = 0; while( ai < a.length || bi < b.length ) { if( bi >= b.length ) s[i++] = a[ai++]; else if( ai >= a.length ) s[i++] = b[bi++]; else if( a[ai].compareTo( b[bi] ) <= 0 ) s[i++] = a[ai++]; else if( a[ai].compareTo( b[bi] ) > 0 ) s[i++] = b[bi++]; } } } function compareTo( s ) { var len1 = this.length; var len2 = s.length; var n = ( len1 < len2 ? len1 : len2 ); for( i = 0 ; i < n ; i++ ) { var a = this.charCodeAt( i ); var b = s.charCodeAt( i ) if( a != b ) { return( a - b ); } return( len1 - len2 ); } String.prototype.compareTo = compareTo; // --> </script> </head> <body> <table border=1 cellspacing="2" cellpadding="20"> <tr> <td width=150><b>Unsorted</b></td> <td width="150"><b>Sorted</b></td> </tr> <tr> <td> <script language="JavaScript"> <!-- months.display(); --> </script> </td> <td> <script language="JavaScript"> <!-- sort( months ); months.display(); --> </script> </td> </tr> </table> </body> </html>
The sortSelect() function sorts the contents of an HTML select box by using the compareTo() function presented previously.
function sortSelect( select ) { var a = new Array(); for( i = 0; i < select.options.length ; i++ ) { a[a.length] = new Option( select.options[i].text, select.options[i].value, select.options[i].defaultSelected, select.options[i].selected ) ; } a = a.sort( function( s, t ) { return( s.text.compareTo( t.text ) ); } ); for( i = 0; i < a.length ; i++ ) { select.options[i] = new Option( a[i].text, a[i].value, a[i].defaultSelected, a[i].selected ); } }
An example of using this function is presented in the next section.
The swapSelects() function moves a selected item in one select box into another select box, then sorts both lists using the sortSelect() function.
function swapSelects( fromSelect, toSelect ) { var toSelect_Length = toSelect.options.length; while( fromSelect.selectedIndex > -1 ) { var index = fromSelect.selectedIndex; toSelect.options[toSelect_Length] = new Option( fromSelect.options[index].text ); toSelect.options[toSelect_Length].value = fromSelect.options[index].value; fromSelect.options[index] = null; toSelect_Length++; } sortSelect( fromSelect ); sortSelect( toSelect ); }
Here is an example of using both the swapSelect() and sortSelect() functions:
<html> <head> <title> JavaScript Professional Projects - Working with Forms </title> <style type="text/css"> <!-- .sameSize{ width: 125; } --> </style> <script language="JavaScript"> <!-- var months = new Array( "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ); function swapSelects( fromSelect, toSelect ) { var toSelect_Length = toSelect.options.length; while( fromSelect.selectedIndex > -1 ) { var index = fromSelect.selectedIndex; toSelect.options[toSelect_Length] = new Option( fromSelect.options[index].text ); toSelect.options[toSelect_Length].value = fromSelect.options[index].value; fromSelect.options[index] = null; toSelect_Length++; } sortSelect( fromSelect ); sortSelect( toSelect ); } function compareTo( s ) { var len1 = this.length; var len2 = s.length; var n = ( len1 < len2 ? len1 : len2 ); for( i = 0 ; i < n ; i++ ) { var a = this.charCodeAt( i ); var b = s.charCodeAt( i ) if( a != b ) { return( a - b ); } } return( len1 - len2 ); } String.prototype.compareTo = compareTo; function sortSelect( select ) { var a = new Array(); for( i = 0; i < select.options.length ; i++ ) { a[a.length] = new Option( select.options[i].text, select.options[i].value, select.options[i].defaultSelected, select.options[i].selected ) ; } a = a.sort( function( s, t ) { return( s.text.compareTo( t.text ) ); } ); for( i = 0; i < a.length ; i++ ) { select.options[i] = new Option( a[i].text, a[i].value, a[i].defaultSelected, a[i].selected ); } } // --> </script> </head> <body> <center> <font size=6>JavaScript Professional Projects</font><br> <font size=4>Chapter 8: Working with Forms</font> </center> <br><br> <br><br> <form name="theForm"> <table cellspacing="6"> <tr> <td> <select size="12" name="ListA" multiple width="125"> <script language="JavaScript"> <!-- for( i = 0 ; i < months.length ; i++ ) { document.write( "<option>" + months[i] + "</option>" ); } sortSelect( document.theForm.ListA ); // --> </script> </select> </td> <td> <input type="button" value="=====>" onClick="JavaScript: swapSelects( document.theForm.ListA, document.theForm.ListB );"> <br><br> <input type="button" value="<=====" onClick="JavaScript: swapSelects( document.theForm.ListB, document.theForm.ListA );"> </td> <td> <select size="12" name="ListB" multiple width="125"></select> <script language="JavaScript"> <!-- if( navigator.appName != "Netscape" ) { document.theForm.ListA.style.width = 125; document.theForm.ListB.style.width = 125; } // --> </script> </td> </tr> </table> </form> </body> </html>
The insertOption() function inserts an additional option into a preexisting HTML select box and then sorts the contents of the select box. This function uses the sortSelect() function presented previously.
function insertOption( select, text ) { select.options[select.options.length] = new Option( text, text, false, false ); sortSelect( select ); } Here is an example of using the insertOption() and sortSelect() functions: <html> <head> <title> JavaScript Professional Projects - Dynamic Forms </title> <style type="text/css"> <!-- .sameSize{ width: 125; } --> </style> <script language="JavaScript"> <!-- function insertOption( select, text ) { select.options[select.options.length] = new Option( text, text, false, false ); sortSelect( select ); } function compareTo( s ) { var len1 = this.length; var len2 = s.length; var n = ( len1 < len2 ? len1 : len2 ); for( i = 0 ; i < n ; i++ ) { var a = this.toUpperCase().charCodeAt( i ); var b = s.toUpperCase().charCodeAt( i ) if( a != b ) { return( a - b ); } } return( len1 - len2 ); } String.prototype.compareTo = compareTo; function sortSelect( select ) { var a = new Array(); for( i = 0; i < select.options.length ; i++ ) { a[a.length] = new Option( select.options[i].text, select.options[i].value, select.options[i].defaultSelected, select.options[i].selected ) ; } a = a.sort( function( s, t ) { return( s.text.compareTo( t.text ) ); } ); for( i = 0; i < a.length ; i++ ) { select.options[i] = new Option( a[i].text, a[i].value, a[i].defaultSelected, a[i].selected ); } } // --> </script> </head> <body> <center> <font size=6>JavaScript Professional Projects</font><br> <font size=4>Chapter 8: Dynamic Foms</font> </center> <br><br> <br><br> <form name="theForm" onSubmit="return( false );"> <table cellpadding="3"> <tr> <td valign="bottom"> <input type="text" name="theText" size="20"> <input type="button" value="Insert" onClick="JavaScript: insertOption( document.theForm.theSelect, document.theForm.theText.value ); document.theForm.theText.value = '';"> </td> <td> <select size="10" name="theSelect" class="sameSize" width=125></select> </td> </tr> </table> </form> </body> </html>
The saveForm() function saves the entire content of a form to the cookie file so that it can be reloaded at a later time.
function saveForm( form ) { for( i = 0 ; i < form.elements.length ; i++ ) { with( form.elements[i] ) { if( type != "submit" && type != "button" && type != "reset" ) document.cookie = form.name + "." + name + "=" + value; } } }
The getCookieValue() function searches the cookie file for a name=value pair with the given name and returns the corresponding value.
function getCookieValue( name ) { var c = document.cookie; var begin = c.indexOf( name ); if( begin < 0 ) return( "" ); begin += name.length + 1; var end = c.indexOf( ";", begin ); if( end == -1 ) end = c.length; return( c.slice( begin, end ) ); }
The loadForm() function is the opposite of the saveForm() function; it loads the form data that was previously stored in the cookie file. This function uses the getCookieValue() function that was presented above.
function loadForm( form ) { for( i = 0 ; i < form.elements.length ; i++ ) { with( form.elements[i] ) { if( type != "submit" && type != "button" && type != "reset" ) value = getCookieValue( form.name + "." + name ); } } } Here is an example of using the saveForm(), loadForm() and getCookieValue() functions: <html> <head> <title> JavaScript Professional Projects - Reading Cookies </title> <script language="JavaScript"> <!-- var now = new Date(); now.setMonth( now.getMonth() + 1 ); document.cookie = "expires=" + now.toGMTString(); function saveForm( form ) { for( i = 0 ; i < form.elements.length ; i++ ) { with( form.elements[i] ) { if( type != "submit" && type != "button" && type != "reset" ) document.cookie = form.name + "." + name + "=" + value; } } } function loadForm( form ) { for( i = 0 ; i < form.elements.length ; i++ ) { with( form.elements[i] ) { if( type != "submit" && type != "button" && type != "reset" ) value = getCookieValue( form.name + "." + name ); } } } function getCookieValue( index ) { var c = document.cookie; var begin = c.indexOf( index + "=" ) + index.length + 1; var end = c.indexOf( ";", begin ); if( end == -1 ) end = c.length; return( c.slice( begin, end ) ); } --> </script> </head> <body onLoad="JavaScript: loadForm( document.mailingForm );"> <center> <font size=6>JavaScript Professional Projects</font><br> <font size=4>Chapter 11: Reading Cookies</font> </center> <br><br> <br><br> <table cellspacing="4" cellpadding="4" width="65%"> <tr> <td> <form name="mailingForm" onSubmit="JavaScript: saveForm( this );"> <b><font size="5">Mailing Address<br></font></b> <br> <b>Last name, First name:</b><br> <input type="text" name="firstLine" size="36"><br> <b>Street/Address:</b><br> <input type="text" name="secondLine" size="36"><br> <b>City State, Zip code:</b><br> <input type="text" name="thirdLine" size="36"> <input type="submit" value="Submit"> </form> </td> </tr> </table> </body> </html>