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>