1// NEW for 2025 | outputs weather widget in site header 2function displayWeatherWidget2025() { 3 4 // write the widget html to the screen 5 document.write('<div id="wxWidgetHeader" class="text-center">'); 6 document.write('<span class="text-white">'); 7 document.write('<img style="height: 30px;" id="wxWidgetImage2025" class="p-0" src="' + wxWidgetImageDefault + '" alt="weather" />'); 8 document.write(' '); 9 document.write('<span id="wxWidgetCurrentTemp2025" class="font-weight-bold"></span><br />'); 10 document.write('<small id="wxWidgetLocation2025"></small>'); 11 document.write('</span>'); 12 document.write('</div>'); 13 14} 15 16// outputs current conditions (alternative layout) 17function displayCurrentConditionsAlt() { 18 19 // simply write a div with an ID that will later be used to populate with HTML on the fly 20 document.write('<div id="wxFullForecastCC"></div>'); 21 22} 23 24// outputs trends (alternative layout) 25function displayTrendsAlt() { 26 27 // simply write a div with an ID that will later be used to populate with HTML on the fly
28 document.write('<div id="wxFullForecastT"></div>'); 29 30} 31 32// outputs hourly forecast (alternative layout) 33function displayHourlyForecastAlt() { 34 35 // simply write a div with an ID that will later be used to populate with HTML on the fly 36 document.write('<div id="wxFullForecastH"></div>'); 37 38} 39 40// outputs ten day (alternative layout) 41function displayTenDayAlt() { 42 43 // simply write a div with an ID that will later be used to populate with HTML on the fly 44 document.write('<div id="wxFullForecastTD"></div>'); 45 46} 47 48// reloads page, passing user-entered ZIP code 49function reloadWithUserZip() { 50 51 // get the value from the zip code field 52 userLocation = document.getElementById('newLocation').value; 53 54 // check to see if value looks like a valid zip 55 isValidZip = /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(userLocation); 56 57 // does it appear like a valid zip? 58 if(isValidZip) { 59 60 // get the base url (without any existing query string) 61 currentPage = location.protocol + '//' + location.host + location.pathname; 62 63 // generate the redirectPage value 64 redirectPage = currentPage + '?zip=' + encodeURIComponent(userLocation); 65 66 // do the redirect 67 window.location.href = redirectPage; 68 69 } else { 70 71 // alert the user 72 alert('That does not look like a valid ZIP code.'); 73 74 } 75 76} 77 78// gets weather data for a user's given location and populates divs with that data accordingly 79function loadUserWeatherData(theZip) { 80 81 // set up root redirect page just in case we hit any snags 82 currentPage = location.protocol + '//' + location.host + location.pathname; 83 84 // make sure a value was set on the theme level for the api key and client id 85 if ((wsiApiKey !== "") && (wsiClientID !== "")) { 86 87 // extract the date and month with leading zeros 88 rightNow = new Date(); 89 rightNowYear = rightNow.getFullYear(); 90 rightNowMonth = rightNow.getMonth(); 91 rightNowDay = rightNow.getDate(); 92 todayDateFormatted = rightNowMonth + '/' + rightNowDay + '/' + rightNowYear; 93 todayDate = new Date(rightNowYear, rightNowMonth, rightNowDay); 94 95 // values used for retrieving almanac data on current day 96 thisDay = ('0' + rightNow.getDate()).slice(-2); 97 thisMonth = (rightNow.getMonth() + 1); 98 thisMonth = ('0' + thisMonth).slice(-2); 99 100 // generate the url for the api call 101 wsiRequestUrl = 'https://api.weather.com/v3/aggcommon/v3-location-point;v3-wx-observations-current;v3-wx-forecast-daily-10day-custom;v3-wx-forecast-hourly-2day-custom;v3-wx-almanac-daily-1day?postalKey=' + theZip + ':US&day=' + thisDay + '&month=' + thisMonth + '&clientId=' + wsiClientID + '&language=en-US&units=e&format=json&apiKey=' + wsiApiKey; 102 103 // set up an ajax call to the generated url 104 jQuery.ajax({ 105 type : "get", 106 url : wsiRequestUrl, 107 success: function(response) { 108 109 // separate out the responses for easier parsing 110 wsi_location_point = response['v3-location-point']; 111 wsi_observations_current = response['v3-wx-observations-current']; 112 wsi_extended_forecast = response['v3-wx-forecast-daily-10day-custom']; 113 wsi_hourly_forecast = response['v3-wx-forecast-hourly-2day-custom']; 114 wsi_almanac = response['v3-wx-almanac-daily-1day']; 115 116 // make sure the value of wsi_location_point is a proper object 117 if (typeof wsi_location_point === 'object' && wsi_location_point !== null) { 118 119 // BEGIN | current conditions generation 120 121 // value is an object so it is safe to continue 122 useCity = wsi_location_point["location"]["city"]; 123 useState = wsi_location_point["location"]["adminDistrictCode"]; 124 useIcon = wsi_observations_current["iconCode"]; 125 useSky = wsi_observations_current["wxPhraseMedium"]; 126 127 if ((wsi_extended_forecast.temperatureMax[0] !== "") && (wsi_extended_forecast.temperatureMax[0] != null)) { 128 useHi = wsi_extended_forecast.temperatureMax[0] + '<sup>°</sup>'; 129 } else { 130 useHi = '-'; 131 } 132 133 useLo = wsi_extended_forecast.temperatureMin[0] + '<sup>°</sup>'; 134 useTemp = wsi_observations_current["temperature"]; 135 usePhrase = wsi_extended_forecast.narrative[0]; 136 137 // build the HTML that will be returned to the calling js 138 html = '<!-- ROW (current conditions) -->'; 139 html = html + '<div class="row mb-4">'; 140 html = html + '<div class="col-12 my-2"><h4>Current Conditions for ' + useCity + ', ' + useState + '</h4></div>'; 141 html = html + '<div class="col-12">'; 142 html = html + '<div class="row">'; 143 html = html + '<div class="col-6 text-center">'; 144 html = html + '<img class="media-object" src="' + wxIconDir + useIcon + '.png" width="60" height="60" alt="' + useSky + '" title="' + useSky + '" />'; 145 html = html + '<p class="h5">' + useHi + ' | ' + useLo + '</p>'; 146 html = html + '</div>'; 147 html = html + '<div class="col-6 text-center">'; 148 html = html + '<p class="h5">Currently:</p><h2 class="display-4">' + useTemp + '<sup>°</sup></h2>'; 149 html = html + '</div>'; 150 html = html + '<div class="col-12 text-center">'; 151 html = html + '<p>' + usePhrase + '</p>'; 152 html = html + '</div>'; 153 html = html + '</div>'; 154 html = html + '</div>'; 155 156 useFeelsLike = wsi_observations_current["temperatureFeelsLike"]; 157 useWindDir = wsi_observations_current["windDirectionCardinal"]; 158 useWindSpeed = wsi_observations_current["windSpeed"]; 159 useHumidity = wsi_observations_current["relativeHumidity"]; 160 useDewPt = wsi_observations_current["temperatureDewPoint"]; 161 usePressure = wsi_observations_current["pressureAltimeter"]; 162 163 html = html + '<div class="col-12 col-xl-6">'; 164 html = html + '<table style="width: 100%;">'; 165 html = html + '<tr class="bg-light">'; 166 html = html + '<td valign="top"><strong>Feels like: </strong></td>'; 167 html = html + '<td class="text-right">' + useFeelsLike + '<sup>°</sup></td>'; 168 html = html + '</tr>'; 169 html = html + '<tr>'; 170 html = html + '<td valign="top"><strong>Wind: </strong></td>'; 171 html = html + '<td class="text-right">' + useWindDir + ' ' + useWindSpeed + 'mph</td>'; 172 html = html + '</tr>'; 173 html = html + '<tr class="bg-light">'; 174 html = html + '<td valign="top"><strong>Humidity: </strong></td>'; 175 html = html + '<td class="text-right">' + useHumidity + '%</td>'; 176 html = html + '</tr>'; 177 html = html + '<tr>'; 178 html = html + '<td valign="top"><strong>Dewpoint: </strong></td>'; 179 html = html + '<td class="text-right">' + useDewPt + '<sup>°</sup></td>'; 180 html = html + '</tr>'; 181 html = html + '<tr class="bg-light">'; 182 html = html + '<td valign="top"><strong>Pressure: </strong></td>'; 183 html = html + '<td class="text-right">' + usePressure + '"</td>'; 184 html = html + '</tr>'; 185 html = html + '</table>'; 186 html = html + '</div>'; 187 188 useCeiling = wsi_observations_current["cloudCeiling"]; 189 useVisibility = wsi_observations_current["visibility"]; 190 191 // manipulate sunrise/sunset datetime values as needed 192 useSunriseDateTime = wsi_observations_current["sunriseTimeLocal"]; 193 theSunriseDateTime = useSunriseDateTime.split("T"); 194 theSunriseTime = theSunriseDateTime[1].split("-"); 195 theSunriseTime = theSunriseTime[0].split(":"); 196 useSunriseHour = parseInt(theSunriseTime[0], 10); 197 198 if (useSunriseHour == "0") { 199 useSunriseHour = "12"; 200 useSunriseAMPM = "AM"; 201 } else if (useSunriseHour == 12) { 202 useSunriseAMPM = "PM"; 203 } else if (useSunriseHour > 12) { 204 useSunriseHour = (useSunriseHour - 12); 205 useSunriseAMPM = "PM"; 206 } else { 207 useSunriseAMPM = "AM"; 208 } 209 210 useSunriseMinute = theSunriseTime[1]; 211 useSunriseSecond = theSunriseTime[2]; 212 213 useSunsetDateTime = wsi_observations_current["sunsetTimeLocal"]; 214 theSunsetDateTime = useSunsetDateTime.split("T"); 215 theSunsetTime = theSunsetDateTime[1].split("-"); 216 theSunsetTime = theSunsetTime[0].split(":"); 217 useSunsetHour = parseInt(theSunsetTime[0], 10); 218 219 if (useSunsetHour == "0") { 220 useSunsetHour = "12"; 221 useSunsetAMPM = "AM"; 222 } else if (useSunsetHour == 12) { 223 useSunsetAMPM = "PM"; 224 } else if (useSunsetHour > 12) { 225 useSunsetHour = (useSunsetHour - 12); 226 useSunsetAMPM = "PM"; 227 } else { 228 useSunsetAMPM = "AM"; 229 } 230 231 useSunsetMinute = theSunsetTime[1]; 232 useSunsetSecond = theSunsetTime[2]; 233 234 html = html + '<div class="col-12 col-xl-6">'; 235 html = html + '<table style="width: 100%;">'; 236 html = html + '<tr>'; 237 html = html + '<td valign="top"><strong>Sky: </strong></td>'; 238 html = html + '<td class="text-right">' + useSky + '</td>'; 239 html = html + '</tr>'; 240 html = html + '<tr class="bg-light">'; 241 html = html + '<td valign="top"><strong>Ceiling: </strong></td>'; 242 html = html + '<td class="text-right">' + useCeiling + '</td>'; 243 html = html + '</tr>'; 244 html = html + '<tr>'; 245 html = html + '<td valign="top"><strong>Visibility: </strong></td>'; 246 html = html + '<td class="text-right">' + useVisibility + 'mi</td>'; 247 html = html + '</tr>'; 248 html = html + '<tr class="bg-light">'; 249 html = html + '<td valign="top"><strong>Sunrise: </strong></td>'; 250 html = html + '<td class="text-right">' + useSunriseHour + ':' + useSunriseMinute + ':' + useSunriseSecond + ' ' + useSunriseAMPM + '</td>'; 251 html = html + '</tr>'; 252 html = html + '<tr class="bg-light">'; 253 html = html + '<td valign="top"><strong>Sunset: </strong></td>'; 254 html = html + '<td class="text-right">' + useSunsetHour + ':' + useSunsetMinute + ':' + useSunsetSecond + ' ' + useSunsetAMPM + '</td>'; 255 html = html + '</tr>'; 256 html = html + '</table>'; 257 html = html + '</div>'; 258 html = html + '<!-- /COL-12 -->'; 259 html = html + '</div>'; 260 html = html + '<!-- /ROW (current conditions) -->'; 261 262 html = html + '<!-- ROW (change location) -->'; 263 html = html + '<div class="row mb-4">'; 264 html = html + '<div class="col-12 my-2"><h4>Change Location</h4></div>'; 265 html = html + '<div class="col-12">'; 266 html = html + '<div class="input-group">'; 267 html = html + '<input name="newLocation" id="newLocation" type="text" class="form-control" placeholder="ZIP Code" aria-label="Search" aria-describedby="change" onFocus="this.value=\'\';">'; 268 html = html + '<div class="input-group-append">'; 269 html = html + '<button class="btn btn-dark" type="button" id="change" onClick="reloadWithUserZip();">Change</button>'; 270 html = html + '</div>'; 271 html = html + '</div>'; 272 html = html + '</div>'; 273 html = html + '<!-- /COL-12 -->'; 274 html = html + '</div>'; 275 html = html + '<!-- /ROW (change location) -->'; 276 277 // assign the value of html to htmlCC so we can reuse html for the other widget chunks 278 htmlCC = html; 279 280 // END | current conditions generation 281 282 // BEGIN | trends generation 283 284 // value is an object so it is safe to continue 285 useCity = wsi_location_point["location"]["city"]; 286 useState = wsi_location_point["location"]["adminDistrictCode"]; 287 288 html = '<!-- ROW (trends) -->'; 289 html = html + '<div class="row mb-4">'; 290 html = html + '<div class="col-12 my-2"><h4>Trends for ' + useCity + ', ' + useState + '</h4></div>'; 291 292 useAvgHi = wsi_almanac.temperatureAverageMax[0]; 293 useAvgLo = wsi_almanac.temperatureAverageMin[0]; 294 useMean = wsi_almanac.temperatureMean[0]; 295 296 html = html + '<div class="col-12 col-xl-6">'; 297 html = html + '<table style="width: 100%;">'; 298 html = html + '<tr class="bg-light">'; 299 html = html + '<td valign="top"><strong>Avg. High: </strong></td>'; 300 html = html + '<td class="text-right">' + useAvgHi + '<sup>°</sup></td>'; 301 html = html + '</tr>'; 302 html = html + '<tr>'; 303 html = html + '<td valign="top"><strong>Avg. Low: </strong></td>'; 304 html = html + '<td class="text-right">' + useAvgLo + '<sup>°</sup></td>'; 305 html = html + '</tr>'; 306 html = html + '<tr class="bg-light">'; 307 html = html + '<td valign="top"><strong>Mean: </strong></td>'; 308 html = html + '<td class="text-right">' + useMean + '<sup>°</sup></td>'; 309 html = html + '</tr>'; 310 html = html + '</table>'; 311 html = html + '</div>'; 312 313 useRecordHi = wsi_almanac.temperatureRecordMax[0]; 314 useRecordHiDate = wsi_almanac.almanacRecordYearMax[0]; 315 useRecordLo = wsi_almanac.temperatureRecordMin[0]; 316 useRecordLoDate = wsi_almanac.almanacRecordYearMin[0]; 317 318 html = html + '<div class="col-12 col-xl-6">'; 319 html = html + '<table style="width: 100%;">'; 320 html = html + '<tr>'; 321 html = html + '<td valign="top"><strong>Record High: </strong></td>'; 322 html = html + '<td class="text-right">'; 323 html = html + useRecordHi + '<sup>°</sup> (' + useRecordHiDate + ')'; 324 html = html + '</td>'; 325 html = html + '</tr>'; 326 html = html + '<tr class="bg-light">'; 327 html = html + '<td valign="top"><strong>Record Low: </strong></td>'; 328 html = html + '<td class="text-right">'; 329 html = html + useRecordLo + '<sup>°</sup> (' + useRecordLoDate + ')'; 330 html = html + '</td>'; 331 html = html + '</tr>'; 332 html = html + '</table>'; 333 html = html + '</div>'; 334 html = html + '<!-- /COL-12 -->'; 335 html = html + '</div>'; 336 html = html + '<!-- /ROW (trends) -->'; 337 338 // assign the value of html to htmlT so we can reuse html for the other widget chunks 339 htmlT = html; 340 341 // END | trends generation 342 343 // BEGIN | hourly generation 344 345 // value is an object so it is safe to continue 346 useCity = wsi_location_point["location"]["city"]; 347 useState = wsi_location_point["location"]["adminDistrictCode"]; 348 349 html = '<!-- ROW (hourly forecast) -->'; 350 html = html + '<div class="row mb-4">'; 351 html = html + '<div class="col-12 my-2"><h4>Hourly Forecast for ' + useCity + ', ' + useState + '</h4></div>'; 352 html = html + '<!-- COL-12 -->'; 353 html = html + '<div class="col-12">'; 354 html = html + '<div class="container weather-forecast-data">'; 355 356 // declare a variable that will be used to output a "day" header (today, tomorrow, friday) 357 newHourHeaderText = ''; 358 359 // loop through the hourly forecast values 360 for(var hour=0; hour <= 47; hour++) { 361 362 // manipulate date values as needed 363 useDateTimeLocal = wsi_hourly_forecast["validTimeLocal"][hour]; 364 theDateTimeLocal = useDateTimeLocal.split("T"); 365 theFormattedDate = theDateTimeLocal[0]; 366 theFormattedDateSplit = theFormattedDate.split("-"); 367 theFormattedDate = theFormattedDateSplit[1] + '/' + theFormattedDateSplit[2] + '/' + theFormattedDateSplit[0]; 368 theFormattedDate = new Date(theFormattedDate); 369 theDateInterval = Math.abs(theFormattedDate - todayDate); 370 theDateDiffDays = Math.ceil(theDateInterval / (1000 * 60 * 60 * 24)) 371 372 // determine how to show day based on value of theDateInterval 373 if (theDateInterval == 0) { 374 theDayToDisplay = 'Today'; 375 } else if (theDateDiffDays == 1) { 376 theDayToDisplay = 'Tomorrow'; 377 } else { 378 theDayToDisplay = wsi_hourly_forecast["dayOfWeek"][hour]; 379 } 380 381 // further manipulate time values as needed 382 theTimeLocal = theDateTimeLocal[1].split(":"); 383 theHourLocal = parseInt(theTimeLocal[0], 10); 384 385 if (theHourLocal == "0") { 386 theHourLocal = "12AM"; 387 } else if (theHourLocal == 12) { 388 theHourLocal = theHourLocal + "PM"; 389 } else if (theHourLocal > 12) { 390 theHourLocal = ((theHourLocal - 12) + "PM"); 391 } else { 392 theHourLocal = theHourLocal + "AM"; 393 } 394 395 // determine if hour is day or night 396 dayOrNight = wsi_hourly_forecast["dayOrNight"][hour]; 397 398 // pick out the data needed for display 399 useHourTemp = wsi_hourly_forecast["temperature"][hour] + '<sup>°</sup>'; 400 useHourIcon = wsi_hourly_forecast["iconCode"][hour]; 401 useHourSky = wsi_hourly_forecast["wxPhraseShort"][hour]; 402 useHourHumidity = wsi_hourly_forecast["relativeHumidity"][hour];
403 useHourPrecip = wsi_hourly_forecast["precipChance"][hour]; 404 useHourWindDir = wsi_hourly_forecast["windDirectionCardinal"][hour]; 405 useHourWindSpeed = wsi_hourly_forecast["windSpeed"][hour]; 406 407 // check to see if the current value of theDaytoDisplay is different than the current value of newHourHeaderText 408 if (newHourHeaderText != theDayToDisplay) { 409 410 // the values differ, so match first, match them up 411 newHourHeaderText = theDayToDisplay; 412 413 // begin the new header row 414 html = html + '<div class="row pr-2">'; 415 html = html + '<div class="col-12">'; 416 html = html + '<span class="forecastHourlyTime"><br />' + newHourHeaderText + '</span>'; 417 html = html + '</div>'; 418 419 // end the header row 420 html = html + '</div>'; 421 422 } 423 424 // begin a new data row 425 html = html + '<div class="row pr-2">'; 426 427 // check if "hour" is odd or even and modify a CSS value accordingly 428 if(hour % 2 == 0){ 429 dayOrNightCSS = ''; 430 } else { 431 dayOrNightCSS = 'weather-forecast-data-night-alt'; 432 } 433 434 // generate the data columns 435 html = html + '<div class="col-2 pt-1 ' + dayOrNightCSS + '">'; 436 html = html + '<span class="forecastHourlyDay">' + theHourLocal + '</span><br />'; 437 html = html + '</div>'; 438 html = html + '<div class="col-2 pt-1 ' + dayOrNightCSS + '">'; 439 html = html + '<span class="forecastHourlyDay">' + useHourTemp + '</span><br />'; 440 html = html + '</div>'; 441 html = html + '<div class="col-2 ' + dayOrNightCSS + '">'; 442 html = html + '<img class="media-object" style="padding-top: 5px; width: 100%; max-width: 60px;" src="' + wxIconDir + + useHourIcon + '.png" alt="' + useHourSky + '" title="' + useHourSky + '" /><br />'; 443 html = html + '</div>'; 444 html = html + '<div class="col-6 ' + dayOrNightCSS + '">'; 445 html = html + '<span class="forecastHourlyDay forecastDeets">'; 446 html = html + useHourSky + ' | '; 447 html = html + 'Humidity: ' + useHourHumidity + '% | '; 448 html = html + 'Precip: ' + useHourPrecip + '% | '; 449 html = html + 'Wind: ' + useHourWindDir + ' ' + useHourWindSpeed + 'mph'; 450 html = html + '</span>'; 451 html = html + '</div>'; 452 453 // end the data row 454 html = html + '</div>'; 455 456 // check to see if this is the fourth hour displayed 457 if (hour == 3) { 458 459 // after the fourth hour of data we want to display a button to allow show/hide of rest of data 460 html = html + '<div class="row pr-2">'; 461 462 // determine whether to stylize for day or night 463 if (dayOrNight == 'D') { 464 html = html + '<div class="col-12">'; 465 } else { 466 html = html + '<div class="col-12 weather-forecast-data-night-alt">'; 467 } 468 469 html = html + '<button class="btn btn-dark btn-block my-3" type="button" id="showHideHourly" data-toggle="collapse" data-target="#collapseHourly" aria-expanded="false" aria-controls="collapseHourly">Show/Hide Full 48-Hour Forecast</button>'; 470 html = html + '</div>'; 471 html = html + '</div>'; 472 473 // open the div for the collapsible part of the data 474 html = html + '<div class="collapse" id="collapseHourly">'; 475 476 } 477 478 } 479 480 html = html + '</div>'; 481 html = html + '</div>'; 482 html = html + '</div>'; 483 html = html + '</div>'; 484 html = html + '<!-- /COL-12 -->'; 485 html = html + '</div>'; 486 html = html + '<!-- /ROW (hourly forecast) -->'; 487 488 // assign the value of html to htmlH so we can reuse html for the other widget chunks 489 htmlH = html; 490 491 // END | hourly generation 492 493 // BEGIN | ten day generation 494 495 // set up month names in an array for later use 496 const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
496November", "December"]; 497 498 // value is an object so it is safe to continue 499 useCity = wsi_location_point["location"]["city"]; 500 useState = wsi_location_point["location"]["adminDistrictCode"]; 501 502 html = '<!-- ROW (extended forecast) -->'; 503 html = html + '<div class="row mb-4">'; 504 html = html + '<div class="col-12 my-2"><h4>Extended Forecast for ' + useCity + ', ' + useState + '</h4></div>'; 505 html = html + '<!-- COL-12 -->'; 506 html = html + '<div class="col-12">'; 507 html = html + '<div class="container weather-forecast-data">'; 508 509 // loop through all 10 returned days of data 510 for (var day=0; day <= 9; day++) { 511 512 // calculate the daypart index value for day and night for each time through the loop 513 dayPartDay = (day * 2); 514 dayPartNight = (dayPartDay + 1); 515 516 // manipulate date values as needed 517 useDateTimeLocal = wsi_extended_forecast["validTimeLocal"][day]; 518 theDateTimeLocal = useDateTimeLocal.split("T"); 519 theFormattedDate = theDateTimeLocal[0]; 520 theFormattedDateSplit = theFormattedDate.split("-"); 521 theFormattedDate = theFormattedDateSplit[1] + '/' + theFormattedDateSplit[2] + '/' + theFormattedDateSplit[0]; 522 theFormattedDate = new Date(theFormattedDate); 523 524 // pick out the data needed for display 525 useDayIcon = wsi_extended_forecast.daypart[0]["iconCode"][dayPartDay]; 526 useDayPhrase = wsi_extended_forecast.daypart[0]["wxPhraseShort"][dayPartDay]; 527 useDayHumidity = wsi_extended_forecast.daypart[0]["relativeHumidity"][dayPartDay]; 528 useDayPrecip = wsi_extended_forecast.daypart[0]["precipChance"][dayPartDay]; 529 useDayWindDir = wsi_extended_forecast.daypart[0]["windDirectionCardinal"][dayPartDay]; 530 useDayWindSpeed = wsi_extended_forecast.daypart[0]["windSpeed"][dayPartDay]; 531 532 useNightIcon = wsi_extended_forecast.daypart[0]["iconCode"][dayPartNight]; 533 useNightPhrase = wsi_extended_forecast.daypart[0]["wxPhraseShort"][dayPartNight]; 534 useNightHumidity = wsi_extended_forecast.daypart[0]["relativeHumidity"][dayPartNight]; 535 useNightPrecip = wsi_extended_forecast.daypart[0]["precipChance"][dayPartNight]; 536 useNightWindDir = wsi_extended_forecast.daypart[0]["windDirectionCardinal"][dayPartNight]; 537 useNightWindSpeed = wsi_extended_forecast.daypart[0]["windSpeed"][dayPartNight]; 538 539 useDayHi = wsi_extended_forecast.daypart[0]["temperature"][dayPartDay] + '<sup>°</sup>'; 540 useDayLo = wsi_extended_forecast.daypart[0]["temperature"][dayPartNight] + '<sup>°</sup>'; 541 useDaypartNameDay = wsi_extended_forecast.daypart[0]["daypartName"][dayPartDay]; 542 useDaypartNameNight = wsi_extended_forecast.daypart[0]["daypartName"][dayPartNight]; 543 544 // add a header row 545 html = html + '<div class="row pr-2">'; 546 html = html + '<div class="col-12 pt-3">'; 547 548 // check to see if useDaypartNameDay is either "today" or "tomorrow" 549 if ((useDaypartNameDay == 'Today') || (useDaypartNameDay == 'Tomorrow')) { 550 551 // just output "today" or "tomorrow" 552 html = html + '<span class="forecastHourlyTime">' + useDaypartNameDay + '</span>'; 553 554 } else if (useDaypartNameDay == null) { 555 556 // just output "today" or "tomorrow" 557 html = html + '<span class="forecastHourlyTime">Today</span>'; 558 559 } else { 560 561 // only include date if not today or tomorrow 562 html = html + '<span class="forecastHourlyTime">' + useDaypartNameDay + ', ' + monthNames[theFormattedDate.getMonth()] + ' ' + theFormattedDate.getDate() + '</span>'; 563 564 } 565 566 html = html + '</div>'; 567 568 // end the header row 569 html = html + '</div>'; 570 571 // only display daytime day part if it hasn't yet become old 572 if (((wsi_extended_forecast.temperatureMax[0] !== "") && (wsi_extended_forecast.temperatureMax[0] != null)) || (dayPartDay > 0)) { 573 574 // begin a new data row 575 html = html + '<div class="row pr-2">'; 576 html = html + '<div class="col-2 pt-1">'; 577 html = html + '<span class="forecastHourlyDay">Day</span><br />'; 578 html = html + '</div>'; 579 html = html + '<div class="col-2 pt-1">'; 580 html = html + '<span class="forecastHourlyDay">' + useDayHi + '</span><br />'; 581 html = html + '</div>'; 582 html = html + '<div class="col-2">'; 583 html = html + '<img class="media-object" style="padding-top: 5px; width: 100%; max-width: 60px;" src="' + wxIconDir + + useDayIcon + '.png" alt="' + useDayPhrase + '" title="' + useDayPhrase + '" /><br />'; 584 html = html + '</div>'; 585 html = html + '<div class="col-6">'; 586 html = html + '<span class="forecastHourlyDay forecastDeets">'; 587 html = html + useDayPhrase + ' | '; 588 html = html + 'Humidity: ' + useDayHumidity + '% | '; 589 html = html + 'Precip: ' + useDayPrecip + '% | '; 590 html = html + 'Wind: ' + useDayWindDir + ' ' + useDayWindSpeed + 'mph'; 591 html = html + '</span>'; 592 html = html + '</div>'; 593 594 // end the data row 595 html = html + '</div>'; 596 597 } 598 599 // begin a new data row 600 html = html + '<div class="row pr-2">'; 601 html = html + '<div class="col-2 pt-1 weather-forecast-data-night-alt">'; 602 html = html + '<span class="forecastHourlyDay">Night</span><br />'; 603 html = html + '</div>'; 604 html = html + '<div class="col-2 pt-1 weather-forecast-data-night-alt">'; 605 html = html + '<span class="forecastHourlyDay">' + useDayLo + '</span><br />'; 606 html = html + '</div>'; 607 html = html + '<div class="col-2 weather-forecast-data-night-alt">'; 608 html = html + '<img class="media-object" style="padding-top: 5px; width: 100%; max-width: 60px;" src="' + wxIconDir + + useNightIcon + '.png" alt="' + useNightPhrase + '" title="' + useNightPhrase + '" /><br />'; 609 html = html + '</div>'; 610 html = html + '<div class="col-6 weather-forecast-data-night-alt">'; 611 html = html + '<span class="forecastHourlyDay forecastDeets">'; 612 html = html + useNightPhrase + ' | '; 613 html = html + 'Humidity: ' + useNightHumidity + '% | '; 614 html = html + 'Precip: ' + useNightPrecip + '% | '; 615 html = html + 'Wind: ' + useNightWindDir + ' ' + useNightWindSpeed + 'mph'; 616 html = html + '</span>'; 617 html = html + '</div>'; 618 619 // end the data row 620 html = html + '</div>'; 621 622 // check to see if this is the second day displayed 623 if (day == 1) { 624 625 // after the second day of data we want to display a button to allow show/hide of rest of data 626 html = html + '<div class="row pr-2">'; 627 html = html + '<div class="col-12">'; 628 html = html + '<button class="btn btn-dark btn-block my-3" type="button" id="showHideDaily" data-toggle="collapse" data-target="#collapseDaily" aria-expanded="false" aria-controls="collapseDaily">Show/Hide Full Extended Forecast</button>'; 629 html = html + '</div>'; 630 html = html + '</div>'; 631 632 // open the div for the collapsible part of the data 633 html = html + '<div class="collapse" id="collapseDaily">'; 634 635 } 636 637 } 638 639 html = html + '</div>'; 640 html = html + '</div>'; 641 html = html + '</div>'; 642 html = html + '</div>'; 643 html = html + '<!-- /COL-12 -->'; 644 html = html + '</div>'; 645 html = html + '<!-- /ROW (extended forecast) -->'; 646 647 // assign the value of html to htmlTD so we can reuse html for the other widget chunks 648 htmlTD = html; 649 650 // END | ten day generation 651 652 // only attempt to rewrite the current conditions div if it exists on the page 653 if (document.getElementById('wxFullForecastCC')) { 654 jQuery("#wxFullForecastCC").html(htmlCC); 655 } 656 657 // only attempt to rewrite the trends div if it exists on the page 658 if (document.getElementById('wxFullForecastT')) { 659 jQuery("#wxFullForecastT").html(htmlT); 660 } 661 662 // only attempt to rewrite the hourly div if it exists on the page 663 if (document.getElementById('wxFullForecastH')) { 664 jQuery("#wxFullForecastH").html(htmlH); 665 } 666 667 // only attempt to rewrite the ten day div if it exists on the page 668 if (document.getElementById('wxFullForecastTD')) { 669 jQuery("#wxFullForecastTD").html(htmlTD); 670 } 671 672 } else { 673 674 // the ZIP code does not appear valid, so alert the user 675 alert('Not a valid ZIP code. Displaying default.'); 676 677 // do the redirect 678 window.location.href = currentPage; 679 680 } 681 682 }, 683 error: function(xhr) { 684 alert('An unknown error has occurred...'); 685 } 686 }); 687 688 } else { 689 690 // do the redirect 691 window.location.href = currentPage; 692 693 } 694 695}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.