1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Array Example 4</title> 6 7 <!-- 8 File: \\cssd.local\Student Resources\Website Development I\CodeSamples\ArrayExample_4.html 9 Copyright (c) 2022 by Jesse Heines. All rights reserved. May be freely 10 copied or excerpted for educational purposes with credit to the author. 11 updated by JMH on June 6, 2022 at 10:27 AM 12 --> 13 14 <script> 15 //// CODE TO INITIALIZE THE ARRAY OF DATE WE WANT TO WORK WITH 16 17 /* This statement declares variable arrCSSD to be an array. It will actually be a 18 two-dimensional (2D) array by the time we finish populating it with data. A 2D 19 array is equivalent to a table with rows and column. Each top level element of 20 the array represents a row, and the data in the secondary array represents the 21 columns. */ 22 var arrCSSD = new Array() ; 23 /* The statements that follow "push" onto the array, which means they add data at the 24 end. Each statement pushes an entire subarray onto the top level array, resulting 25 in a data structure with the 4 "columns". These columns, in order, are: 26 | Room # | Instructor Name | Course Name | Time Slot | 27 where "Day Period" is "A" for 7:10-8:30, "B" for 8:40=10:00, "C" for 10:10-11:30, 28 "D" for 11:40-1:00, and "E" for 1:10-2:30. */ 29 arrCSSD.push( [ 1, "Lees", "Economics", "A" ] ) ; 30 arrCSSD.push( [ 1, "Lees", "Geography", "B" ] ) ; 31 arrCSSD.push( [ 2, "Burzycki", "Biology IA", "D" ] ) ; 32 arrCSSD.push( [ 2, "Burzycki", "Biology IB", "E" ] ) ; 33 arrCSSD.push( [ 3, "Latorella", "World Literature IA", "A" ] ) ; 34 arrCSSD.push( [ 3, "Latorella", "Special Units", "B" ] ) ; 35 arrCSSD.push( [ 3, "Latorella", "American Literature IA", "D" ] ) ; 36 arrCSSD.push( [ 3, "Latorella", "Tolkien", "E" ] ) ; 37 arrCSSD.push( [ 4, "Jones", "CDL Prep.", "B" ] ) ; 38 arrCSSD.push( [ 4, "Jones", "CDL Prep.", "D" ] ) ; 39 arrCSSD.push( [ 6, "Mosher", "Algebra IA", "A" ] ) ; 40 arrCSSD.push( [ 6, "Mosher", "Computation for Business", "B" ] ) ; 41 arrCSSD.push( [ 7, "Piper", "Short Story", "D" ] ) ; 42 arrCSSD.push( [ 7, "Piper", "Mythology", "E" ] ) ; 43 arrCSSD.push( [ 8, "Kroll", "Purchasing", "D" ] ) ; 44 arrCSSD.push( [ 8, "Kroll", "Nutrition for Culinary", "E" ] ) ; 45 arrCSSD.push( [ 10, "Spires", "Small Business Management", "A" ] ) ; 46 arrCSSD.push( [ 10, "Spires", "Advanced Microsoft Applications", "D" ] ) ; 47 arrCSSD.push( [ 10, "Spires", "Career Awareness", "E" ] ) ; 48 49 50 //// FUNCTIONS TO DISPLAY THE DATA TABLE 51 52 // This is a "helper" function that returns the time slot given its letter identifier. 53 // Note that the string returned is actually a table itself that goes inside the last 54 // column of the master table. 55 var TimeSlot = function( strLetterID ) { 56 var strReturn = "<table id='timeslot' cellpadding='0' cellspacing='0'><tr><td>" ; 57 switch ( strLetterID ) { 58 case "A" : strReturn += "7:10 AM</td><td> – </td><td>8:30 AM" ; break ; 59 case "B" : strReturn += "8:40 AM</td><td> – </td><td> 10:00 AM" ; break ; 60 case "C" : strReturn += "10:10 AM</td><td> – </td><td> 11:30 AM" ; break ; 61 case "D" : strReturn += "11:40 AM</td><td> – </td><td> 1:00 PM" ; break ; 62 case "E" : strReturn += "1:10 PM</td><td> – </td><td> 2:30 PM" ; break ; 63 } 64 strReturn += "</td></tr></table>" ; 65 // the following statement was used for debugging 66 // console.log( strReturn ) ; 67 return strReturn ; 68 } 69 70 // This function displays the table in whatever order it is currently sorted. 71 var DisplayTable = function( nSortColumn ) { 72 // Loop through the entire array, displaying the subarray in each top-level element 73 // in a separate row. 74 for ( var k = 0 ; k < arrCSSD.length ; k++ ) { 75 document.writeln( "<tr>" ) ; 76 document.writeln( " <td>" + arrCSSD[k][0] + "</td>" ) ; 77 document.writeln( " <td>" + arrCSSD[k][1] + "</td>" ) ; 78 document.writeln( " <td>" + arrCSSD[k][2] + "</td>" ) ; 79 document.writeln( " <td>" + TimeSlot( arrCSSD[k][3] ) + "</td>" ) ; 80 document.writeln( "</tr>" ) ; 81 } 82 83 // Highlight the header cell of the column on which the data is sorted. 84 // Be careful! The getElementsByTagName function returns a *collection*, which is 85 // similar to, but not quite the same as an *array*! 86 var colHeaderCells = document.getElementsByTagName("th") ; 87 colHeaderCells[nSortColumn-1].setAttribute( 88 "style", "background-color: lightgreen ; color: black" ) ; 89 } 90 91 92 //// FUNCTIONS TO SORT THE TABLE DATA ON THE DESIRED COLUMN 93 94 // Note: The following 4 functions could be combined into a single function with some 95 // additional programming, but I have left them as separate functions for clarity. We 96 // could also write additional functions which sort the specified columns in descending 97 // order. 98 99 // This function compares the first (0th) items in the subarrays, which are the 100 // ROOM NUMBERS. It returns -1 if the 1st item should come before the 2nd. +1 if the 101 // 1st item should come after the 2nd, 0 if their current order is OK. 102 var fnRoomAscending = function( a, b ) { 103 if ( a[0] < b[0] ) { 104 return -1 ; 105 } else if ( a[0] > b[0] ) { 106 return +1 ; 107 } else { 108 return 0 ; 109 } 110 } 111 112 // This function compares the second (index 1) items in the subarrays, which are the 113 // INSTRUCTOR NAMES. It returns -1 if the 1st item should come before the 2nd. +1 if 114 // the 1st item should come after the 2nd, 0 if their current order is OK. 115 var fnNameAscending = function( a, b ) { 116 if ( a[1] < b[1] ) { 117 return -1 ; 118 } else if ( a[1] > b[1] ) { 119 return +1 ; 120 } else { 121 return 0 ; 122 } 123 } 124 125 // This function compares the third (index 2) items in the subarrays, which are the 126 // COURSE NAMES. It returns -1 if the 1st item should come before the 2nd. +1 if the 127 // 1st item should come after the 2nd, 0 if their current order is OK. 128 var fnCourseAscending = function( a, b ) { 129 if ( a[2] < b[2] ) { 130 return -1 ; 131 } else if ( a[2] > b[2] ) { 132 return +1 ; 133 } else { 134 return 0 ; 135 } 136 } 137 138 // This function compares the fourth (index 3) items in the subarrays, which are the 139 // TIME SLOTS. Remember that the time slots are encoded as "A", "B", "C", "D", or "E". 140 // Just like the other functions, this one also returns -1 if the 1st item should come 141 // before the 2nd. +1 if the 1st item should come after the 2nd, 0 if their current 142 // order is OK. 143 var fnTimeAscending = function( a, b ) { 144 if ( a[3] < b[3] ) { 145 return -1 ; 146 } else if ( a[3] > b[3] ) { 147 return +1 ; 148 } else { 149 return 0 ; 150 } 151 } 152 153 154 //// FUNCTION TO RELOAD THE PAGE WITH A SPECIFIED SORT COLUMN 155 156 // This function is executed when the user clicks on a column header cell. The 157 // parameter passed to this function is the number of the column on which we wish to 158 // sort the table. 159 var ReloadPage = function( nSortColumn ) { 160 // The following statement returns: 161 // "/StudentResources/CodeSamples/ArrayExample_4.html" 162 var strThisPagePath = window.location.pathname ; 163 164 // To this we want to add a query parameter, which is part of a query string. 165 // The question mark begins the query string part of a URL. 166 // Each parameter is then written in name=value format. 167 // Thus, what we want is the page path returned by the above statement, then a 168 // question mark, then the query parameter name ("SortColumn") followed by an 169 // equals sign (=) and finally followed by the parameter value, which in our 170 // current case is the number of the desired sort column passed to this function. 171 var strFullPagePath = strThisPagePath + "?SortColumn=" + nSortColumn ; 172 173 // The final step is to replace the current page with the full path that we just 174 // constructed. In our case, this is the same page that we are currently viewing, 175 // but with a parameter specifying the desired sort column. 176 window.location.replace( strFullPagePath ) ; 177 } 178 179 //// CODE TO SET THE DESIRED SORT COLUMN 180 181 // nSortColumn is the number of the column by which the data will be sorted. The 182 // default is 1, but this can be changed by clicking on a different column header cell. 183 var nSortColumn = 1 ; 184 185 // The following code determines whether a query (search) string has been supplied 186 // and, if so, whether that query string contains a SortColumn parameter and a legal 187 // value (1-4). If it does, the value of the SortColumn parameter replaces the 188 // nSortColumn value so that the table data is sorted as the user desires. 189 // Note that for simplicity, the following code does not contain a lot of error 190 // checking. In a real application you have to have a lot of error checking whenever 191 // you get input from the user to ensure that the data he or she enters is valid. In 192 // many of the production quality programs that I have written personally, the amount 193 // of error-checking code EXCEEDS the amount of processing code! 194 // The following code could also be made more efficient, but I have written it our 195 // step-by-step for clarity. 196 197 // (1) get the query (search) string, which starts with a question mark (?) 198 var strSearchString = window.location.search ; 199 if ( strSearchString != "" && strSearchString.startsWith( "?SortColumn" ) ) { 200 // (2) split the search string on the equals sign (=), which returns an array 201 arrSearchString = strSearchString.split( "=" ) ; 202 // (3) the value we want is the 2nd (index 1) element of the array 203 strSortColumn = arrSearchString[1] ; 204 // (4) CRITICAL! Note that values extracted from query strings are ALWAYS STRINGS, 205 // not numbers. For use in our program we must therefore convert string variable 206 // strSortColumn to a number (variable nSortColumn) using the built-in eval function. 207 nSortColumn = eval( strSortColumn ) ; 208 } 209 </script> 210 211 <style> 212 h2#title { /* main page title */ 213 color: blue ; 214 margin-bottom: 0.2em ; 215 } 216 h3#semester { /* page subtitle (semester dates) */ 217 color: blue ; 218 margin-top: 0 ; 219 } 220 table#master tr th { /* formatting for the table header row */ 221 background-color: black ; 222 color: white ; 223 } 224 table#master tr th:hover { /* formatting change when a header cell is moused over */ 225 background-color: yellow ; 226 color: black ; 227 } 228 /* Note that the nth-child pseudo-selector's argument begins at 1, not 0. (Sigh.) */ 229 table#master tr td:nth-child(1) { /* formatting for column 1 */ 230 text-align: center ; 231 } 232 table#master tr td:nth-child(4) { /* formatting for column 4 */ 233 text-align: right ; 234 } 235 table#timeslot tr td:nth-child(1), /* formatting for the Time Slot subtable */ 236 table#timeslot tr td:nth-child(3) { /* that is the data in column 4 */ 237 width: 4.09em ; 238 text-align: right ; 239 } 240 </style> 241 242 </head> 243 244 <body> 245 <!-- display the page title and semester dates --> 246 <h2 id="title">Corrections Special School District</h2> 247 <h3 id="semester">Semester: April 4 to June 17, 2022</h3> 248 249 <script> 250 // The following code displays a message stating how the data is sorted. 251 // Note the use of document.write instead of document.writeln to prevent extra spaces 252 // from being added where not desired, such as before the period. 253 // -- document.writeln outputs text followed by a carriage return, which the browser 254 // displays as a space. 255 // -- document.write outputs text without a carriage return. 256 document.write( "<p>This is option " + nSortColumn + ", in which the data is " + 257 "ordered by: <strong style='background-color: lightgreen'> " ) ; 258 switch ( nSortColumn ) { 259 case 1 : // sorted on the Room Number 260 document.write( "Room Number" ) ; break ; 261 case 2 : // sorted on the Instructor Name 262 document.write( "Instructor Name" ) ; break ; 263 case 3 : // sorted on the Course name 264 document.write( "Course Name" ) ; break ; 265 case 4 : // sorted on the Time Slot 266 document.write( "Time Slot" ) ; break ; 267 } 268 document.writeln( " </strong></p>" ) ; 269 </script> 270 271 <!-- This is the table of room numbers, instructor names, course names, and time slots. --> 272 <table id="master" cellpadding="5" cellspacing="0" border="1"> 273 <tr> 274 <!-- 275 Note that each table header cell has an onclick parameter. The value of this 276 parameter is the name of a function that will be called when that table cell is 277 clicked. To that function we pass the number of the column by which we want the 278 table data to be sorted. 279 --> 280 <th onclick="ReloadPage( 1 )">Room #</th> 281 <th onclick="ReloadPage( 2 )">Instructor</th> 282 <th onclick="ReloadPage( 3 )">Course</th> 283 <th onclick="ReloadPage( 4 )">Time Slot</th> 284 </tr> 285 286 <script> 287 // Before displaying the table, we sort the array on the desired column using the 288 // appropriate comparison function. 289 switch ( nSortColumn ) { 290 case 1 : // sort by Room # 291 arrCSSD.sort( fnRoomAscending ) ; break ; 292 case 2 : // sort by Instructor Name 293 arrCSSD.sort( fnNameAscending ) ; break ; 294 case 3 : // sort by Course Name 295 arrCSSD.sort( fnCourseAscending ) ; break ; 296 case 4 : // sort by Time Slot 297 arrCSSD.sort( fnTimeAscending ) ; break ; 298 } 299 300 // We are now finally ready to display the table! :) 301 DisplayTable( nSortColumn ) ; 302 </script> 303 </table> 304 </body> 305 306 </html>