1 2 3<!DOCTYPE html> 4<html> 5<head> 6 <!-- CCU 03/2006 meta tags settings start --> 7 <title>CincyTicket</title> 8 <meta name="description" content="Visit CincyTicket.com to get tickets for the hottest events in Cincinnati, OH and the surrounding area."> 9 <meta name="keywords" content="CincyTicket, tickets,Buy Tickets, events, performances, shows, online ticketing"> 10 <meta name="author" content="CincyTicket"> 11 <meta name="abstract" content="Buy tickets and see performance listings from CincyTicket"> 12 <meta name="robots" content="INDEX, FOLLOW"> 13 14 <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.8, minimum-scale=1.0' name='viewport' /> 15 <meta name="google-translate-customization" content="9aaf36daf6e43103-a12f76fcd2014ac8-g804c3b886a9cdf60-11"></meta> 16 17 <meta name="fragment" content="!"> 18 19 <link rel="stylesheet" type="text/css" href="//www.cincyticket.com/include/structure.css?ver=20228"> 20 <link rel="stylesheet" type="text/css" href="//www.cincyticket.com/include/style.css?ver=20228"> 21 <link rel='stylesheet' content='text/css' href='/include/jqueryui-themes/default/jquery-ui.css' /> 22 23 <link rel="stylesheet" type="text/css" media="only screen and (max-width: 1024px)" href="//www.cincyticket.com/include/mobile.css?ver=20228"> 24 25
25<script type="text/javascript" src="//www.cincyticket.com/include/javascript.js?ver=20228"></script>
25 26
26<script type="text/javascript" src="//www.cincyticket.com/include/jq.js"></script>
26 27 28
28<script type='text/javascript' src='/include/jquery-3.5.1.min.js'></script>
28<script type='text/javascript' src='/include/jqueryui-themes/jquery-ui.min.js'></script>
28 29
29<script type="text/javascript" src="//www.cincyticket.com/include/mobile.js"></script>
29 30
31<script type="text/javascript"> 32 if (!navigator.cookieEnabled) { 33 alert("Your browser settings are currently configured to not allow cookies. Please enable cookies and try again."); 34 window.stop(); 35 document.execCommand("Stop"); //works in IE, 36 } 37</script>
37 38 39 40
41<script type="text/javascript" src="//www.cincyticket.com/include/swApi.js"></script>
vendor: 2 bytes, line 41
41
42<script type="text/javascript" src="//www.cincyticket.com/include/swApiPublic.js"></script>
vendor: 2 bytes, line 42
42
43<script type="text/javascript"> 44 45var window = window || {}; 46var Showare = Showare || {}; 47var document = document || undefined; 48 49Showare.Logger = { 50 Settings: { 51 ShouldLogInDev: true 52 }, 53 data: null, 54 env: {} 55} 56 57window.onerror = function(msg, url, lineNo, _, error) { 58 var envInfo = Showare.Logger._getEnvironmentDetails(); 59 60 var message = { 61 Description: msg, 62 SourceFile: url, 63 SourceLine: lineNo, 64 Referer: envInfo.referer, 65 QueryString: envInfo.querystring, 66 ErrorType: Showare.Logger.Settings.ErrorType, 67 Website: envInfo.website, 68 ShouldLogInDev: Showare.Logger.Settings.ShouldLogInDev, 69 Browser: envInfo.browser, 70 IPAddress: envInfo.ipaddress 71 }; 72 73 if (error != undefined) { 74 message.Exception = error.stack; 75 } 76 77 if (Showare.Logger.data) { 78 message.StateVariables = JSON.stringify(Showare.Logger.data); 79 } 80 81 swApiPublic.sendRequest("POST", "/v1/errorlog/", message); 82 Showare.Logger.data = null; 83 return false; 84 85 function shouldfilterError() { 86 return !( 87 // This error gets thrown by third party includes, to see full error, we need 88 // to do https://blog.sentry.io/2016/05/17/what-is-script-error.html 89 (msg.search("\s*Script error.*") == -1) && 90 // Related to iOS issue: https://github.com/getsentry/raven-js/issues/756 91 (msg.search(".*evaluating 'elt.parentNode'.*") == -1)) 92 } 93}; 94 95Showare.Logger.log = function(exception, data) { 96 Showare.Logger.data = data; 97 98 if (Object.prototype.toString.call(exception) == "[object Error]") { 99 if (exception.stack) { 100 var ex = exception.stack.split('\n'); 101 // Parse exceptions in the format of 102 // ' at src (javascript.js?ver=20228:510)' 103 var data = ex[1].match(/.+\((.+):(\d+):(\d+)\)/); 104 // and 105 // ' at src javascript.js?ver=20228:510' 106 if (!data) { 107 data = ex[1].match(/.+\s(.+):(\d+):(\d+)/); 108 } 109 window.onerror(ex[0], data[1], data[2], '', exception); 110 } else { 111 window.onerror(exception.name + ": " + exception.message, '', ''); 112 } 113 } else { 114 window.onerror(exception, '', ''); 115 } 116}; 117 118Showare.Logger.warn = function(msg, data) { 119 var logDetails = { 120 environment: Showare.Logger._getEnvironmentDetails(), 121 message: msg, 122 data: data 123 } 124 125 swApiPublic.sendRequest("POST", "/v1/errorlog/warn", logDetails); 126 return; 127}; 128 129Showare.Logger._getEnvironmentDetails = function() { 130 Showare.Logger.Settings.ErrorType = 'Javascript'; 131 return { 132 browser: "Mozilla/5.0 AppleWebKit/537.36 KHTML, like Gecko compatible PageSourceSearchBot/1.0 https//pagesourcesearch.com/bot Chrome/128.0.0.0 Safari/537.36", 133 ipaddress: "181.215.65.76", 134 querystring: window.location.href, 135 referer: "", 136 website: "www.cincyticket.com", 137 basketid: "6kLTVUS0FTQzgzMTEwMTgCMDI2MD0yOyIwNTExNTkSMjEuOD0xO1c2LjY1LjEUV0dCVkRCLJ____oQVR" 138 } 139} 140 141</script>
141<script type="text/javascript"> 142//---------------------------DATEPICKER--------------------------------- 143function buildDatepicker(options) { 144 //Calling this function should be sufficient to create a calendar within a designated div, with and 145 //EX: headerDP = buildDatepicker({"calendarID":"headerCalendar","linkedInputID":"headerCalendarInput","isModal":false,"forceDates":true, "defaultDate": "{{Output date from server Here}}"}); <~ would create a calendar object for the calendar presented at #headerCalendar, and link it to #headerCalendarInput 146 //most calendar methods are specific to the document the calendar resides on, and should be handled via the onChange event for the linked input 147 //Available Options: 148 // calendarID (required) == string, ID of calendar div 149 // linkedInput (required) == string, ID of input which will change when a date is selected 150 // isModal == boolean, if true, calendar will be hidden, and display when the designated input recieves focus. If false, the calendar will be present and display as an inline block at all times. 151 // forceDates == boolean, if true only highlighted dates will be clickable 152 // detailedCalendar == boolean, if true data is pulled to determine pricing information, sold out days, limited availablility - requires eventID 153 // defaultDate == string, mm/dd/yyyy date that calendar should start on (this will only represent the month displayed at the begining) 154 // type == string: defaults to "performancedates", which will add all visible performances 155 // eventID == integer: defaults to -1 which means no event. Other values will filter by events with that ID, allowing for a search of performance dates for a specific event only 156 // isMultiplePerformanceIndicator == boolean: if true, shows indicator for dates with multiple performance times 157 // 158 //Methods: 159 // showDlg()/hideDlg() : shows/hides modal calendars, no valid for non-modal calendars 160 // addHighlightDay(mm/dd/yyyy) : adds a date (presented as a mm/dd/yyyy string) to the list of highlight dates for the calendar - REQUIRES HighlightDays() function call to visually represent this change on the calendar 161 // clearHihghlightDays() : removes all stored highlight dates 162 // highlightDays() : adds highlight class to stored days, visually highlighting them ont he calendar. 163 164 var myID = options.calendarID; //required 165 var myLinkedInput = options.linkedInputID; //required 166 var isModal = options.isModal || false; 167 var showLoader = options.showLoader || false; 168 var forceDates = options.forceDates || false; 169 var myDefault = new Date(); 170 if (options.defaultDate) { 171 try{ 172 173 myDefault = new Date(options.defaultDate); 174 } catch (e) { 175 console.log("date no valid for calendar: " + myID); 176 console.log(e); 177 } 178 } 179 var type = options.type || "performancedates"; 180 var eventID = options.eventID || -1; 181 var detailedCalendar = options.detailedCalendar && eventID != -1 || false; 182 var bundleID = options.bundleID || -1; 183 var categoryID = options.CategoryID || -1; 184 var corporatePartnerPage = options.corporatePartnerPage || 0; 185 var bValidCoupon = options.bValidCoupon || 0; 186 var couponCode = options.couponCode || ""; 187 var isMultiplePerformanceIndicator = options.isMultiplePerformanceIndicatorFlag || 0; 188 189 return new swDatepicker(myID, myLinkedInput, isModal, showLoader, forceDates, detailedCalendar, myDefault, type, eventID, bundleID, categoryID, corporatePartnerPage,bValidCoupon,couponCode,isMultiplePerformanceIndicator) 190} 191function swDatepicker(id, target, modal, loader, force, detailed, defaultDate, type, eventID, bundleID, categoryID, corporatePartnerPage,bValidCoupon,couponCode,isMultiplePerformanceIndicator) { 192 193 this.$id = $('#' + id); // element to attach widget to 194 this.$monthObj = this.$id.find('.month'); 195 this.$prev = this.$id.find('.bn_prev'); 196 this.$next = this.$id.find('.bn_next'); 197 this.$grid = this.$id.find('.cal'); 198 this.$target = $('#' + target); // div or text box that will receive the selected date string and focus (if modal) 199 this.bModal = modal; // true if datepicker should appear in a modal dialog box. 200 this.showLoader = loader; 201 this.forceDateSelection = force; //if true, will only allow users to click on highlighted dates - see addHighlightDay() 202 this.detailedCalendar = detailed; 203 this.active = !modal; 204 this.type = type; 205 this.eventID = eventID; 206 this.bundleID = bundleID; 207 this.categoryID = categoryID; 208 this.corporatePartnerPage = corporatePartnerPage; 209 this.fromDateRange = ""; 210 this.toDateRange = ""; 211 this.dateRangeEvents = []; 212 this.calendarName = id; 213 214 this.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 215 'July', 'August', 'September', 'October', 'November', 'December']; 216 217 this.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; 218 219 this.dateObj = new Date(); 220 221 this.curYear = this.dateObj.getFullYear(); 222 this.year = defaultDate.getFullYear(); 223 224 this.curMonth = this.dateObj.getMonth(); 225 this.month = defaultDate.getMonth(); 226 this.getFirstDate(defaultDate.getMonth()); //update the month to the first performance ASAP 227 228 this.curDate = this.dateObj.getDate(); 229 this.date = defaultDate.getDate(); 230 this.currentDate = (this.month == this.curMonth && this.year == this.curYear); 231 this.activeMonth = (String(this.month + 1) + "/1/" + this.year); 232 233 this.keys = { 234 tab: 9, 235 enter: 13, 236 esc: 27, 237 space: 32, 238 pageup: 33, 239 pagedown: 34, 240 end: 35, 241 home: 36, 242 left: 37, 243 up: 38, 244 right: 39, 245 down: 40 246 }; 247 248 this.bValidCoupon = bValidCoupon; 249 this.couponCode = couponCode; 250 this.isMultiplePerformanceIndicator = isMultiplePerformanceIndicator; 251 252 this.highlightDates = []; 253 254 // display the current month 255 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 256 257 // populate the calendar grid
258 this.popGrid(); 259 260 // update the table's activedescdendant to point to the current day 261 this.$grid.attr('aria-activedescendant', this.$grid.find('.today').attr('id')); 262 263 this.bindHandlers(); 264 265 //show selected day 266 $('#' + this.calendarName + '-day' + this.date).addClass('focus').attr('aria-selected', 'true'); 267 268 // hide dialog if in modal mode 269 if (this.bModal == true) { 270 this.$id.attr('aria-hidden', 'true'); 271 //show/hide functionality may vary based on use, so should be handled after the datepicker is created. 272 //if we're on mobile, disable keyboard for the input: 273 if ($(window).width() < 1024) { 274 this.$target.attr("readonly", "true"); 275 } 276 } 277 278 this.currencySymbol = "$"; 279 this.buyTicketsButtonText = "Buy Tickets"; 280} 281 282// 283// popGrid() is a member function to populate the datepicker grid with calendar days 284// representing the current month 285// 286// @return N/A 287// 288swDatepicker.prototype.popGrid = function () { 289 if(this.showLoader) 290 $(".calendar-loading").show(); 291 var numDays = this.calcNumDays(this.year, this.month); 292 var startWeekday = this.calcStartWeekday(this.year, this.month); 293 //var lastMonth = this.month - 1; 294 //var lastMonthYear = this.year; 295 var weekday = 0; 296 var curDay = 1; 297 var rowCount = 1; 298 var $tbody = this.$grid.find('tbody'); 299 300 var currentDateDay = this.dateObj.getDate(); 301 var currentDateMonth = this.dateObj.getMonth(); 302 var currentDateYear = this.dateObj.getFullYear(); 303 304 var gridCells = '\t<tr id="row1">\n'; 305 306 // Keeping in case the client (Gaylord) pushes back on not having previous month's dates selectable 307 // If the last month is -1, roll it over to December (11) and subtract 1 from the last month's year 308 /*if (lastMonth < 0) { 309 lastMonth = 11; 310 lastMonthYear = lastMonthYear - 1; 311 } 312 313 var lastMonthNumDays = this.calcNumDays(lastMonthYear, lastMonth); 314 var lastMonthStartDay = lastMonthNumDays - (startWeekday - 1);*/ 315 316 // clear the grid 317 $tbody.empty(); 318 $('#msg').empty(); 319 320 // Keeping in case the client (Gaylord) pushes back on not having previous month's dates selectable 321 // Insert the leading empty cells 322 /*for (var weekday = 0; weekday < startWeekday; weekday++) { 323 gridCells += '\t\t<td id="' + this.calendarName + '-day' + lastMonthStartDay + '" class="day-cell muted last-month" headers="row' + 324 rowCount + ' ' + this.dayNames[weekday] + '" role="gridcell" aria-selected="false" data-year="' + lastMonthYear + '"><span class="calendar-day notranslate" data-month="' + lastMonth + '">' + lastMonthStartDay + '</span> <span class="calendar-dayoftheweek" style="display: none;">' + this.dayNames[weekday] + '</span></td>'; 325 //gridCells += '\t\t<td class="empty" data-month="' + lastMonth + '" data-year="' + lastMonthYear + '" data-day="' + lastMonthStartDay + '"> </td>\n'; 326 lastMonthStartDay++; 327 }*/ 328 329 for (var weekday = 0; weekday < startWeekday; weekday++) { 330 gridCells += '\t\t<td class="empty"> </td>\n'; 331 } 332 333 // insert the days of the month. 334 for (curDay = 1; curDay <= numDays; curDay++) { 335 336 if (curDay == this.curDate && this.currentDate == true) { 337 338 gridCells += '\t\t<td id="' + this.calendarName + '-day' + curDay + '" class="today day-cell" aria-label="row' + 339 rowCount + ' ' + this.dayNames[weekday] + '" role="gridcell" aria-selected="false"><span class="calendar-day notranslate">' + curDay + '</span> <span class="calendar-dayoftheweek" style="display: none;">' + this.dayNames[weekday] + '</span></td>'; 340 } 341 else { 342 var addMuted = ""; 343 344 // Only mute dates in the past for the date range selector widget 345 if (this.type == 'dateRangeSelect') { 346 // If the year is in the past, or the year is the same but the month is in the past, or the month and year are the same but the day is in the past, mute the date 347 if (this.year < currentDateYear 348 || (this.year == currentDateYear && this.month < currentDateMonth) 349 || (this.year == currentDateYear && this.month == currentDateMonth && curDay < currentDateDay) 350 ) { 351 addMuted = " muted"; 352 } 353 } 354 355 gridCells += '\t\t<td id="' + this.calendarName + '-day' + curDay + '" class="day-cell' + addMuted + '" aria-label="row' + 356 rowCount + ' ' + this.dayNames[weekday] + '" role="gridcell" aria-selected="false"><span class="calendar-day notranslate">' + curDay + '</span> <span class="calendar-dayoftheweek" style="display: none;">' + this.dayNames[weekday] + '</span></td>'; 357 } 358 359 360 if (weekday == 6 && curDay < numDays) { 361 // This was the last day of the week, close it out 362 // and begin a new one 363 gridCells += '\t</tr>\n\t<tr id="row' + rowCount + '">\n'; 364 rowCount++; 365 weekday = 0; 366 } 367 else { 368 weekday++; 369 } 370 } 371 372 // Insert any trailing empty cells 373 for (weekday; weekday < 7; weekday++) { 374 375 gridCells += '\t\t<td class="empty"> </td>\n'; 376 } 377 378 gridCells += '\t</tr>'; 379 380 $tbody.append(gridCells); 381 if(this.detailedCalendar){ 382 this.getCalendarDetails(); 383 }else{ 384 this.fetchDates();
385 } 386 387} 388 389// 390// calcNumDays() is a member function to calculate the number of days in a given month 391// 392// @return (integer) number of days 393// 394swDatepicker.prototype.calcNumDays = function (year, month) { 395 396 return 32 - new Date(year, month, 32).getDate(); 397} 398 399// 400// calcstartWeekday() is a member function to calculate the day of the week the first day of a 401// month lands on 402// 403// @return (integer) number representing the day of the week (0=Sunday....6=Saturday) 404// 405swDatepicker.prototype.calcStartWeekday = function (year, month) { 406 407 return new Date(year, month, 1).getDay(); 408 409} // end calcStartWeekday() 410 411// 412// showPrevMonth() is a member function to show the previous month 413// 414// @param (offset int) offset may be used to specify an offset for setting 415// focus on a day the specified number of days from 416// the end of the month. 417// @return N/A 418// 419swDatepicker.prototype.showPrevMonth = function (offset) { 420 // show the previous month 421 if (this.month < 1) { 422 this.month = 11; 423 this.year--; 424 } 425 else { 426 this.month--; 427 } 428 429 if (this.month != this.curMonth || this.year != this.curYear) { 430 this.currentDate = false; 431 } 432 else { 433 this.currentDate = true; 434 } 435 436 this.activeMonth = (String(this.month + 1) + "/1/" + this.year) 437 438 // populate the calendar grid 439 this.popGrid(); 440 441 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 442 443 // if offset was specified, set focus on the last day - specified offset 444 if (offset != null) { 445 var numDays = this.calcNumDays(this.year, this.month); 446 var day = 'day' + (numDays - offset); 447 448 this.$grid.attr('aria-activedescendant', this.calendarName + '-' + day); 449 $('#' + this.calendarName + '-' + day).addClass('focus').attr('aria-selected', 'true'); 450 } 451 452 453} // end showPrevMonth() 454 455// 456// showNextMonth() is a member function to show the next month 457// 458// @param (offset int) offset may be used to specify an offset for setting 459// focus on a day the specified number of days from 460// the beginning of the month. 461// @return N/A 462// 463swDatepicker.prototype.showNextMonth = function (offset) { 464 465 // show the next month 466 if (this.month == 11) { 467 this.month = 0; 468 this.year++; 469 } 470 else { 471 this.month++; 472 } 473 474 if (this.month != this.curMonth || this.year != this.curYear) { 475 this.currentDate = false; 476 } 477 else { 478 this.currentDate = true; 479 } 480 481 this.activeMonth = (String(this.month + 1) + "/1/" + this.year) 482 483 // populate the calendar grid 484 this.popGrid(); 485 486 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 487 488 // if offset was specified, set focus on the first day + specified offset 489 if (offset != null) { 490 var day = 'day' + offset; 491 492 this.$grid.attr('aria-activedescendant', this.calendarName + '-' + day); 493 $('#' + this.calendarName + '-' + day).addClass('focus').attr('aria-selected', 'true'); 494 } 495 496} // end showNextMonth() 497 498// 499// showPrevYear() is a member function to show the previous year 500// 501// @return N/A 502// 503swDatepicker.prototype.showPrevYear = function () { 504 505 // decrement the year 506 this.year--; 507 508 if (this.month != this.curMonth || this.year != this.curYear) { 509 this.currentDate = false; 510 } 511 else { 512 this.currentDate = true; 513 } 514 515 // populate the calendar grid 516 this.popGrid(); 517 518 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 519 520} // end showPrevYear() 521 522// 523// showNextYear() is a member function to show the next year 524// 525// @return N/A 526// 527swDatepicker.prototype.showNextYear = function () { 528 529 // increment the year 530 this.year++; 531 532 if (this.month != this.curMonth || this.year != this.curYear) { 533 this.currentDate = false; 534 } 535 else { 536 this.currentDate = true; 537 } 538 539 // populate the calendar grid
540 this.popGrid(); 541 542 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 543 544} // end showNextYear() 545 546// 547// bindHandlers() is a member function to bind event handlers for the widget 548// 549// @return N/A 550// 551swDatepicker.prototype.bindHandlers = function () { 552 553 var thisObj = this; 554 555 ////////////////////// bind button handlers ////////////////////////////////// 556 this.$prev.click(function (e) { 557 return thisObj.handlePrevClick(e); 558 }); 559 560 this.$next.click(function (e) { 561 return thisObj.handleNextClick(e); 562 }); 563 564 this.$prev.keydown(function (e) { 565 return thisObj.handlePrevKeyDown(e); 566 }); 567 568 this.$next.keydown(function (e) { 569 return thisObj.handleNextKeyDown(e); 570 }); 571 572 ///////////// bind grid handlers ////////////// 573 574 this.$grid.keydown(function (e) { 575 return thisObj.handleGridKeyDown(e); 576 }); 577 578 this.$grid.keypress(function (e) { 579 return thisObj.handleGridKeyPress(e); 580 }); 581 582 this.$grid.focus(function (e) { 583 return thisObj.handleGridFocus(e); 584 }); 585 586 this.$grid.blur(function (e) { 587 return thisObj.handleGridBlur(e); 588 }); 589 590 this.$grid.delegate('td', 'click', function (e) { 591 return thisObj.handleGridClick(this, e); 592 }); 593 594} // end bindHandlers(); 595 596function scrollToFirstHighlightDay() { 597 // find all the heights of elements before the calendar 598 var EventInfoHeight = $('#EventInformationWrap').outerHeight() + 64; // 64 is the height mobile navigation 599 var EventLabelAndOptionsHeight = $('#eventCalendarLabelAndOptions').outerHeight(); 600 var CalendarMonthHeight = $('.sw-datepicker.large-datepicker .month-wrap').outerHeight(); 601 602 var EventInfoAndOptionsHeight = EventInfoHeight + EventLabelAndOptionsHeight; 603 var CalendarTopInfoHeaderHeights = EventInfoHeight + EventLabelAndOptionsHeight + CalendarMonthHeight + 10; // 10 is just a gap added so it is not sticking against the month section 604 605 // set the Top section sticky so when it focuses on the first hightlight day you can still see the informations 606 $('#EventInformationWrap').addClass("make-this-section-sticky"); 607 $('#eventCalendarLabelAndOptions').addClass("make-this-section-sticky"); 608 $('#eventCalendarLabelAndOptions').css("top", EventInfoHeight); 609 $('.sw-datepicker.large-datepicker .month-wrap').addClass("make-this-section-sticky"); 610 $('.sw-datepicker.large-datepicker .month-wrap').css("top", EventInfoAndOptionsHeight); 611 612 // Check if any elements with the class .highlight-day exist 613 var highlightDay = $('.performance-list-calendar .highlight-day').first(); 614 615 // set the first day cell 616 var firstDayCel = $('.day-cell').first(); 617 var scrollToPosition = 0; 618 619 if (highlightDay.length > 0) { // Get the offset only if .highlight-day element exists 620 scrollToPosition = highlightDay.offset().top; 621 scrollToPosition = scrollToPosition - CalendarTopInfoHeaderHeights; 622 $('html, body').animate({scrollTop: scrollToPosition}, 'slow'); 623 } else { // if there's no highlights on this month, focus on the first day of the month 624 scrollToPosition = firstDayCel.offset().top; 625 scrollToPosition = scrollToPosition - (CalendarTopInfoHeaderHeights * 2); 626 $('html, body').animate({scrollTop: scrollToPosition}, 'slow'); 627 } 628} 629 630// 631// handlePrevClick() is a member function to process click events for the prev month button 632// 633// @input (e obj) e is the event object associated with the event 634// 635// @return (boolean) false if consuming event, true if propagating 636// 637swDatepicker.prototype.handlePrevClick = function (e) { 638 639 var active = this.$grid.attr('aria-activedescendant'); 640 641 if (e.ctrlKey) { 642 this.showPrevYear(); 643 } 644 else { 645 this.showPrevMonth(); 646 } 647 648 if (this.currentDate == false) { 649 this.$grid.attr('aria-activedescendant', this.calendarName + '-day1'); 650 } 651 else { 652 this.$grid.attr('aria-activedescendant', active); 653 } 654 655 e.stopPropagation(); 656 return false; 657 658} // end handlePrevClick() 659 660// 661// handleNextClick() is a member function to process click events for the next month button 662// 663// @input (e obj) e is the event object associated with the event 664// 665// @return (boolean) false if consuming event, true if propagating 666// 667swDatepicker.prototype.handleNextClick = function (e) { 668 669 var active = this.$grid.attr('aria-activedescendant'); 670 671 if (e.ctrlKey) { 672 this.showNextYear(); 673 } 674 else { 675 this.showNextMonth(); 676 } 677 678 if (this.currentDate == false) { 679 this.$grid.attr('aria-activedescendant', this.calendarName + '-day1'); 680 } 681 else { 682 this.$grid.attr('aria-activedescendant', active); 683 } 684 685 e.stopPropagation(); 686 return false; 687 688} // end handleNextClick() 689 690// 691// handlePrevKeyDown() is a member function to process keydown events for the prev month button 692// 693// @input (e obj) e is the event object associated with the event 694// 695// @return (boolean) false if consuming event, true if propagating 696// 697swDatepicker.prototype.handlePrevKeyDown = function (e) { 698 699 if (e.altKey) { 700 return true; 701 } 702 703 switch (e.keyCode) { 704 case this.keys.tab: { 705 if (this.bModal == false || !e.shiftKey || e.ctrlKey) { 706 return true; 707 } 708 709 this.$grid.focus(); 710 e.stopPropagation(); 711 return false; 712 } 713 case this.keys.enter: 714 case this.keys.space: { 715 if (e.shiftKey) { 716 return true; 717 } 718 719 if (e.ctrlKey) { 720 this.showPrevYear(); 721 } 722 else { 723 this.showPrevMonth(); 724 } 725 726 e.stopPropagation(); 727 return false; 728 } 729 } 730 731 return true; 732 733} // end handlePrevKeyDown() 734 735// 736// handleNextKeyDown() is a member function to process keydown events for the next month button 737// 738// @input (e obj) e is the event object associated with the event 739// 740// @return (boolean) false if consuming event, true if propagating 741// 742swDatepicker.prototype.handleNextKeyDown = function (e) { 743 744 if (e.altKey) { 745 return true; 746 } 747 748 switch (e.keyCode) { 749 case this.keys.enter: 750 case this.keys.space: { 751 752 if (e.ctrlKey) { 753 this.showNextYear(); 754 } 755 else { 756 this.showNextMonth(); 757 } 758 759 e.stopPropagation(); 760 return false; 761 } 762 } 763 764 return true; 765 766} // end handleNextKeyDown() 767 768// 769// handleGridKeyDown() is a member function to process keydown events for the datepicker grid 770// 771// @input (e obj) e is the event object associated with the event 772// 773// @return (boolean) false if consuming event, true if propagating 774// 775swDatepicker.prototype.handleGridKeyDown = function (e) { 776 777 var $rows = this.$grid.find('tbody tr'); 778 var $curDay = $('#' + this.$grid.attr('aria-activedescendant'));
779 var $days = this.$grid.find('td').not('.empty'); 780 var $curRow = $curDay.parent(); 781 782 if (e.altKey) { 783 return true; 784 } 785 786 switch (e.keyCode) { 787 case this.keys.tab: { 788 789 if (this.bModal == true) { 790 if (e.shiftKey) { 791 this.$next.focus(); 792 } 793 else { 794 this.$prev.focus(); 795 } 796 e.stopPropagation() 797 return false; 798 } 799 break; 800 } 801 case this.keys.enter: 802 case this.keys.space: { 803 804 if (e.ctrlKey) { 805 return true; 806 } 807 808 // update the target box 809 this.$target.val((this.month + 1) + '/' + $curDay.find(".calendar-day").text() + '/' + this.year).change(); 810 811 // fall through 812 } 813 case this.keys.esc: { 814 // dismiss the dialog box 815 this.hideDlg(); 816 817 e.stopPropagation(); 818 return false; 819 } 820 case this.keys.left: { 821 822 if (e.ctrlKey || e.shiftKey) { 823 return true; 824 } 825 826 var dayIndex = $days.index($curDay) - 1; 827 var $prevDay = null; 828 829 if (dayIndex >= 0) { 830 $prevDay = $days.eq(dayIndex); 831 832 $curDay.removeClass('focus').attr('aria-selected', 'false'); 833 $prevDay.addClass('focus').attr('aria-selected', 'true'); 834 835 this.$grid.attr('aria-activedescendant', $prevDay.attr('id')); 836 } 837 else { 838 this.showPrevMonth(0); 839 } 840 841 e.stopPropagation(); 842 return false; 843 } 844 case this.keys.right: { 845 846 if (e.ctrlKey || e.shiftKey) { 847 return true; 848 } 849 850 var dayIndex = $days.index($curDay) + 1; 851 var $nextDay = null; 852 853 if (dayIndex < $days.length) { 854 $nextDay = $days.eq(dayIndex); 855 $curDay.removeClass('focus').attr('aria-selected', 'false'); 856 $nextDay.addClass('focus').attr('aria-selected', 'true'); 857 858 this.$grid.attr('aria-activedescendant', $nextDay.attr('id')); 859 } 860 else { 861 // move to the next month 862 this.showNextMonth(1); 863 } 864 865 e.stopPropagation(); 866 return false; 867 } 868 case this.keys.up: { 869 870 if (e.ctrlKey || e.shiftKey) { 871 return true; 872 } 873 874 var dayIndex = $days.index($curDay) - 7; 875 var $prevDay = null; 876 877 if (dayIndex >= 0) { 878 $prevDay = $days.eq(dayIndex); 879 880 $curDay.removeClass('focus').attr('aria-selected', 'false'); 881 $prevDay.addClass('focus').attr('aria-selected', 'true'); 882 883 this.$grid.attr('aria-activedescendant', $prevDay.attr('id')); 884 } 885 else { 886 // move to appropriate day in previous month 887 dayIndex = 6 - $days.index($curDay); 888 889 this.showPrevMonth(dayIndex); 890 } 891 892 e.stopPropagation(); 893 return false; 894 } 895 case this.keys.down: { 896 897 if (e.ctrlKey || e.shiftKey) { 898 return true; 899 } 900 901 var dayIndex = $days.index($curDay) + 7; 902 var $prevDay = null; 903 904 if (dayIndex < $days.length) { 905 $prevDay = $days.eq(dayIndex); 906 907 $curDay.removeClass('focus').attr('aria-selected', 'false'); 908 $prevDay.addClass('focus').attr('aria-selected', 'true'); 909 910 this.$grid.attr('aria-activedescendant', $prevDay.attr('id')); 911 } 912 else { 913 // move to appropriate day in next month 914 dayIndex = 8 - ($days.length - $days.index($curDay)); 915 916 this.showNextMonth(dayIndex); 917 } 918 919 e.stopPropagation(); 920 return false; 921 } 922 case this.keys.pageup: { 923 var active = this.$grid.attr('aria-activedescendant'); 924 925 926 if (e.shiftKey) { 927 return true; 928 } 929 930 931 if (e.ctrlKey) { 932 this.showPrevYear(); 933 } 934 else { 935 this.showPrevMonth(); 936 } 937 938 if ($('#' + active).attr('id') == undefined) { 939 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 940 $('#' + this.calendarName + '-' + lastDay).addClass('focus').attr('aria-selected', 'true'); 941 } 942 else { 943 $('#' + this.calendarName + '-' + active).addClass('focus').attr('aria-selected', 'true'); 944 } 945 946 e.stopPropagation(); 947 return false; 948 } 949 case this.keys.pagedown: { 950 var active = this.$grid.attr('aria-activedescendant'); 951 952 953 if (e.shiftKey) { 954 return true; 955 } 956 957 if (e.ctrlKey) { 958 this.showNextYear(); 959 } 960 else { 961 this.showNextMonth(); 962 } 963 964 if ($('#' + active).attr('id') == undefined) { 965 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 966 $('#' + this.calendarName + '-' + lastDay).addClass('focus').attr('aria-selected', 'true'); 967 } 968 else { 969 $('#' + this.calendarName + '-' + active).addClass('focus').attr('aria-selected', 'true'); 970 } 971 972 e.stopPropagation(); 973 return false; 974 } 975 case this.keys.home: { 976 977 if (e.ctrlKey || e.shiftKey) { 978 return true; 979 } 980 981 $curDay.removeClass('focus').attr('aria-selected', 'false'); 982 983 $('#' + this.calendarName + '-day1').addClass('focus').attr('aria-selected', 'true'); 984 985 this.$grid.attr('aria-activedescendant', this.calendarName + '-day1'); 986 987 e.stopPropagation(); 988 return false; 989 } 990 case this.keys.end: { 991 992 if (e.ctrlKey || e.shiftKey) { 993 return true; 994 } 995 996 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 997 998 $curDay.removeClass('focus').attr('aria-selected', 'false'); 999 1000 $('#' + this.calendarName + '-' + lastDay).addClass('focus').attr('aria-selected', 'true'); 1001 1002 this.$grid.attr('aria-activedescendant', this.calendarName + '-' + lastDay); 1003 1004 e.stopPropagation(); 1005 return false; 1006 } 1007 } 1008 1009 return true; 1010 1011} // end handleGridKeyDown() 1012 1013//
1014// handleGridKeyPress() is a member function to consume keypress events for browsers that 1015// use keypress to scroll the screen and manipulate tabs 1016// 1017// @input (e obj) e is the event object associated with the event 1018// 1019// @return (boolean) false if consuming event, true if propagating 1020// 1021swDatepicker.prototype.handleGridKeyPress = function (e) { 1022 1023 if (e.altKey) { 1024 return true; 1025 } 1026 1027 switch (e.keyCode) { 1028 case this.keys.tab: 1029 case this.keys.enter: 1030 case this.keys.space: 1031 case this.keys.esc: 1032 case this.keys.left: 1033 case this.keys.right: 1034 case this.keys.up: 1035 case this.keys.down: 1036 case this.keys.pageup: 1037 case this.keys.pagedown: 1038 case this.keys.home: 1039 case this.keys.end: { 1040 e.stopPropagation(); 1041 return false; 1042 } 1043 } 1044 1045 return true; 1046 1047} // end handleGridKeyPress() 1048 1049// 1050// handleGridClick() is a member function to process mouse click events for the datepicker grid 1051// 1052// @input (id obj) e is the id of the object triggering the event 1053// 1054// @input (e obj) e is the event object associated with the event 1055// 1056// @return (boolean) false if consuming event, true if propagating 1057// 1058swDatepicker.prototype.handleGridClick = function (id, e) { 1059 var $cell = $(id); 1060 1061 if ($cell.is('.empty')) { 1062 return true; 1063 } 1064 1065 this.$grid.find('.focus').removeClass('focus').attr('aria-selected', 'false'); 1066 $cell.addClass('focus').attr('aria-selected', 'true'); 1067 this.$grid.attr('aria-activedescendant', $cell.attr('id')); 1068 1069 var $curDay = $('#' + this.$grid.attr('aria-activedescendant')); 1070 1071 /*console.log($curDay); 1072 var isLastMonth = $curDay.hasClass('last-month'); 1073 1074 var monthSelected = this.month + 1; 1075 var yearSelected = this.year; 1076 1077 if (isLastMonth) { 1078 monthSelected--; 1079 1080 if (monthSelected == 0) 1081 monthSelected = 12; 1082 1083 yearSelected = $curDay.data('year'); 1084 } 1085 1086 console.log("month selected: " + monthSelected); 1087 console.log("year selected: " + yearSelected);*/ 1088 1089 // update the target box 1090 if(this.type == 'dateRangeSelect'){ 1091 if ($curDay.hasClass('muted')) 1092 return true; 1093 1094 var $rangeSelDate = new Date((this.month + 1) + '/' + $curDay.children('.calendar-day').text() + '/' + this.year); 1095 if(this.fromDateRange == '' && this.toDateRange == ''){ 1096 //no dates selected yet, store this in the from date range for now 1097 this.fromDateRange = $rangeSelDate; 1098 }else{ 1099 //we've previously selected at least one date here, so figure out which one it should be 1100 if($rangeSelDate < this.fromDateRange){ 1101 this.toDateRange = this.fromDateRange; 1102 this.fromDateRange = $rangeSelDate; 1103 }else{ 1104 this.toDateRange = $rangeSelDate; 1105 } 1106 } 1107 1108 var objDateRange = {} 1109 objDateRange.from = this.fromDateRange; 1110 objDateRange.to = this.toDateRange; 1111 this.$target.val(JSON.stringify(objDateRange)).change(); 1112 if(objDateRange.from != '' && objDateRange.to != ''){ 1113 this.hideDlg(); //NOTE: this only works if the date range is a modal, for other calendars you'll need to manage display according to needs based on current values. 1114 } 1115 e.stopPropagation(); 1116 return false; 1117 } 1118 if (!this.forceDateSelection || $cell.hasClass("highlight-day")) { 1119 this.$target.val((this.month + 1) + '/' + $curDay.children('.calendar-day').text() + '/' + this.year).change(); 1120 // dismiss the dialog box 1121 this.hideDlg(); 1122 } 1123 e.stopPropagation(); 1124 return false; 1125 1126} // end handleGridClick() 1127 1128// 1129// handleGridFocus() is a member function to process focus events for the datepicker grid 1130// 1131// @input (e obj) e is the event object associated with the event 1132// 1133// @return (boolean) true 1134// 1135swDatepicker.prototype.handleGridFocus = function (e) { 1136 var active = this.$grid.attr('aria-activedescendant'); 1137 1138 if ($('#' + active).attr('id') == undefined) { 1139 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 1140 $('#' + lastDay).addClass('focus').attr('aria-selected', 'true'); 1141 } 1142 else { 1143 $('#' + active).addClass('focus').attr('aria-selected', 'true'); 1144 } 1145 1146 return true; 1147 1148} // end handleGridFocus() 1149 1150// 1151// handleGridBlur() is a member function to process blur events for the datepicker grid 1152// 1153// @input (e obj) e is the event object associated with the event 1154// 1155// @return (boolean) true 1156// 1157swDatepicker.prototype.handleGridBlur = function (e) { 1158 $('#' + this.$grid.attr('aria-activedescendant')).removeClass('focus').attr('aria-selected', 'false'); 1159 1160 return true; 1161 1162} // end handleGridBlur() 1163 1164//
1165// showDlg() is a member function to show the datepicker and give it focus. This function is only called if 1166// the datepicker is used in modal dialog mode. 1167// 1168// @return N/A 1169// 1170swDatepicker.prototype.showDlg = function () { 1171 if (!this.bModal) 1172 return; 1173 1174 var thisObj = this; 1175 var thisNode = this.$id; 1176 1177 this.highlightDays(); 1178 1179 this.active = true; 1180 1181 //prevent calendar from pushing out of the right side of the window 1182 if (thisNode.parent()[0].getBoundingClientRect().left > (window.innerWidth / 2)) 1183 thisNode.addClass("right-side"); 1184 1185 $(".content-wrap").bind('click', function (e) { 1186 if (!thisNode[0].contains(e.target) && e.target != thisObj.$target[0]) { 1187 thisObj.hideDlg(); 1188 } 1189 }); 1190 1191 // show the dialog 1192 this.$id.attr('aria-hidden', 'false'); 1193 1194 this.$grid.focus(); 1195 1196} // end showDlg() 1197 1198// 1199// hideDlg() is a member function to hide the datepicker and remove focus. This function is only called if 1200// the datepicker is used in modal dialog mode. 1201// 1202// @return N/A 1203// 1204swDatepicker.prototype.hideDlg = function () { 1205 if (!this.bModal) 1206 return; 1207 1208 this.active = false; 1209 var thisNode = this.$id; 1210 1211 // unbind the modal event sinks 1212 $(document).unbind('click'); 1213 1214 // hide the dialog 1215 this.$id.attr('aria-hidden', 'true'); 1216 1217 // set focus on the focus target 1218 //this.$target.focus(); 1219 1220} // end showDlg() 1221 1222//function to highlight days with performances or valid information 1223//to prevent rewriting the calendar each time a date is added, popGrid() should be called after all dates have been added 1224swDatepicker.prototype.addHighlightDay = function (date) { 1225 var datesplit = String(date).split("/"); 1226 for(var i = 0;i < datesplit.length; i++){ 1227 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1228 } 1229 date = datesplit.join("/"); 1230 if (datesplit.length != 3) { 1231 //date didn't come in in m/d/yyyy format, kick it back in the console 1232 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1233 console.log(date); 1234 return; 1235 1236 } 1237 this.highlightDates.push(date); 1238 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1239 $("#" + this.calendarName + "-day" + datesplit[1]).addClass("highlight-day"); 1240 } 1241} 1242swDatepicker.prototype.addDateInfoBox = function (date, infoBoxText) { 1243 var datesplit = String(date).split("/"); 1244 for(var i = 0;i < datesplit.length; i++){ 1245 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1246 } 1247 date = datesplit.join("/"); 1248 if (datesplit.length != 3) { 1249 //date didn't come in in m/d/yyyy format, kick it back in the console 1250 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1251 console.log(date); 1252 return; 1253 1254 } 1255 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1256 $("#" + this.calendarName + "-day" + datesplit[1]).append('<span class="date-info-box">' + infoBoxText + '</span>'); 1257 } 1258} 1259swDatepicker.prototype.addDateSubNote = function (date, noteText) { 1260 var datesplit = String(date).split("/"); 1261 for(var i = 0;i < datesplit.length; i++){ 1262 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1263 } 1264 date = datesplit.join("/"); 1265 if (datesplit.length != 3) { 1266 //date didn't come in in m/d/yyyy format, kick it back in the console 1267 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1268 console.log(date); 1269 return; 1270 1271 } 1272 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1273 var spanClass = this.isMultiplePerformanceIndicator ? 'date-info-box date-sub-note multiple-performancetime-subnote' : 'date-info-box date-sub-note'; 1274 $("#" + this.calendarName + "-day" + datesplit[1]).append('<span class="' + spanClass + '">' + noteText + '</span>'); 1275 } 1276} 1277swDatepicker.prototype.setDaySoldOut = function (date) { 1278 var datesplit = String(date).split("/"); 1279 for(var i = 0;i < datesplit.length; i++){ 1280 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1281 } 1282 date = datesplit.join("/"); 1283 if (datesplit.length != 3) { 1284 //date didn't come in in m/d/yyyy format, kick it back in the console 1285 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1286 console.log(date); 1287 return; 1288 1289 } 1290 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1291 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('sold-out'); 1292 1293 this.addDateInfoBox(date, "Sold Out"); 1294 $("#" + this.calendarName + "-day" + datesplit[1]).children(".date-info-box").removeClass("date-info-box").addClass("sold-out-info-box"); 1295 } 1296} 1297swDatepicker.prototype.setcustomStatus = function (date,showPhoneNumber,currenStatus) { 1298 var datesplit = String(date).split("/"); 1299 for(var i = 0;i < datesplit.length; i++){ 1300 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1301 } 1302 date = datesplit.join("/"); 1303 if (datesplit.length != 3) { 1304 //date didn't come in in m/d/yyyy format, kick it back in the console 1305 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1306 console.log(date); 1307 return; 1308 1309 } 1310 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1311 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('sold-out'); 1312 var phoneNumber = " <br> [email protected] " 1313 if (!showPhoneNumber) 1314 phoneNumber=""; 1315 this.addDateInfoBox(date, currenStatus +phoneNumber); 1316 1317 $("#" + this.calendarName + "-day" + datesplit[1]).children(".date-info-box").removeClass("date-info-box").addClass("sold-out-info-box"); 1318 } 1319} 1320swDatepicker.prototype.setDayLimitedAvailabilty = function (date) { 1321 var datesplit = String(date).split("/"); 1322 for(var i = 0;i < datesplit.length; i++){ 1323 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1324 } 1325 date = datesplit.join("/"); 1326 if (datesplit.length != 3) { 1327 //date didn't come in in m/d/yyyy format, kick it back in the console 1328 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1329 console.log(date); 1330 return; 1331 1332 } 1333 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1334 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('limited-availability'); 1335 1336 this.addDateSubNote(date, 'Selling Quickly'); 1337 //$("#" + this.calendarName + "-day" + datesplit[1]).children(".date-info-box").removeClass("date-info-box").addClass("sold-out-info-box"); 1338 } 1339 if($(".limited-availability-legend-item").length == 0){ 1340 1341 $(".calendar-notes-wrap").append('<div class="limited-availability-legend-item"><span classs="calendar-limited-availability-legend-icon">!</span> - Selling Quickly</div>') 1342 1343 // $("#streamlinedCalendarLimitedAvailabilityLegend").append('<div class="limited-availability-legend-item"><span class="calendar-limited-availability-legend-icon">!</span> - Selling Quickly</div>') 1344 } 1345} 1346swDatepicker.prototype.setMultiplePerformanceTimes = function (date) { 1347 var datesplit = String(date).split("/"); 1348 for(var i = 0;i < datesplit.length; i++){ 1349 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1350 } 1351 1352 date = datesplit.join("/"); 1353 if (datesplit.length != 3) { 1354 //date didn't come in in m/d/yyyy format, kick it back in the console 1355 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1356 return; 1357 1358 } 1359 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1360 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('multipleperformancetimes'); 1361 1362 } 1363 if($(".multiple-performancetimes-notes").length == 0){ 1364 1365 } 1366 1367} 1368swDatepicker.prototype.setMutedDay = function (date) { 1369 var datesplit = String(date).split("/"); 1370 for(var i = 0;i < datesplit.length; i++){ 1371 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1372 } 1373 date = datesplit.join("/"); 1374 if (datesplit.length != 3) { 1375 //date didn't come in in m/d/yyyy format, kick it back in the console 1376 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1377 return; 1378 1379 } 1380 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1381 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('muted'); 1382 } 1383} 1384swDatepicker.prototype.clearMutedDay = function (date) { 1385 var datesplit = String(date).split("/"); 1386 for(var i = 0;i < datesplit.length; i++){ 1387 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1388 } 1389 date = datesplit.join("/"); 1390 if (datesplit.length != 3) { 1391 //date didn't come in in m/d/yyyy format, kick it back in the console 1392 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1393 return; 1394 1395 } 1396 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1397 $("#" + this.calendarName + "-day" + datesplit[1]).removeClass('muted'); 1398 } 1399} 1400swDatepicker.prototype.setCouponMutedDay = function (date) { 1401 var datesplit = String(date).split("/"); 1402 for(var i = 0;i < datesplit.length; i++){ 1403 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1404 } 1405 date = datesplit.join("/"); 1406 if (datesplit.length != 3) { 1407 //date didn't come in in m/d/yyyy format, kick it back in the console 1408 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1409 return; 1410 1411 } 1412 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1413 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('coupon-muted'); 1414 } 1415}
1416swDatepicker.prototype.setPasswordHiddenDay = function (date) { 1417 var datesplit = String(date).split("/"); 1418 for(var i = 0;i < datesplit.length; i++){ 1419 datesplit[i] = datesplit[i].replace(/^0+/, ''); 1420 } 1421 date = datesplit.join("/"); 1422 if (datesplit.length != 3) { 1423 //date didn't come in in m/d/yyyy format, kick it back in the console 1424 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 1425 return; 1426 1427 } 1428 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 1429 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('password-hidden'); 1430 $("#" + this.calendarName + "-day" + datesplit[1]).removeClass('highlight-day'); 1431 } 1432} 1433swDatepicker.prototype.clearAllMutedDays = function () { 1434 $(".muted").removeClass('muted'); 1435} 1436swDatepicker.prototype.clearHighlightDays = function () { 1437 this.highlightDates = []; 1438 this.highlightDays(); 1439} 1440//highlights all days in the highlightDates array 1441swDatepicker.prototype.highlightDays = function () { 1442 $("#" + this.calendarName + " .highlight-day").removeClass("highlight-day"); 1443 var curYear = this.year; 1444 var curMonth = this.month; 1445 var calName = this.calendarName; 1446 var IEFix = new RegExp(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g); 1447 1448 this.highlightDates.forEach(function (o, i, a) { 1449 var datesplit = o.split("/"); 1450 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 1451 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '')).addClass("highlight-day"); 1452 } 1453 }); 1454 this.setColors(); 1455} 1456swDatepicker.prototype.setColors = function () { 1457 /* 1458 Custom color functionality. Utilized by dropping calendar-colors.txt file in root of custom folder 1459 requires json content of text file formatted as follows: 1460 { 1461 "events": 1462 {"528": 1463 [ 1464 {"date":"12/1/2025", "color": "#ccc"}, 1465 {"date":"12/2/2025", "color": "#ccc"} 1466 ] 1467 , 1468 "529": 1469 [ 1470 {"date":"12/8/2025", "color": "#ccc"}, 1471 {"date":"12/9/2025", "color": "#ccc"} 1472 ] 1473 } 1474 , 1475 "bundles":[], 1476 "generic": 1477 {"dates": 1478 [ 1479 {"date":"12/23/2025", "color": "#def"}, 1480 {"date":"12/22/2025", "color": "#1a1"} 1481 ] 1482 , 1483 "weekdays": 1484 [ 1485 {"day":"Saturday", "color": "#2a2"}, 1486 {"day":"Thursday", "color": "#3a3"} 1487 ] 1488 } 1489 } 1490 } 1491 */ 1492 var thisDP = this; 1493 try{ 1494 $.getJSON("/calendar-colors.txt") 1495 .done(function (data) { 1496 thisDP.renderColors(data); 1497 }) 1498 .fail(function (jqxhr, textStatus, error) { 1499 console.log("No Custom Calendar Colors Found"); 1500 return; 1501 }); 1502 }catch(e){ 1503 console.log("parsing error:"); 1504 console.log(e); 1505 return; 1506 } 1507} 1508swDatepicker.prototype.renderColors = function (colorData) { 1509 var curYear = this.year; 1510 var curMonth = this.month; 1511 var calName = this.calendarName; 1512 var IEFix = new RegExp(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g); 1513 //set generic colors 1514 if(colorData.generic){ 1515 if(colorData.generic.dates.length > 0){ 1516 colorData.generic.dates.forEach(function (o, i, a) { 1517 var datesplit = o.date.split("/"); 1518 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 1519 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '') + ' .calendar-day').css("background-color", o.color); 1520 } 1521 }); 1522 } 1523 if(colorData.generic.weekdays && colorData.generic.weekdays.length > 0){ 1524 colorData.generic.weekdays.forEach(function (o, i, a) { 1525 $("td[headers*=" + o.day + "] .calendar-day").css("background-color", o.color); 1526 }); 1527 } 1528 } 1529 if(colorData.events && colorData.events[this.eventID] && this.eventID !== -1){
1530 colorData.events[this.eventID].forEach(function (o, i, a) { 1531 var datesplit = o.date.split("/"); 1532 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 1533 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '') + ' .calendar-day').css("background-color", o.color); 1534 } 1535 }); 1536 } 1537 if(colorData.bundles && colorData.bundles[this.bundleID] && this.bundleID !== -1){ 1538 colorData.bundles[this.bundleID].forEach(function (o, i, a) { 1539 var datesplit = o.date.split("/"); 1540 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 1541 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '') + ' .calendar-day').css("background-color", o.color); 1542 } 1543 }); 1544 } 1545} 1546swDatepicker.prototype.fetchDates = function(){ 1547 var thisCalendar = this; 1548 var haveDates = thisCalendar.fetchLocalDates(); 1549 if (thisCalendar.categoryID >= 0) 1550 haveDates = false; 1551 this.clearHighlightDays(); 1552 if(haveDates){ 1553 //valid local dates stored 1554 try{ 1555 haveDates = JSON.parse(haveDates); 1556 if (haveDates.length > 0) { 1557 haveDates.forEach(function(o){ 1558 thisCalendar.addHighlightDay(o); 1559 }) 1560 thisCalendar.highlightDays(); 1561 } 1562 } catch (e) { 1563 console.log("Failed to grab dates. Date object not valid: ", haveDates); 1564 console.log(e); 1565 } 1566 } else { 1567 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 1568 { 1569 action: thisCalendar.type, 1570 calMonth: thisCalendar.activeMonth, 1571 iEvent: thisCalendar.eventID, 1572 iBundle: thisCalendar.bundleID, 1573 iCategory : thisCalendar.categoryID, 1574 cp : thisCalendar.corporatePartnerPage 1575 }) 1576 .done(function (data) { 1577 thisCalendar.storeDates(data.performancedates); 1578 try { 1579 if (data.performancedates.length > 0) { 1580 data.performancedates.forEach(function (o) { 1581 1582 thisCalendar.addHighlightDay(o); 1583 }) 1584 thisCalendar.highlightDays(); 1585 } 1586 } catch (e) { 1587 console.log("Failed to grab dates. Date object not valid: " + haveDates); 1588 console.log(e); 1589 } 1590 $(".calendar-loading").hide(); 1591 }) 1592 .fail(function (jqxhr, textStatus, error) { 1593 var err = textStatus + ", " + error; 1594 console.log("Request Failed: " + err); 1595 $(".calendar-loading").hide(); 1596 }); 1597 } 1598} 1599swDatepicker.prototype.getCalendarDetails = function(){ 1600 var thisCalendar = this; 1601 this.clearHighlightDays(); 1602 $("#" + this.calendarName).removeClass("has-muted-days"); 1603 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 1604 { 1605 action: thisCalendar.type, 1606 calMonth: thisCalendar.activeMonth, 1607 iEvent: thisCalendar.eventID, 1608 iBundle: thisCalendar.bundleID, 1609 iCategory : thisCalendar.categoryID, 1610 cp : thisCalendar.corporatePartnerPage, 1611 bValidCoupon : thisCalendar.bValidCoupon, 1612 couponCode : thisCalendar.couponCode 1613 }) 1614 .done(function (data) { 1615 //to save on request time, we need to resolve the data on the client a bit before we store it 1616 var performanceDates = []; 1617 data.performanceDateData.forEach(function(dd){ 1618 1619 if(dd.DoNotShowPublic == 0){ 1620 var detailsObj = {}; 1621 var currentDateIndex = fetchDateIndex(dd.CalendarDate, performanceDates); 1622 if(currentDateIndex == -1){ 1623 detailsObj.date = dd.CalendarDate; 1624 detailsObj.performances = []; 1625 detailsObj.performances.push(dd.PerformanceCode); 1626 detailsObj.defaultPrice = dd.LowestDefaultPrice; 1627 detailsObj.PerformanceName = dd.PerformanceName; 1628 detailsObj.PerformanceTime = dd.PerfTime; 1629 detailsObj.PerformanceStartTimeAlias = dd.PerformanceStartTimeAlias; 1630 detailsObj.DisplayType = dd.DisplayType; 1631 detailsObj.CalendarViewShowPrice = dd.CalendarViewShowPrice; 1632 detailsObj.CalendarViewShowPerformanceName = dd.CalendarViewShowPerformanceName; 1633 detailsObj.CalendarViewShowPerformanceTime = dd.CalendarViewShowPerformanceTime; 1634 detailsObj.CalendarViewShowBuyButton = dd.CalendarViewShowBuyButton; 1635 detailsObj.defaultPricingCode = dd.LowestDefaultPricingCode; 1636 detailsObj.secondaryPrice = dd.LowestSecondaryPrice; 1637 detailsObj.secondaryPricingCode =dd.LowestSecondaryPricingCode; 1638 detailsObj.NoCouponAvailable = dd.NoCouponAvailable; 1639 detailsObj.passwordMatch = dd.passwordMatch; 1640 detailsObj.qualifierPasswordMatch = dd.qualifierPasswordMatch; 1641 detailsObj.hasPassword = dd.hasPassword; 1642 detailsObj.hasQualifierPassword = dd.hasQualifierPassword; 1643 detailsObj.hasCoupons = dd.hasCoupons; 1644 detailsObj.IsSalesPeriodEnded = dd.IsSalesPeriodEnded; 1645 detailsObj.SaleIcon = dd.SaleIcon; 1646 detailsObj.BSaleIcon = dd.BSaleIcon; 1647 1648 detailsObj.hasQualifiers = dd.hasQualifiers;
1649 performanceDates.push(detailsObj) 1650 1651 }else{ 1652 performanceDates[currentDateIndex].performances.push(dd.PerformanceCode); 1653 performanceDates[currentDateIndex].NoCouponAvailable = dd.NoCouponAvailable; 1654 performanceDates[currentDateIndex].passwordMatch = dd.passwordMatch; 1655 performanceDates[currentDateIndex].acMatch = dd.acMatch; 1656 performanceDates[currentDateIndex].qualifierPasswordMatch = dd.qualifierPasswordMatch; 1657 performanceDates[currentDateIndex].hasPassword = dd.hasPassword; 1658 performanceDates[currentDateIndex].hasQualifierPassword = dd.hasQualifierPassword; 1659 performanceDates[currentDateIndex].hasCoupons = dd.hasCoupons; 1660 performanceDates[currentDateIndex].PerformanceName = dd.PerformanceName; 1661 performanceDates[currentDateIndex].PerformanceTime = dd.PerfTime; 1662 performanceDates[currentDateIndex].PerformanceStartTimeAlias = dd.PerformanceStartTimeAlias; 1663 performanceDates[currentDateIndex].CalendarViewShowPrice = dd.CalendarViewShowPrice; 1664 performanceDates[currentDateIndex].CalendarViewShowPerformanceName = dd.CalendarViewShowPerformanceName; 1665 performanceDates[currentDateIndex].CalendarViewShowPerformanceTime = dd.CalendarViewShowPerformanceTime; 1666 performanceDates[currentDateIndex].CalendarViewShowBuyButton = dd.CalendarViewShowBuyButton; 1667 performanceDates[currentDateIndex].IsSalesPeriodEnded = dd.IsSalesPeriodEnded; 1668 performanceDates[currentDateIndex].SaleIcon = dd.SaleIcon; 1669 performanceDates[currentDateIndex].BSaleIcon = dd.BSaleIcon; 1670 performanceDates[currentDateIndex].hasQualifiers = dd.hasQualifiers; 1671 //check for lowest price 1672 if(performanceDates[currentDateIndex].defaultPrice > dd.LowestDefaultPrice && dd.LowestDefaultPrice != null){ 1673 performanceDates[currentDateIndex].defaultPrice = dd.LowestDefaultPrice; 1674 performanceDates[currentDateIndex].defaultPricingCode = dd.LowestDefaultPricingCode; 1675 } 1676 if(performanceDates[currentDateIndex].hasCoupons == 1 && performanceDates[currentDateIndex].defaultPrice < dd.LowestDefaultPrice && dd.LowestDefaultPrice != null && false){ 1677 performanceDates[currentDateIndex].defaultPrice = dd.LowestDefaultPrice; 1678 performanceDates[currentDateIndex].defaultPricingCode = dd.LowestDefaultPricingCode; 1679 } 1680 if(performanceDates[currentDateIndex].secondaryPrice > dd.LowestSecondaryPrice && dd.LowestSecondaryPrice != null){ 1681 performanceDates[currentDateIndex].secondaryPrice = dd.LowestSecondaryPrice; 1682 performanceDates[currentDateIndex].secondaryPricingCode = dd.LowestSecondaryPricingCode; 1683 } 1684 1685 1686 } 1687 //set limited availaibility by matching up results from query with performances 1688 for(perf in data.performances){ 1689 if(data.performances[perf].id == dd.PerformanceID){ 1690 data.performances[perf].LimitedAvailability = dd.LimitedAvailability; 1691 data.performances[perf].TimeZone = dd.TimeZone.replace('"', ""); 1692 data.performances[perf].SingleAreaVenueAreaID = dd.SingleAreaVenueAreaID; 1693 data.performances[perf].NoCouponAvailable = dd.NoCouponAvailable; 1694 data.performances[perf].passwordMatch = dd.passwordMatch; 1695 data.performances[perf].acMatch = dd.acMatch; 1696 data.performances[perf].qualifierPasswordMatch = dd.qualifierPasswordMatch; 1697 data.performances[perf].hasPassword = dd.hasPassword; 1698 data.performances[perf].hasQualifierPassword = dd.hasQualifierPassword; 1699 } 1700 } 1701 } 1702 1703 }) 1704 1705 data.performanceDates = performanceDates; 1706 delete data.performanceDateData; 1707 try { 1708 if (thisCalendar.couponCode != "" && $("#couponCode").length > 0) 1709 { 1710 if($("#coupon-notify").length > 0) 1711 $("#coupon-notify").remove(); 1712 1713 var notifyMessage = document.createElement("div"); 1714 notifyMessage.setAttribute("id","coupon-notify"); 1715 notifyMessage.setAttribute("class",data.hasValidCoupon ? 'coupon-notify-message' : 'coupon-error-message'); 1716 notifyMessage.innerHTML = (data.hasValidCoupon ? "Code <b>" + thisCalendar.couponCode + "</b> has been applied to valid dates and times." : "The code entered is either invalid, or no longer available."); 1717 $("#plCalendar").prepend(notifyMessage); 1718 window.scrollTo(0,0); 1719 } 1720 1721 thisCalendar.doCalendarDetailed(data); 1722 } catch (e) { 1723 console.log("Failed to parse details. Date object not valid: ", data); 1724 console.log(e); 1725 } 1726 }) 1727 .fail(function (jqxhr, textStatus, error) { 1728 var err = textStatus + ", " + error; 1729 console.log("Request Failed: " + err); 1730 }); 1731} 1732swDatepicker.prototype.doCalendarDetailed = function(detailData){ 1733 var thisCalendar = this; 1734 this.detailData = detailData; 1735 var defaultPricingLegend = [], secondaryPricingLegend = [];
1736 detailData.performanceDates.forEach(function(d){ 1737 thisCalendar.addHighlightDay(d.date); 1738 if (d.NoCouponAvailable > 0) 1739 thisCalendar.setCouponMutedDay(d.date); 1740 1741 //check if date sold out 1742 var dateSoldOut = true; 1743 var customStatus = false; 1744 var showPhoneNumber =false; 1745 var dateLimitedAvailability = false; 1746 var performanceStatus=""; 1747 var performanceOnSale = false; 1748 var IsSalesPeriodEnded = false; 1749 var aggregatedMentaInfo = { 1750 buttonVisible: false, 1751 buttonText: "", 1752 buttonUrl: "", 1753 totalCount: 0 1754 }; 1755 1756 var isMentaResaleAvailable = false; 1757 var performanceTimesLength = 0; 1758 var QualiferButton = false; 1759 d.performances.forEach(function(datePerformance){ 1760 var performanceKey = String(datePerformance).toLowerCase(); 1761 var currentPerformance = detailData.performances[performanceKey]; 1762 1763 if (!currentPerformance) { 1764 var perfIndex = d.performances.indexOf(datePerformance); 1765 if (perfIndex !== -1) { 1766 d.performances.splice(perfIndex, 1); 1767 } 1768 console.log("Date Trimmed, child performance not contained in performance data: " + datePerformance); 1769 return; 1770 } 1771 1772 //let currentPerformance = detailData.performances[String(datePerformance).toLowerCase()]; 1773 performanceTimesLength ++; 1774 1775 if(detailData.performances[String(datePerformance).toLowerCase()] && detailData.performances[String(datePerformance).toLowerCase()].status == "On Sale"){ 1776 dateSoldOut = false; 1777 performanceOnSale=true; 1778 if(currentPerformance.LimitedAvailability == 1) 1779 dateLimitedAvailability = true; 1780 1781 IsSalesPeriodEnded = currentPerformance.IsSalesPeriodEnded==1 1782 } 1783 else{ 1784 1785 if ((currentPerformance.status != "Sold Out") && (currentPerformance.status != "On Sale") ){ 1786 1787 customStatus=true; 1788 performanceStatus=currentPerformance.status; 1789 dateSoldOut = false; 1790 //dateLimitedAvailability=false; 1791 if ( currentPerformance.bSalePhone==1 || currentPerformance.SalePhone==1){ 1792 showPhoneNumber=true; 1793 } 1794 } 1795 var mentaMarketplace = currentPerformance.MentaMarketplace; 1796 var hasMentaOption = currentPerformance.IsMentaEnabled == 1 && mentaMarketplace && mentaMarketplace.buttonVisible; 1797 1798 if (hasMentaOption) { 1799 var availableCount = parseInt(mentaMarketplace.totalCount, 10); 1800 if (!isNaN(availableCount) && availableCount > 0) { 1801 aggregatedMentaInfo.totalCount += availableCount; 1802 } 1803 if (mentaMarketplace.buttonText && aggregatedMentaInfo.buttonText === "") { 1804 aggregatedMentaInfo.buttonText = mentaMarketplace.buttonText; 1805 } 1806 if (mentaMarketplace.buttonUrl && aggregatedMentaInfo.buttonUrl === "") { 1807 aggregatedMentaInfo.buttonUrl = mentaMarketplace.buttonUrl; 1808 } 1809 aggregatedMentaInfo.buttonVisible = true; 1810 dateSoldOut = false; 1811 showPhoneNumber=false; 1812 customStatus=true; 1813 } 1814 } 1815 1816 // If date is sold out or custom status (not 'on sale'), check if qualifier access code or password match 1817 if (dateSoldOut || customStatus) { 1818 if (currentPerformance.acMatch == 1 || (currentPerformance.qualifierPasswordMatch == 1 && currentPerformance.hasQualifierPassword == 1)) { 1819 dateSoldOut = false; 1820 customStatus = false; 1821 performanceOnSale = true; 1822 showPhoneNumber = false; 1823 } 1824 } 1825 // If date is sold out or custom status (not 'on sale'), check if it has a public qualifier -- hasQualifiers is set on CalendarRequests.asp when qualifiers exist for performance 1826 if (currentPerformance.hasQualifiers) { 1827 dateSoldOut = false; 1828 customStatus = false; 1829 performanceOnSale = true; 1830 showPhoneNumber = false; 1831 QualiferButton = true; 1832 // If performance has qualifier but status is "On Sale", do not show "Premium Access" text on calendar date 1833 if (currentPerformance.status == "On Sale") { 1834 QualiferButton = false; 1835 } 1836 1837 } 1838 }) 1839 1840 if (aggregatedMentaInfo.buttonVisible && aggregatedMentaInfo.buttonText === "") { 1841 aggregatedMentaInfo.buttonText = "Official Resale Available"; 1842 } 1843 var hasMentaCtaForDate = aggregatedMentaInfo.buttonVisible && (aggregatedMentaInfo.totalCount > 0 || aggregatedMentaInfo.buttonUrl !== ""); 1844 isMentaResaleAvailable = hasMentaCtaForDate && !performanceOnSale; 1845 d.MentaMarketplace = aggregatedMentaInfo; 1846 1847 if(dateLimitedAvailability && !dateSoldOut){ 1848 thisCalendar.setDayLimitedAvailabilty(d.date); 1849 } 1850 if (thisCalendar.isMultiplePerformanceIndicator == 1 && performanceTimesLength > 1) { 1851 thisCalendar.setMultiplePerformanceTimes(d.date); 1852 } 1853 if ( IsSalesPeriodEnded) { 1854 performanceStatus=d.SaleIcon; 1855 } 1856 else{ 1857 if(isMentaResaleAvailable && !performanceOnSale){ 1858 1859 thisCalendar.addDateSubNote(d.date, 'Sold Out'); 1860 //thisCalendar.setDaySoldOut(d.date); 1861 //thisCalendar.addDateInfoBox(d.date, "Sold Out"); 1862 thisCalendar.configureMentaSettings(d); 1863 } 1864 else{ 1865 performanceStatus=d.BSaleIcon; 1866 } 1867 1868 } 1869 1870 if (performanceStatus == null || performanceStatus == "") 1871 performanceStatus="sold out"; 1872 1873 if(dateSoldOut){ 1874 thisCalendar.setDaySoldOut(d.date); 1875 }else{ 1876 if ( (customStatus && !dateLimitedAvailability && !performanceOnSale && !isMentaResaleAvailable) || IsSalesPeriodEnded) 1877 { 1878 thisCalendar.setcustomStatus(d.date,showPhoneNumber,performanceStatus) 1879 } 1880 else{ 1881 //date not sold out, add details, add to legend if one exists 1882 var detailString = ""; 1883 1884 // if the price option is checked in event landing page in the admin 1885 if(d.CalendarViewShowPrice != 0){ 1886 //for now, we'll just add the pricing, this would be a spot to modify what is displayed on the dates by changing the contents of this string 1887 if(d.defaultPrice != null){ 1888 if (QualiferButton) { // SHOWDEV-22142 - If date has public qualifier, show qualifier text (Premium Access) instead of price and buy button 1889 detailString = detailString + "<span class='display-perfbuybutton'>Premium Access</span>"; 1890 }else { 1891 1892 detailString = "<span class='display-perfprice'>" + thisCalendar.currencySymbol + d.defaultPrice.toFixed(2).replace('.00','') + "</span>"; 1893 1894 } 1895 1896 if(defaultPricingLegend.indexOf(d.defaultPricingCode) === -1) 1897 defaultPricingLegend.push(d.defaultPricingCode); 1898 } 1899 if(d.secondaryPricingCode != "" && d.secondaryPricingCode != null){ 1900 if(secondaryPricingLegend.indexOf(d.secondaryPricingCode) === -1) 1901 secondaryPricingLegend.push(d.secondaryPricingCode); 1902 1903 if (d.DisplayType === "calendar" || d.DisplayType === "streamlined") { 1904 1905 detailString = "<span class='display-perfprice-withchild'>" + thisCalendar.currencySymbol + d.secondaryPrice.toFixed(2).replace('.00','') + "/</span>" + detailString; 1906 1907 } 1908 } 1909 } 1910 if(d.CalendarViewShowPerformanceName != 0){ 1911 detailString = detailString + "<span class='display-perfname'>" + d.PerformanceName + "</span> "; 1912 } 1913 1914 if(d.CalendarViewShowPerformanceTime != 0){ 1915 if(d.PerformanceStartTimeAlias != ""){ // Performance Alias time is present 1916 detailString = detailString + " <span class='display-perft
1916ime'>" + d.PerformanceStartTimeAlias + "</span>"; 1917 } else { 1918 detailString = detailString + " <span class='display-perftime'>" + d.PerformanceTime + "</span>"; 1919 } 1920 1921 } 1922 if(d.CalendarViewShowBuyButton != 0){ 1923 var styleString = ""; 1924 if (d.DisplayType === "streamlined") 1925 styleString = " style='width: 100%;'"; 1926 var buttonText = (isMentaResaleAvailable && d.OverrideBuyTicketsButtonText) ? d.OverrideBuyTicketsButtonText : thisCalendar.buyTicketsButtonText; 1927 detailString = detailString + "<span class='button display-perfbuybutton'"+styleString+">" + buttonText + "</span>"; 1928 } 1929 1930 thisCalendar.addDateInfoBox(d.date, detailString); 1931 } 1932 } 1933 1934 }) 1935 //for now, we only generate the legend if there are one or two prices pesent 1936 if(defaultPricingLegend.length === 1 && secondaryPricingLegend.length === 1){ 1937 $("#calendarLegend").html(secondaryPricingLegend[0] +" / " + defaultPricingLegend[0]) 1938 1939 $("#calendarLegend").show(); 1940 }else{ 1941 if(defaultPricingLegend.length === 1){ 1942 $("#calendarLegend").html(defaultPricingLegend[0]) 1943 1944 $("#calendarLegend").show(); 1945 }else{ 1946 $("#calendarLegend").hide(); 1947 } 1948 } 1949 if(typeof(setFilterOptions) == 'function'){ 1950 setFilterOptions(thisCalendar); 1951 } 1952 if (detailData.hasValidCoupon) { 1953 $("#plCalendar").append("<input type='hidden' id='hasValidCoupon' value='1' />"); 1954 } else { 1955 $("#plCalendar").append("<input type='hidden' id='hasValidCoupon' value='0' />"); 1956 } 1957 $(".calendar-loading").hide(); 1958} 1959swDatepicker.prototype.configureMentaSettings = function (dateDetail) { 1960 // Set Menta Resale Settings 1961 1962} 1963 1964swDatepicker.prototype.getFirstDate = function(defaultMonth){ 1965 var thisCalendar = this; 1966 //this should only happen once on calendar load - currently only enabled for bundles 1967 if(thisCalendar.bundleID == 0 || thisCalendar.bundleID == -1) 1968 return defaultMonth; //currently only developed for bundles TODO: add event, category, standard support. 1969 1970 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 1971 { 1972 action: 'initialBundleDate', 1973 iBundle: thisCalendar.bundleID, 1974 cp : thisCalendar.corporatePartnerPage 1975 }) 1976 .done(function (data) { 1977 try { 1978 if (data.performancedates.length > 0) { 1979 1980 1981 var firstMonth = Number(String(data.performancedates).split("/")[0]) - 1; 1982 var firstYear = Number(String(data.performancedates).split("/")[2]); 1983 thisCalendar.month = firstMonth - 1; //to make this simple, we're using the showNextMonth() function, which means we need to set the month to 1 less than our target, as that function increments the month itself 1984 thisCalendar.year = firstYear; 1985 thisCalendar.showNextMonth(); 1986 }else{ 1987 return defaultMonth; 1988 } 1989 }catch(e){ 1990 console.log("getFirstDate returned invalid date. Default used"); 1991 console.log(e); 1992 return defaultMonth; 1993 } 1994 }) 1995 .fail(function (jqxhr, textStatus, error) { 1996 var err = textStatus + ", " + error; 1997 console.log("Request Failed: " + err); 1998 }); 1999} 2000swDatepicker.prototype.fetchLocalDates = function () { 2001 //utliize storage to store months 2002 var CalendarExpireTime = new Date().getTime(); var isExpired = false; var datesData = ""; 2003 var calendarIDString = this.calendarName + this.type + this.eventID + this.bundleID + "-" + this.corporatePartnerPage + "_" + this.activeMonth; 2004 try { 2005 //check for local storage support 2006 isExpired = CalendarExpireTime > Number(localStorage.getItem("CalendarExpireTime_" + calendarIDString)); 2007 if (isExpired) { 2008 //item expired, clear local results 2009 localStorage.setItem("ShowareDates_" + calendarIDString, ""); 2010 localStorage.setItem("CalendarExpireTime_" + calendarIDString, CalendarExpireTime + (1000 * 60 * 30)); //item information expires after 30 minutes 2011 return false; 2012 } 2013 localStorage.setItem("CalendarExpireTime_" + calendarIDString, CalendarExpireTime + (1000 * 60 * 30)); //item information expires after 30 minutes 2014 if (localStorage.getItem("ShowareDates_" + calendarIDString) != null && localStorage.getItem("ShowareDates_" + calendarIDString) != "" && localStorage.getItem("ShowareDates_" + calendarIDString) != []) { 2015 return localStorage.getItem("ShowareDates_" + calendarIDString); 2016 } else { 2017 //date info not stored 2018 return false; 2019 } 2020 } catch (e) { 2021 return false; 2022 } 2023} 2024swDatepicker.prototype.storeDates = function (dateData) { 2025 2026 var calendarIDString = this.calendarName + this.type + this.eventID + this.bundleID + "-" + this.corporatePartnerPage + "_" + this.activeMonth; 2027 try { 2028 localStorage.setItem("ShowareDates_" + calendarIDString, JSON.stringify(dateData)); 2029 } catch (e) { 2030 //no local storage 2031 } 2032} 2033swDatepicker.prototype.getDateRangeEvents = function (dateRangeData) { 2034 var thisCalendar = this; 2035 try{ 2036 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 2037 { 2038 action: 'getDateRangeEvents', 2039 dateRange: JSON.stringify(dateRangeData), 2040 }) 2041 .done(function (data) { 2042 try { 2043 thisCalendar.dateRangeEvents = data; 2044 }catch(e){ 2045 console.log("getDateRangeEvents returned invali
2045d response."); 2046 console.log(data, e); 2047 return []//return empty array; 2048 } 2049 }) 2050 .fail(function (jqxhr, textStatus, error) { 2051 var err = textStatus + ", " + error; 2052 console.log("Request Failed: " + err); 2053 }); 2054 2055 }catch(e){ 2056 console.log("Unable to fetch date range events:", e) 2057 } 2058} 2059swDatepicker.prototype.clearDateRange = function () { 2060 this.fromDateRange = ''; 2061 this.toDateRange = ''; 2062} 2063function fetchDateIndex(dateString, dateObjectArray){ 2064 try{ 2065 for(var i = 0;i < dateObjectArray.length;i++){ 2066 if(dateObjectArray[i].date == dateString){ 2067 return i; 2068 break; 2069 } 2070 } 2071 return -1; 2072 }catch(e){ 2073 //this function requires specific objects with a date property, it will fail otherwise and we'll just return what one would expect from a failed indexof 2074 return -1; 2075 } 2076} 2077function swapMonthDay(d){ 2078 //expects dd/mm/yyyy format 2079 try{ 2080 let splitDate = d.split("/"); 2081 let newDate = splitDate[1] + '/' + splitDate[0] + "/" + splitDate[2]; 2082 return newDate; 2083 }catch(e){ 2084 console.log("could not swap date:",d,e); 2085 return d; 2086 } 2087} 2088 2089</script>
2089 2090
2090<script type="text/javascript"> 2091 if (typeof localStorage === 'object') { 2092 try { 2093 localStorage.setItem('localStorage', 1); 2094 localStorage.removeItem('localStorage'); 2095 } catch (e) { 2096 Storage.prototype._setItem = Storage.prototype.setItem; 2097 Storage.prototype.setItem = function () { }; 2098 console.log("local storage not availalbe, data tracking limited"); 2099 } 2100 } 2101 function persistDataLayer(layerName, pageVal) { 2102 var ShoWareExpTime = new Date().getTime(); var isExpired = false; 2103 2104 try { 2105 isExpired = ShoWareExpTime > Number(localStorage.getItem("swExpTime")); 2106 if (isExpired) { 2107 removeDataLayer(); 2108 } 2109 localStorage.setItem("swExpTime", ShoWareExpTime + 1000 * 60 * 30); //tag information expires after 30 minutes of inactivity 2110 2111 //grab anything we might have in storage= 2112 var existVal = localStorage.getItem(layerName); 2113 if (pageVal != "") { 2114 //page val trumps all, store it and send it back 2115 localStorage.setItem(layerName, pageVal); 2116 return pageVal; 2117 } else { 2118 //page val was empty, so we'll try to pull a value out of local storage 2119 if (existVal != "" && existVal != null && existVal != undefined && !isExpired) { 2120 return existVal; 2121 } else { 2122 //no value exists, or the values stored have expired; 2123 return ""; 2124 } 2125 } 2126 } catch(e) { 2127 //no local storage, or other error, we'll just return the page value. Calls to this function should assume the possibility of failure as local storage does not work on IOS devices with private browsing enabled. 2128 return pageVal; 2129 } 2130 } 2131 function addDataLayer(layerName, setVal) { 2132 try { 2133 //the data layer MUST be set up before the container is introduced. 2134 //We will rely on future loads to address these variables as they are added after the pageload. 2135 localStorage.setItem(layerName, setVal); 2136 //push data to dataLayer so we can retrieve it with non-load events (clicks, changes, etc...) 2137 dataLayer.push({[layerName]: setVal}); 2138 } 2139 catch (e) { 2140 //local storage failed, or the data layer was not available. 2141 } 2142 } 2143 function removeDataLayer() { 2144 //empty showare data layer from local storage. 2145 for (var i = localStorage.length - 1; i >= 0; i--) { 2146 layerName = localStorage.key(i); 2147 if (layerName.indexOf("Ticketing") > -1) { 2148 localStorage.removeItem(layerName); 2149 } 2150 } 2151 } 2152 function tryParse(jsonString) { 2153 if (jsonString == "" || jsonString == null || jsonString == undefined) { 2154 return ''; 2155 } 2156 try { 2157 JSON.parse(jsonString); 2158 } catch (e) { 2159 console.log(e); 2160 return ''; 2161 } 2162 return JSON.parse(jsonString); 2163 } 2164 </script>
2164 2165 2166
2166<script> 2167 window.dataLayer = window.dataLayer || []; 2168 dataLayer.push({ 2169 'TicketingHasActivePerformances': 'True', 2170 'TicketingPage': '/default.asp', 2171 'TicketingEventID': persistDataLayer("TicketingEventID", ""), 2172 'TicketingBundleID': persistDataLayer("TicketingBundleID", ""), 2173 'TicketingPerformanceID': persistDataLayer("TicketingPerformanceID", ""), 2174 'TicketingPerformanceCode': persistDataLayer("TicketingPerformanceCode", ""), 2175 'TicketingPerformanceDate': persistDataLayer("TicketingPerformanceDate", ""), 2176 'TicketingOrderID': persistDataLayer("TicketingOrderID", "0"), 2177 'TicketingNewCustomer': persistDataLayer("TicketingNewCustomer", ""), 2178 'TicketingCustomerID': "", 2179 'TicketingCustomerZipCode': persistDataLayer("TicketingCustomerZipCode", ""), 2180 'TicketingCustomerState': persistDataLayer("TicketingCustomerState", ""), 2181 'TicketingCustomerCountry': persistDataLayer("TicketingCustomerCountry", ""), 2182 'TicketingCustomerCity': persistDataLayer("TicketingCustomerCity", ""), 2183 'TicketingCurrencyCode': persistDataLayer("TicketingCurrencyCode", "USD"), 2184 'TicketingOrderTotal': persistDataLayer("TicketingOrderTotal", ""), 2185 'TicketingCoupon': persistDataLayer("TicketingCoupon", ""), 2186 'TicketingPromo': persistDataLayer("TicketingPromo", ""), 2187 'TicketingDiscountAmount': persistDataLayer("TicketingDiscountAmount", ""), //promo code dicount value only 2188 'TicketingHasMixedBasket': persistDataLayer("TicketingHasMixedBasket", ""), 2189 'TicketingOrderSubTotal': persistDataLayer("TicketingOrderSubTotal", ""), 2190 'TicketingItemCount': persistDataLayer("TicketingItemCount", ""), 2191 'TicketingBundleCount': persistDataLayer("TicketingBundleCount", ""), 2192 'TicketingShippingMethod': persistDataLayer("TicketingShippingMethod", ""), 2193 'TicketingIsWillCall': persistDataLayer("TicketingIsWillCall", ""), 2194 'TicketingHeardAbout': persistDataLayer("TicketingHeardAbout", ""), 2195 'TicketingShippingTotal': persistDataLayer("TicketingShippingTotal", ""), 2196 'TicketingTaxTotal': persistDataLayer("TicketingTaxTotal", ""), 2197 'TicketingFeesTotal': persistDataLayer("TicketingFeesTotal", ""), 2198 'TicketingProcessingFee': persistDataLayer("TicketingProcessingFee", ""), 2199 'TicketingTicketFeesTotal': persistDataLayer("TicketingTicketFeesTotal", ""), 2200 'TicketingTicketItems': persistDataLayer("TicketingTicketItems", ""), 2201 'TicketingDonationItems': persistDataLayer("TicketingDonationItems", ""), 2202 'TicketingMembershipItems': persistDataLayer("TicketingMembershipItems", ""), 2203 'TicketingSalesChannel': persistDataLayer("TicketingSalesChannel", ""), 2204 'TicketingPaymentType': persistDataLayer("TicketingPaymentType", ""), 2205 'TicketingEventName': persistDataLayer("TicketingEventName", ""), 2206 'TicketingPerformanceName': persistDataLayer("TicketingPerformanceName", ""), 2207 'TicketingBundleName': persistDataLayer("TicketingBundleName", ""), 2208 'TicketingPromoterID': persistDataLayer("TicketingPromoterID", ""), 2209 'TicketingEventCategories': persistDataLayer("TicketingEventCategories", ""), 2210 'GAClientID': persistDataLayer("GAClientID", ""), 2211 'transactionId': 0, 2212 'transactionTotal': parseFloat(persistDataLayer("transactionTotal", "")), 2213 'transactionAffiliation' : 'CincyTicket', 2214 'transactionTax': parseFloat(persistDataLayer("transactionTax", "")), 2215 'transactionShipping': parseFloat(persistDataLayer("transactionShipping", "")), 2216 'transactionProducts': tryParse(persistDataLayer("transactionProducts", "")) 2217 }); 2218 if(typeof(customDataLayerPush) === "function"){ 2219 customDataLayerPush(); //custom function can be defined in local files and values pushed prior to GTM loading to simplify tag implimentation 2220 } 2221 </script>
2221 2222 2223 <!-- CLIENT Google Tag Manager --> 2224
2224<script>
vendor: 373 bytes, lines 2224-2228
2224(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 2225 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 2226 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 2227 '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 2228 })(window,document,'script','dataLayer','
2228GTM-WZ8HC5
vendor: 3 bytes, line 2228
2228');
2228</script>
2228 2229 <!-- End CLIENT Google Tag Manager --> 2230 2231 <!-- PRIMARY Google Tag Manager --> 2232
2232<script>
vendor: 389 bytes, lines 2232-2236
2232(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 2233 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 2234 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 2235 '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 2236 })(window,document,'script','dataLayer','
2236GTM-MDGF2K
vendor: 3 bytes, line 2236
2236');
2236</script>
2236 2237 <!-- End PRIMARY Google Tag Manager --> 2238 2239 2240 2241
2241<script type="text/javascript"> 2242 var simpleCacheBuster = { 2243 beforeLength: 0, 2244 afterLength: 0 2245 }; 2246 2247 simpleCacheBuster.beforeLength = document.cookie.length; 2248 simpleCacheBuster.afterLength = document.cookie.replace("ShowareVersion=newUI", " ").length; 2249 2250 // If length is the same, then we haven't set this version cookie before, clear the cache. 2251 // If after length is smaller, then we have replaced the same version, do nothing. 2252 // After length shouldn't be greater, do nothing. 2253 if (simpleCacheBuster.beforeLength == simpleCacheBuster.afterLength) { 2254 document.cookie = "ShowareVersion=newUI"; 2255 2256 // This will force browser to reload all includes from server instead of cache. 2257 // Sadly, this doesn't work on Chrome due to a bug that they refuse to fix. 2258 // https://bugs.chromium.org/p/chromium/issues/detail?id=443462 2259 location.reload(true); 2260 } 2261 </script>
2261 2262 2263
2263<script language="JavaScript"> 2264 $(document).ready(function () { 2265 var sessionKey; 2266 sessionKey = ''; 2267 //v1Session variable declared in jq.js 2268 v1Session.setSessionKey(sessionKey); 2269 }); 2270 2271 </script>
2271 2272
2272<script type="text/javascript"> 2273 /* 2274 * Replace all SVG images with inline SVG - allows for image modificcation via CSS 2275 */ 2276 function extractIcons() { 2277 $('img.sw-icon').each(function () { 2278 var $img = $(this); 2279 var imgID = $img.attr('id'); 2280 var imgClass = $img.attr('class'); 2281 var imgURL = $img.attr('src'); 2282 2283 $.get(imgURL, function (data) { 2284 // Get the SVG tag, ignore the rest 2285 var $svg = jQuery(data).find('svg'); 2286 2287 // Add replaced image's ID to the new SVG 2288 if (typeof imgID !== 'undefined') { 2289 $svg = $svg.attr('id', imgID); 2290 } 2291 // Add replaced image's classes to the new SVG 2292 if (typeof imgClass !== 'undefined') { 2293 $svg = $svg.attr('class', imgClass + ' replaced-svg'); 2294 } 2295 // Remove any invalid XML tags as per http://validator.w3.org 2296 $svg = $svg.removeAttr('xmlns:a'); 2297 // Replace image with new SVG 2298 $img.replaceWith($svg); 2299 }, 'xml'); 2300 }); 2301 } 2302 </script>
2302 2303
2303<script type="text/javascript"> 2304 function getGAClientID() { 2305 try { 2306 return ga.getAll()[0].get('clientId'); 2307 } catch (e) { 2308 return "0"; 2309 } 2310 } 2311 function addGAClient(){ 2312 var gaID = getGAClientID(); 2313 if(gaID == "0"){ 2314 //no analytics (unlikely), or analytics not loaded yet 2315 setTimeout(function(){addGAClient()}, 500); 2316 }else{ 2317 try{ 2318 addDataLayer('GAClientID', gaID); 2319 }catch(e){ 2320 console.log("Failed to add data layer object: GAClientID:"); 2321 console.log(e); 2322 } 2323 } 2324 } 2325 addGAClient(); 2326 2327 </script>
2327 2328 2329 2330 2331 <!-- Comodo SSL Seal --> 2332 2333
2333<script type="text/javascript"> 2334 //<![CDATA[ 2335 var tlJsHost = ((window.location.protocol == "https:") ? "https://secure.comodo.com/" : "http://www.trustlogo.com/"); document.write(unescape("%3Cscript src='" + tlJsHost + "trustlogo/javascript/trustlogo.js' type='text/javascript'%3E%3C/script%3E")); 2336 //]]> 2337 </script>
2337 2338 2339
2340<script type="text/javascript"> 2341 2342 var swEnhancedEcommerce = { 2343 basketProducts: [], 2344 myImpressions: [], 2345 myProducts: [], 2346 2347 //Building Up items to pass to analytics 2348 addImpressions: function (name, id, price, category, list, position) { 2349 //adds a product impression to myImpressions - represents a user being presented a specific product 2350 if (price != '') { //price is optional 2351 this.myImpressions.push( 2352 { 2353 'name': name, // Name or ID is required. 2354 'id': id, 2355 'price': price, 2356 'category': category, 2357 'list': list, 2358 'position': position 2359 } 2360 ); 2361 } else { 2362 this.myImpressions.push( 2363 { 2364 'name': name, // Name or ID is required. 2365 'id': id, 2366 'category': category, 2367 'list': list, 2368 'position': position 2369 } 2370 ); 2371 } 2372 }, 2373 2374 addProducts: function (name, id, price, category, position) { 2375 //product clicks represent a product being selected. For showare currently this will always be a single product, but future use may require allowing users to select multiple products 2376 //this represents a click on a product, NOT adding a product to the basket 2377 if (price != '') { //price is optional 2378 2379 this.myProducts.push( 2380 { 2381 'name': name, // Name or ID is required. 2382 'id': id, 2383 'price': price, 2384 'category': category, 2385 'position': position 2386 } 2387 ); 2388 } else { 2389 this.myProducts.push( 2390 { 2391 'name': name, // Name or ID is required. 2392 'id': id, 2393 'category': category, 2394 'position': position 2395 } 2396 ); 2397 } 2398 }, 2399 2400 //object management functions 2401 clearImpressions: function(){ 2402 this.myImpressions = []; 2403 }, 2404 clearProducts: function () { 2405 this.myProducts = []; 2406 }, 2407 2408 //Passing data to analytics 2409 sendImpressions: function(){ 2410 window.dataLayer.push({ 2411 'event': 'impressionsPushed', 2412 'ecommerce': { 2413 'impressions': this.myImpressions 2414 } 2415 }); 2416 }, 2417 sendProducts: function (list) { 2418 //list should be a string of the originator of the product click, for instance a performance list, event list, callout, or other 2419 window.dataLayer.push({ 2420 'event': 'productClick', 2421 'ecommerce': { 2422 'click': { 2423 'actionField': { 'list': list }, // Optional list property. 2424 'products': this.myProducts 2425 } 2426 } 2427 }); 2428 }, 2429 sendDetails: function (name, id, category) { 2430 //tracks a user's view of product details 2431 window.dataLayer.push({ 2432 'event': 'detailView', 2433 'ecommerce': { 2434 'detail': { 2435 'products': [{ 2436 'name': name, // Name or ID is required. 2437 'id': id, 2438 'category': category, 2439 }] 2440 } 2441 } 2442 }); 2443 }, 2444 2445 sendAddToBasket: function(){ 2446 var newAddedProducts = this.compareBasketProducts(this.basketProducts); 2447 if (newAddedProducts.length === 0) { 2448 return; 2449 } 2450 console.log("added items to basket:", newAddedProducts); 2451 //REQUIRES basketProducts populated via fetchBasketProducts or directly 2452 window.dataLayer.push({ 2453 'event': 'addToCart', 2454 'ecommerce': { 2455 'add': { // 'add' actionFieldObject measures. 2456 'products': newAddedProducts // adding a product to a shopping cart. 2457 } 2458 } 2459 }); 2460 }, 2461 2462 sendAddItemToBasket: function(name, id, price, category, quantity){ 2463 //REQUIRES basketProducts populated via fetchBasketProducts or directly 2464 window.dataLayer.push({ 2465 'event': 'addToCart', 2466 'ecommerce': { 2467 'add': { // 'add' actionFieldObject measures. 2468 'products': [{ // removing a product to a shopping cart. 2469 'name': name, 2470 'id': id, 2471 'price': price, 2472 'category': category, 2473 'quantity': quantity 2474 }] 2475 } 2476 } 2477 }); 2478 }, 2479 2480 sendRemoveFromBasket: function (name, id, price, category, quantity, doUpdate) { 2481 //the item should be removed from the actual basket before this is called, as the basket is updated immediately 2482 window.dataLayer.push({ 2483 'event': 'removeFromCart', 2484 'ecommerce': { 2485 'remove': { // 'remove' actionFieldObject measures. 2486 'products': [{ // removing a product to a shopping cart. 2487 'name': name, 2488 'id': id, 2489 'price': price, 2490 'category': category, 2491 'quantity': quantity 2492 }] 2493 } 2494 } 2495 }); 2496 if (doUpdate) { 2497 this.fetchBasketProducts(); 2498 } 2499 }, 2500 2501 sendRemoveAllFromBasket: function () { 2502 //the item should be removed from the actual basket before this is called, as the basket is updated immediately 2503 window.dataLayer.push({ 2504 'event': 'removeFromCart', 2505 'ecommerce': { 2506 'remove': { // 'remove' actionFieldObject measures. 2507 'products': this.basketProducts 2508 } 2509 } 2510 }); 2511 this.basketProducts = []; 2512 localStorage.removeItem('swAddedBasketProducts'); 2513 }, 2514 2515 //method to fetch basket - we should only call this if we intend to send products to analytics 2516 fetchBasketProducts: function (type, orderID, doAddToCartAfter) { 2517 if (typeof type === 'undefined') type = 'basket'; //defaults to grabbing basket items 2518 if (typeof orderID === 'undefined') orderID = 0; 2519 doAddToCartAfter = doAddToCartAfter || false; 2520 var fetchURL = "include/modules/enhancedEcommerceBasket.asp?type=" + type + "&orderid=" + orderID; 2521 2522 try { 2523 $.ajax({
2524 context: this, 2525 url: fetchURL 2526 }) 2527 .done(function (data) { 2528 //note that we'll only have basket details if this method is called. Functions like sendAddToBasket, and sendPurchase will not function if this method has not completed. 2529 try{ 2530 this.basketProducts = JSON.parse(data); 2531 } catch (e) { 2532 console.log(e); 2533 this.basketProducts = []; 2534 } 2535 //try to update the data layer with the most current products 2536 try{ 2537 addDataLayer("TicketingTicketItems",data); 2538 } catch (e){ 2539 console.log(e); 2540 } 2541 if(doAddToCartAfter){ 2542 this.sendAddToBasket(); 2543 } 2544 }); 2545 //grab the basket and store contents 2546 } catch (e) { 2547 console.log(e); 2548 return 2549 } 2550 }, 2551 2552 sendOrder: function (orderID, orderTotal, taxFees, shippingFees, couponCodes, orderCode) { 2553 var fetchURL = "include/modules/enhancedEcommerceBasket.asp?type=order&orderid=" + orderID + "&orderCode=" + orderCode; 2554 orderProducts = []; 2555 2556 try { 2557 $.ajax({
2558 context: this, 2559 url: fetchURL 2560 }) 2561 .done(function (data) { 2562 //note that we'll only have basket details if this method is called. Functions like sendAddToBasket, and sendPurchase will not function if this method has not completed. 2563 try { 2564 orderProducts = JSON.parse(data); 2565 } catch (e) { 2566 console.log(e); 2567 orderProducts = []; 2568 } 2569 dataLayer.push({ 2570 'event': 'purchaseMade', 2571 'ecommerce': { 2572 'purchase': { 2573 'actionField': { 2574 'id': orderID, // Transaction ID. Required for purchases and refunds. 2575 'affiliation': 'Online Ticketing', 2576 'revenue': orderTotal, // Total transaction value (incl. tax and shipping) 2577 'tax': taxFees, 2578 'shipping': shippingFees, 2579 'coupon': couponCodes 2580 }, 2581 'products': orderProducts 2582 } 2583 } 2584 }); 2585 }); 2586 //grab the basket and store contents 2587 } catch (e) { 2588 console.log(e); 2589 return 2590 } 2591 2592 2593 }, 2594 2595 // -------------------------------------------- CHECKOUT STEPS -------------------------------------------- 2596 // 1. Basket Page "Checkout" Clicked 2597 // 2. login/guest/create 2598 // 3. Streamlined - select shipping method 2599 // 4. Streamlined - enter payment information 2600 // 5. Streamlined - complete clicked 2601 // 6. view order 2602 sendCheckoutStep: function(stepID, option){ 2603 dataLayer.push({ 2604 'event': 'checkout', 2605 'ecommerce': { 2606 'checkout': { 2607 'actionField': { 'step': stepID, 'option': option }, 2608 'products': this.basketProducts 2609 } 2610 } 2611 }); 2612 }, 2613 sendViewPromotion: function(promotionItems){ 2614 //promotion items should be an array of promotion items 2615 dataLayer.push({ 2616 'event': 'view_promotion', 2617 'ecommerce': { 2618 'items': promotionItems 2619 } 2620 }); 2621 console.log("sent promotions"); 2622 console.log(promotionItems); 2623 }, 2624 sendSelectPromotion: function(promotionItems){ 2625 //promotion items should be an array of promotion items 2626 dataLayer.push({ 2627 'event': 'select_promotion', 2628 'ecommerce': { 2629 'items': promotionItems 2630 } 2631 }); 2632 console.log("selected promotions"); 2633 console.log(promotionItems); 2634 }, 2635 2636 getStoredAddedBasketProducts: function () { 2637 if (typeof localStorage === 'undefined') { 2638 return []; 2639 } 2640 try { 2641 var storedRaw = localStorage.getItem('swAddedBasketProducts'); 2642 if (!storedRaw) { 2643 return []; 2644 } 2645 var parsed = JSON.parse(storedRaw); 2646 return Array.isArray(parsed) ? parsed : []; 2647 } catch (e) { 2648 console.log(e); 2649 return []; 2650 } 2651 }, 2652 cloneBasketProduct: function (product) { 2653 if (!product || typeof product !== 'object') { 2654 return product; 2655 } 2656 var clone = {}; 2657 for (var prop in product) { 2658 if (Object.prototype.hasOwnProperty.call(product, prop)) { 2659 clone[prop] = product[prop]; 2660 } 2661 } 2662 return clone; 2663 }, 2664 cloneBasketProducts: function (source) { 2665 var cloned = []; 2666 if (!Array.isArray(source)) { 2667 return cloned; 2668 } 2669 for (var i = 0; i < source.length; i++) { 2670 cloned.push(this.cloneBasketProduct(source[i])); 2671 } 2672 return cloned; 2673 }, 2674 buildBasketProductSignature: function (product) { 2675 if (!product || typeof product !== 'object') { 2676 return ''; 2677 } 2678 var keys = Object.keys(product).sort(); 2679 var normalized = {}; 2680 for (var i = 0; i < keys.length; i++) { 2681 var key = keys[i];
2682 normalized[key] = product[key]; 2683 } 2684 try { 2685 return JSON.stringify(normalized); 2686 } catch (e) { 2687 console.log(e); 2688 return ''; 2689 } 2690 }, 2691 persistAddedBasketProducts: function (products) { 2692 if (typeof localStorage === 'undefined') { 2693 return; 2694 } 2695 try { 2696 localStorage.setItem('swAddedBasketProducts', JSON.stringify(this.cloneBasketProducts(products))); 2697 } catch (e) { 2698 console.log(e); 2699 } 2700 }, 2701 storeAddedBasketProducts: function(basketProducts) { 2702 this.compareBasketProducts(basketProducts); 2703 }, 2704 compareBasketProducts: function(basketProducts, options){ 2705 var opts = options || {}; 2706 var products = Array.isArray(basketProducts) ? basketProducts : []; 2707 if (typeof localStorage === 'undefined') { 2708 return opts.returnCombined ? { unmatched: products, combined: this.cloneBasketProducts(products) } : products; 2709 } 2710 2711 var storedProducts = this.getStoredAddedBasketProducts(); 2712 var storedCounts = {}; 2713 for (var i = 0; i < storedProducts.length; i++) { 2714 var storedSignature = this.buildBasketProductSignature(storedProducts[i]); 2715 if (storedSignature) { 2716 storedCounts[storedSignature] = (storedCounts[storedSignature] || 0) + 1; 2717 } 2718 } 2719 2720 var unmatchedProducts = []; 2721 var combinedProducts = this.cloneBasketProducts(storedProducts); 2722 var pendingCounts = {}; 2723 2724 for (var j = 0; j < products.length; j++) { 2725 var product = products[j]; 2726 var productSignature = this.buildBasketProductSignature(product); 2727 2728 if (!productSignature) { 2729 unmatchedProducts.push(product); 2730 combinedProducts.push(this.cloneBasketProduct(product)); 2731 continue; 2732 } 2733 2734 var alreadyTracked = pendingCounts[productSignature] || 0; 2735 var existingCount = storedCounts[productSignature] || 0; 2736 2737 if (alreadyTracked < existingCount) { 2738 pendingCounts[productSignature] = alreadyTracked + 1; 2739 } else { 2740 unmatchedProducts.push(product); 2741 pendingCounts[productSignature] = alreadyTracked + 1; 2742 combinedProducts.push(this.cloneBasketProduct(product)); 2743 } 2744 } 2745 2746 if (opts.persist !== false) { 2747 this.persistAddedBasketProducts(combinedProducts); 2748 } 2749 2750 if (opts.returnCombined) { 2751 return { unmatched: unmatchedProducts, combined: combinedProducts }; 2752 } 2753 2754 return unmatchedProducts; 2755 } 2756 2757 2758 } 2759</script>
2759
2760<script type="text/javascript"> 2761//---------------------------DATEPICKER--------------------------------- 2762function buildDatepicker(options) { 2763 //Calling this function should be sufficient to create a calendar within a designated div, with and 2764 //EX: headerDP = buildDatepicker({"calendarID":"headerCalendar","linkedInputID":"headerCalendarInput","isModal":false,"forceDates":true, "defaultDate": "{{Output date from server Here}}"}); <~ would create a calendar object for the calendar presented at #headerCalendar, and link it to #headerCalendarInput 2765 //most calendar methods are specific to the document the calendar resides on, and should be handled via the onChange event for the linked input 2766 //Available Options: 2767 // calendarID (required) == string, ID of calendar div 2768 // linkedInput (required) == string, ID of input which will change when a date is selected 2769 // isModal == boolean, if true, calendar will be hidden, and display when the designated input recieves focus. If false, the calendar will be present and display as an inline block at all times. 2770 // forceDates == boolean, if true only highlighted dates will be clickable 2771 // detailedCalendar == boolean, if true data is pulled to determine pricing information, sold out days, limited availablility - requires eventID 2772 // defaultDate == string, mm/dd/yyyy date that calendar should start on (this will only represent the month displayed at the begining) 2773 // type == string: defaults to "performancedates", which will add all visible performances 2774 // eventID == integer: defaults to -1 which means no event. Other values will filter by events with that ID, allowing for a search of performance dates for a specific event only 2775 // isMultiplePerformanceIndicator == boolean: if true, shows indicator for dates with multiple performance times 2776 // 2777 //Methods: 2778 // showDlg()/hideDlg() : shows/hides modal calendars, no valid for non-modal calendars 2779 // addHighlightDay(mm/dd/yyyy) : adds a date (presented as a mm/dd/yyyy string) to the list of highlight dates for the calendar - REQUIRES HighlightDays() function call to visually represent this change on the calendar 2780 // clearHihghlightDays() : removes all stored highlight dates 2781 // highlightDays() : adds highlight class to stored days, visually highlighting them ont he calendar. 2782 2783 var myID = options.calendarID; //required 2784 var myLinkedInput = options.linkedInputID; //required 2785 var isModal = options.isModal || false; 2786 var showLoader = options.showLoader || false; 2787 var forceDates = options.forceDates || false; 2788 var myDefault = new Date(); 2789 if (options.defaultDate) { 2790 try{ 2791 2792 myDefault = new Date(options.defaultDate); 2793 } catch (e) { 2794 console.log("date no valid for calendar: " + myID); 2795 console.log(e); 2796 } 2797 } 2798 var type = options.type || "performancedates"; 2799 var eventID = options.eventID || -1; 2800 var detailedCalendar = options.detailedCalendar && eventID != -1 || false; 2801 var bundleID = options.bundleID || -1; 2802 var categoryID = options.CategoryID || -1; 2803 var corporatePartnerPage = options.corporatePartnerPage || 0; 2804 var bValidCoupon = options.bValidCoupon || 0; 2805 var couponCode = options.couponCode || ""; 2806 var isMultiplePerformanceIndicator = options.isMultiplePerformanceIndicatorFlag || 0; 2807 2808 return new swDatepicker(myID, myLinkedInput, isModal, showLoader, forceDates, detailedCalendar, myDefault, type, eventID, bundleID, categoryID, corporatePartnerPage,bValidCoupon,couponCode,isMultiplePerformanceIndicator) 2809} 2810function swDatepicker(id, target, modal, loader, force, detailed, defaultDate, type, eventID, bundleID, categoryID, corporatePartnerPage,bValidCoupon,couponCode,isMultiplePerformanceIndicator) { 2811 2812 this.$id = $('#' + id); // element to attach widget to 2813 this.$monthObj = this.$id.find('.month'); 2814 this.$prev = this.$id.find('.bn_prev'); 2815 this.$next = this.$id.find('.bn_next'); 2816 this.$grid = this.$id.find('.cal'); 2817 this.$target = $('#' + target); // div or text box that will receive the selected date string and focus (if modal) 2818 this.bModal = modal; // true if datepicker should appear in a modal dialog box. 2819 this.showLoader = loader; 2820 this.forceDateSelection = force; //if true, will only allow users to click on highlighted dates - see addHighlightDay() 2821 this.detailedCalendar = detailed; 2822 this.active = !modal; 2823 this.type = type; 2824 this.eventID = eventID; 2825 this.bundleID = bundleID; 2826 this.categoryID = categoryID; 2827 this.corporatePartnerPage = corporatePartnerPage; 2828 this.fromDateRange = ""; 2829 this.toDateRange = ""; 2830 this.dateRangeEvents = []; 2831 this.calendarName = id; 2832 2833 this.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 2834 'July', 'August', 'September', 'October', 'November', 'December']; 2835 2836 this.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; 2837 2838 this.dateObj = new Date(); 2839 2840 this.curYear = this.dateObj.getFullYear(); 2841 this.year = defaultDate.getFullYear(); 2842 2843 this.curMonth = this.dateObj.getMonth(); 2844 this.month = defaultDate.getMonth(); 2845 this.getFirstDate(defaultDate.getMonth()); //update the month to the first performance ASAP 2846 2847 this.curDate = this.dateObj.getDate(); 2848 this.date = defaultDate.getDate(); 2849 this.currentDate = (this.month == this.curMonth && this.year == this.curYear); 2850 this.activeMonth = (String(this.month + 1) + "/1/" + this.year); 2851 2852 this.keys = { 2853 tab: 9, 2854 enter: 13, 2855 esc: 27, 2856 space: 32, 2857 pageup: 33, 2858 pagedown: 34, 2859 end: 35, 2860 home: 36, 2861 left: 37, 2862 up: 38, 2863 right: 39, 2864 down: 40 2865 }; 2866 2867 this.bValidCoupon = bValidCoupon; 2868 this.couponCode = couponCode; 2869 this.isMultiplePerformanceIndicator = isMultiplePerformanceIndicator; 2870 2871 this.highlightDates = []; 2872 2873 // display the current month 2874 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 2875 2876 // populate the calendar grid
2877 this.popGrid(); 2878 2879 // update the table's activedescdendant to point to the current day 2880 this.$grid.attr('aria-activedescendant', this.$grid.find('.today').attr('id')); 2881 2882 this.bindHandlers(); 2883 2884 //show selected day 2885 $('#' + this.calendarName + '-day' + this.date).addClass('focus').attr('aria-selected', 'true'); 2886 2887 // hide dialog if in modal mode 2888 if (this.bModal == true) { 2889 this.$id.attr('aria-hidden', 'true'); 2890 //show/hide functionality may vary based on use, so should be handled after the datepicker is created. 2891 //if we're on mobile, disable keyboard for the input: 2892 if ($(window).width() < 1024) { 2893 this.$target.attr("readonly", "true"); 2894 } 2895 } 2896 2897 this.currencySymbol = "$"; 2898 this.buyTicketsButtonText = "Buy Tickets"; 2899} 2900 2901// 2902// popGrid() is a member function to populate the datepicker grid with calendar days 2903// representing the current month 2904// 2905// @return N/A 2906// 2907swDatepicker.prototype.popGrid = function () { 2908 if(this.showLoader) 2909 $(".calendar-loading").show(); 2910 var numDays = this.calcNumDays(this.year, this.month); 2911 var startWeekday = this.calcStartWeekday(this.year, this.month); 2912 //var lastMonth = this.month - 1; 2913 //var lastMonthYear = this.year; 2914 var weekday = 0; 2915 var curDay = 1; 2916 var rowCount = 1; 2917 var $tbody = this.$grid.find('tbody'); 2918 2919 var currentDateDay = this.dateObj.getDate(); 2920 var currentDateMonth = this.dateObj.getMonth(); 2921 var currentDateYear = this.dateObj.getFullYear(); 2922 2923 var gridCells = '\t<tr id="row1">\n'; 2924 2925 // Keeping in case the client (Gaylord) pushes back on not having previous month's dates selectable 2926 // If the last month is -1, roll it over to December (11) and subtract 1 from the last month's year 2927 /*if (lastMonth < 0) { 2928 lastMonth = 11; 2929 lastMonthYear = lastMonthYear - 1; 2930 } 2931 2932 var lastMonthNumDays = this.calcNumDays(lastMonthYear, lastMonth); 2933 var lastMonthStartDay = lastMonthNumDays - (startWeekday - 1);*/ 2934 2935 // clear the grid 2936 $tbody.empty(); 2937 $('#msg').empty(); 2938 2939 // Keeping in case the client (Gaylord) pushes back on not having previous month's dates selectable 2940 // Insert the leading empty cells 2941 /*for (var weekday = 0; weekday < startWeekday; weekday++) { 2942 gridCells += '\t\t<td id="' + this.calendarName + '-day' + lastMonthStartDay + '" class="day-cell muted last-month" headers="row' + 2943 rowCount + ' ' + this.dayNames[weekday] + '" role="gridcell" aria-selected="false" data-year="' + lastMonthYear + '"><span class="calendar-day notranslate" data-month="' + lastMonth + '">' + lastMonthStartDay + '</span> <span class="calendar-dayoftheweek" style="display: none;">' + this.dayNames[weekday] + '</span></td>'; 2944 //gridCells += '\t\t<td class="empty" data-month="' + lastMonth + '" data-year="' + lastMonthYear + '" data-day="' + lastMonthStartDay + '"> </td>\n'; 2945 lastMonthStartDay++; 2946 }*/ 2947 2948 for (var weekday = 0; weekday < startWeekday; weekday++) { 2949 gridCells += '\t\t<td class="empty"> </td>\n'; 2950 } 2951 2952 // insert the days of the month. 2953 for (curDay = 1; curDay <= numDays; curDay++) { 2954 2955 if (curDay == this.curDate && this.currentDate == true) { 2956 2957 gridCells += '\t\t<td id="' + this.calendarName + '-day' + curDay + '" class="today day-cell" aria-label="row' + 2958 rowCount + ' ' + this.dayNames[weekday] + '" role="gridcell" aria-selected="false"><span class="calendar-day notranslate">' + curDay + '</span> <span class="calendar-dayoftheweek" style="display: none;">' + this.dayNames[weekday] + '</span></td>'; 2959 } 2960 else { 2961 var addMuted = ""; 2962 2963 // Only mute dates in the past for the date range selector widget 2964 if (this.type == 'dateRangeSelect') { 2965 // If the year is in the past, or the year is the same but the month is in the past, or the month and year are the same but the day is in the past, mute the date 2966 if (this.year < currentDateYear 2967 || (this.year == currentDateYear && this.month < currentDateMonth) 2968 || (this.year == currentDateYear && this.month == currentDateMonth && curDay < currentDateDay) 2969 ) { 2970 addMuted = " muted"; 2971 } 2972 } 2973 2974 gridCells += '\t\t<td id="' + this.calendarName + '-day' + curDay + '" class="day-cell' + addMuted + '" aria-label="row' + 2975 rowCount + ' ' + this.dayNames[weekday] + '" role="gridcell" aria-selected="false"><span class="calendar-day notranslate">' + curDay + '</span> <span class="calendar-dayoftheweek" style="display: none;">' + this.dayNames[weekday] + '</span></td>'; 2976 } 2977 2978 2979 if (weekday == 6 && curDay < numDays) { 2980 // This was the last day of the week, close it out 2981 // and begin a new one 2982 gridCells += '\t</tr>\n\t<tr id="row' + rowCount + '">\n'; 2983 rowCount++; 2984 weekday = 0; 2985 } 2986 else { 2987 weekday++; 2988 } 2989 } 2990 2991 // Insert any trailing empty cells 2992 for (weekday; weekday < 7; weekday++) { 2993 2994 gridCells += '\t\t<td class="empty"> </td>\n'; 2995 } 2996 2997 gridCells += '\t</tr>'; 2998 2999 $tbody.append(gridCells); 3000 if(this.detailedCalendar){ 3001 this.getCalendarDetails(); 3002 }else{ 3003 this.fetchDates();
3004 } 3005 3006} 3007 3008// 3009// calcNumDays() is a member function to calculate the number of days in a given month 3010// 3011// @return (integer) number of days 3012// 3013swDatepicker.prototype.calcNumDays = function (year, month) { 3014 3015 return 32 - new Date(year, month, 32).getDate(); 3016} 3017 3018// 3019// calcstartWeekday() is a member function to calculate the day of the week the first day of a 3020// month lands on 3021// 3022// @return (integer) number representing the day of the week (0=Sunday....6=Saturday) 3023// 3024swDatepicker.prototype.calcStartWeekday = function (year, month) { 3025 3026 return new Date(year, month, 1).getDay(); 3027 3028} // end calcStartWeekday() 3029 3030// 3031// showPrevMonth() is a member function to show the previous month 3032// 3033// @param (offset int) offset may be used to specify an offset for setting 3034// focus on a day the specified number of days from 3035// the end of the month. 3036// @return N/A 3037// 3038swDatepicker.prototype.showPrevMonth = function (offset) { 3039 // show the previous month 3040 if (this.month < 1) { 3041 this.month = 11; 3042 this.year--; 3043 } 3044 else { 3045 this.month--; 3046 } 3047 3048 if (this.month != this.curMonth || this.year != this.curYear) { 3049 this.currentDate = false; 3050 } 3051 else { 3052 this.currentDate = true; 3053 } 3054 3055 this.activeMonth = (String(this.month + 1) + "/1/" + this.year) 3056 3057 // populate the calendar grid 3058 this.popGrid(); 3059 3060 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 3061 3062 // if offset was specified, set focus on the last day - specified offset 3063 if (offset != null) { 3064 var numDays = this.calcNumDays(this.year, this.month); 3065 var day = 'day' + (numDays - offset); 3066 3067 this.$grid.attr('aria-activedescendant', this.calendarName + '-' + day); 3068 $('#' + this.calendarName + '-' + day).addClass('focus').attr('aria-selected', 'true'); 3069 } 3070 3071 3072} // end showPrevMonth() 3073 3074// 3075// showNextMonth() is a member function to show the next month 3076// 3077// @param (offset int) offset may be used to specify an offset for setting 3078// focus on a day the specified number of days from 3079// the beginning of the month. 3080// @return N/A 3081// 3082swDatepicker.prototype.showNextMonth = function (offset) { 3083 3084 // show the next month 3085 if (this.month == 11) { 3086 this.month = 0; 3087 this.year++; 3088 } 3089 else { 3090 this.month++; 3091 } 3092 3093 if (this.month != this.curMonth || this.year != this.curYear) { 3094 this.currentDate = false; 3095 } 3096 else { 3097 this.currentDate = true; 3098 } 3099 3100 this.activeMonth = (String(this.month + 1) + "/1/" + this.year) 3101 3102 // populate the calendar grid 3103 this.popGrid(); 3104 3105 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 3106 3107 // if offset was specified, set focus on the first day + specified offset 3108 if (offset != null) { 3109 var day = 'day' + offset; 3110 3111 this.$grid.attr('aria-activedescendant', this.calendarName + '-' + day); 3112 $('#' + this.calendarName + '-' + day).addClass('focus').attr('aria-selected', 'true'); 3113 } 3114 3115} // end showNextMonth() 3116 3117// 3118// showPrevYear() is a member function to show the previous year 3119// 3120// @return N/A 3121// 3122swDatepicker.prototype.showPrevYear = function () { 3123 3124 // decrement the year 3125 this.year--; 3126 3127 if (this.month != this.curMonth || this.year != this.curYear) { 3128 this.currentDate = false; 3129 } 3130 else { 3131 this.currentDate = true; 3132 } 3133 3134 // populate the calendar grid 3135 this.popGrid(); 3136 3137 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 3138 3139} // end showPrevYear() 3140 3141// 3142// showNextYear() is a member function to show the next year 3143// 3144// @return N/A 3145// 3146swDatepicker.prototype.showNextYear = function () { 3147 3148 // increment the year 3149 this.year++; 3150 3151 if (this.month != this.curMonth || this.year != this.curYear) { 3152 this.currentDate = false; 3153 } 3154 else { 3155 this.currentDate = true; 3156 } 3157 3158 // populate the calendar grid
3159 this.popGrid(); 3160 3161 this.$monthObj.html(this.monthNames[this.month] + ' ' + this.year); 3162 3163} // end showNextYear() 3164 3165// 3166// bindHandlers() is a member function to bind event handlers for the widget 3167// 3168// @return N/A 3169// 3170swDatepicker.prototype.bindHandlers = function () { 3171 3172 var thisObj = this; 3173 3174 ////////////////////// bind button handlers ////////////////////////////////// 3175 this.$prev.click(function (e) { 3176 return thisObj.handlePrevClick(e); 3177 }); 3178 3179 this.$next.click(function (e) { 3180 return thisObj.handleNextClick(e); 3181 }); 3182 3183 this.$prev.keydown(function (e) { 3184 return thisObj.handlePrevKeyDown(e); 3185 }); 3186 3187 this.$next.keydown(function (e) { 3188 return thisObj.handleNextKeyDown(e); 3189 }); 3190 3191 ///////////// bind grid handlers ////////////// 3192 3193 this.$grid.keydown(function (e) { 3194 return thisObj.handleGridKeyDown(e); 3195 }); 3196 3197 this.$grid.keypress(function (e) { 3198 return thisObj.handleGridKeyPress(e); 3199 }); 3200 3201 this.$grid.focus(function (e) { 3202 return thisObj.handleGridFocus(e); 3203 }); 3204 3205 this.$grid.blur(function (e) { 3206 return thisObj.handleGridBlur(e); 3207 }); 3208 3209 this.$grid.delegate('td', 'click', function (e) { 3210 return thisObj.handleGridClick(this, e); 3211 }); 3212 3213} // end bindHandlers(); 3214 3215function scrollToFirstHighlightDay() { 3216 // find all the heights of elements before the calendar 3217 var EventInfoHeight = $('#EventInformationWrap').outerHeight() + 64; // 64 is the height mobile navigation 3218 var EventLabelAndOptionsHeight = $('#eventCalendarLabelAndOptions').outerHeight(); 3219 var CalendarMonthHeight = $('.sw-datepicker.large-datepicker .month-wrap').outerHeight(); 3220 3221 var EventInfoAndOptionsHeight = EventInfoHeight + EventLabelAndOptionsHeight; 3222 var CalendarTopInfoHeaderHeights = EventInfoHeight + EventLabelAndOptionsHeight + CalendarMonthHeight + 10; // 10 is just a gap added so it is not sticking against the month section 3223 3224 // set the Top section sticky so when it focuses on the first hightlight day you can still see the informations 3225 $('#EventInformationWrap').addClass("make-this-section-sticky"); 3226 $('#eventCalendarLabelAndOptions').addClass("make-this-section-sticky"); 3227 $('#eventCalendarLabelAndOptions').css("top", EventInfoHeight); 3228 $('.sw-datepicker.large-datepicker .month-wrap').addClass("make-this-section-sticky"); 3229 $('.sw-datepicker.large-datepicker .month-wrap').css("top", EventInfoAndOptionsHeight); 3230 3231 // Check if any elements with the class .highlight-day exist 3232 var highlightDay = $('.performance-list-calendar .highlight-day').first(); 3233 3234 // set the first day cell 3235 var firstDayCel = $('.day-cell').first(); 3236 var scrollToPosition = 0; 3237 3238 if (highlightDay.length > 0) { // Get the offset only if .highlight-day element exists 3239 scrollToPosition = highlightDay.offset().top; 3240 scrollToPosition = scrollToPosition - CalendarTopInfoHeaderHeights; 3241 $('html, body').animate({scrollTop: scrollToPosition}, 'slow'); 3242 } else { // if there's no highlights on this month, focus on the first day of the month 3243 scrollToPosition = firstDayCel.offset().top; 3244 scrollToPosition = scrollToPosition - (CalendarTopInfoHeaderHeights * 2); 3245 $('html, body').animate({scrollTop: scrollToPosition}, 'slow'); 3246 } 3247} 3248 3249// 3250// handlePrevClick() is a member function to process click events for the prev month button 3251// 3252// @input (e obj) e is the event object associated with the event 3253// 3254// @return (boolean) false if consuming event, true if propagating 3255// 3256swDatepicker.prototype.handlePrevClick = function (e) { 3257 3258 var active = this.$grid.attr('aria-activedescendant'); 3259 3260 if (e.ctrlKey) { 3261 this.showPrevYear(); 3262 } 3263 else { 3264 this.showPrevMonth(); 3265 } 3266 3267 if (this.currentDate == false) { 3268 this.$grid.attr('aria-activedescendant', this.calendarName + '-day1'); 3269 } 3270 else { 3271 this.$grid.attr('aria-activedescendant', active); 3272 } 3273 3274 e.stopPropagation(); 3275 return false; 3276 3277} // end handlePrevClick() 3278 3279// 3280// handleNextClick() is a member function to process click events for the next month button 3281// 3282// @input (e obj) e is the event object associated with the event 3283// 3284// @return (boolean) false if consuming event, true if propagating 3285// 3286swDatepicker.prototype.handleNextClick = function (e) { 3287 3288 var active = this.$grid.attr('aria-activedescendant'); 3289 3290 if (e.ctrlKey) { 3291 this.showNextYear(); 3292 } 3293 else { 3294 this.showNextMonth(); 3295 } 3296 3297 if (this.currentDate == false) { 3298 this.$grid.attr('aria-activedescendant', this.calendarName + '-day1'); 3299 } 3300 else { 3301 this.$grid.attr('aria-activedescendant', active); 3302 } 3303 3304 e.stopPropagation(); 3305 return false; 3306 3307} // end handleNextClick() 3308 3309// 3310// handlePrevKeyDown() is a member function to process keydown events for the prev month button 3311// 3312// @input (e obj) e is the event object associated with the event 3313// 3314// @return (boolean) false if consuming event, true if propagating 3315// 3316swDatepicker.prototype.handlePrevKeyDown = function (e) { 3317 3318 if (e.altKey) { 3319 return true; 3320 } 3321 3322 switch (e.keyCode) { 3323 case this.keys.tab: { 3324 if (this.bModal == false || !e.shiftKey || e.ctrlKey) { 3325 return true; 3326 } 3327 3328 this.$grid.focus(); 3329 e.stopPropagation(); 3330 return false; 3331 } 3332 case this.keys.enter: 3333 case this.keys.space: { 3334 if (e.shiftKey) { 3335 return true; 3336 } 3337 3338 if (e.ctrlKey) { 3339 this.showPrevYear(); 3340 } 3341 else { 3342 this.showPrevMonth(); 3343 } 3344 3345 e.stopPropagation(); 3346 return false; 3347 } 3348 } 3349 3350 return true; 3351 3352} // end handlePrevKeyDown() 3353 3354// 3355// handleNextKeyDown() is a member function to process keydown events for the next month button 3356// 3357// @input (e obj) e is the event object associated with the event 3358// 3359// @return (boolean) false if consuming event, true if propagating 3360// 3361swDatepicker.prototype.handleNextKeyDown = function (e) { 3362 3363 if (e.altKey) { 3364 return true; 3365 } 3366 3367 switch (e.keyCode) { 3368 case this.keys.enter: 3369 case this.keys.space: { 3370 3371 if (e.ctrlKey) { 3372 this.showNextYear(); 3373 } 3374 else { 3375 this.showNextMonth(); 3376 } 3377 3378 e.stopPropagation(); 3379 return false; 3380 } 3381 } 3382 3383 return true; 3384 3385} // end handleNextKeyDown() 3386 3387// 3388// handleGridKeyDown() is a member function to process keydown events for the datepicker grid 3389// 3390// @input (e obj) e is the event object associated with the event 3391// 3392// @return (boolean) false if consuming event, true if propagating 3393// 3394swDatepicker.prototype.handleGridKeyDown = function (e) { 3395 3396 var $rows = this.$grid.find('tbody tr'); 3397 var $curDay = $('#' + this.$grid.attr('aria-activedescendant'));
3398 var $days = this.$grid.find('td').not('.empty'); 3399 var $curRow = $curDay.parent(); 3400 3401 if (e.altKey) { 3402 return true; 3403 } 3404 3405 switch (e.keyCode) { 3406 case this.keys.tab: { 3407 3408 if (this.bModal == true) { 3409 if (e.shiftKey) { 3410 this.$next.focus(); 3411 } 3412 else { 3413 this.$prev.focus(); 3414 } 3415 e.stopPropagation() 3416 return false; 3417 } 3418 break; 3419 } 3420 case this.keys.enter: 3421 case this.keys.space: { 3422 3423 if (e.ctrlKey) { 3424 return true; 3425 } 3426 3427 // update the target box 3428 this.$target.val((this.month + 1) + '/' + $curDay.find(".calendar-day").text() + '/' + this.year).change(); 3429 3430 // fall through 3431 } 3432 case this.keys.esc: { 3433 // dismiss the dialog box 3434 this.hideDlg(); 3435 3436 e.stopPropagation(); 3437 return false; 3438 } 3439 case this.keys.left: { 3440 3441 if (e.ctrlKey || e.shiftKey) { 3442 return true; 3443 } 3444 3445 var dayIndex = $days.index($curDay) - 1; 3446 var $prevDay = null; 3447 3448 if (dayIndex >= 0) { 3449 $prevDay = $days.eq(dayIndex); 3450 3451 $curDay.removeClass('focus').attr('aria-selected', 'false'); 3452 $prevDay.addClass('focus').attr('aria-selected', 'true'); 3453 3454 this.$grid.attr('aria-activedescendant', $prevDay.attr('id')); 3455 } 3456 else { 3457 this.showPrevMonth(0); 3458 } 3459 3460 e.stopPropagation(); 3461 return false; 3462 } 3463 case this.keys.right: { 3464 3465 if (e.ctrlKey || e.shiftKey) { 3466 return true; 3467 } 3468 3469 var dayIndex = $days.index($curDay) + 1; 3470 var $nextDay = null; 3471 3472 if (dayIndex < $days.length) { 3473 $nextDay = $days.eq(dayIndex); 3474 $curDay.removeClass('focus').attr('aria-selected', 'false'); 3475 $nextDay.addClass('focus').attr('aria-selected', 'true'); 3476 3477 this.$grid.attr('aria-activedescendant', $nextDay.attr('id')); 3478 } 3479 else { 3480 // move to the next month 3481 this.showNextMonth(1); 3482 } 3483 3484 e.stopPropagation(); 3485 return false; 3486 } 3487 case this.keys.up: { 3488 3489 if (e.ctrlKey || e.shiftKey) { 3490 return true; 3491 } 3492 3493 var dayIndex = $days.index($curDay) - 7; 3494 var $prevDay = null; 3495 3496 if (dayIndex >= 0) { 3497 $prevDay = $days.eq(dayIndex); 3498 3499 $curDay.removeClass('focus').attr('aria-selected', 'false'); 3500 $prevDay.addClass('focus').attr('aria-selected', 'true'); 3501 3502 this.$grid.attr('aria-activedescendant', $prevDay.attr('id')); 3503 } 3504 else { 3505 // move to appropriate day in previous month 3506 dayIndex = 6 - $days.index($curDay); 3507 3508 this.showPrevMonth(dayIndex); 3509 } 3510 3511 e.stopPropagation(); 3512 return false; 3513 } 3514 case this.keys.down: { 3515 3516 if (e.ctrlKey || e.shiftKey) { 3517 return true; 3518 } 3519 3520 var dayIndex = $days.index($curDay) + 7; 3521 var $prevDay = null; 3522 3523 if (dayIndex < $days.length) { 3524 $prevDay = $days.eq(dayIndex); 3525 3526 $curDay.removeClass('focus').attr('aria-selected', 'false'); 3527 $prevDay.addClass('focus').attr('aria-selected', 'true'); 3528 3529 this.$grid.attr('aria-activedescendant', $prevDay.attr('id')); 3530 } 3531 else { 3532 // move to appropriate day in next month 3533 dayIndex = 8 - ($days.length - $days.index($curDay)); 3534 3535 this.showNextMonth(dayIndex); 3536 } 3537 3538 e.stopPropagation(); 3539 return false; 3540 } 3541 case this.keys.pageup: { 3542 var active = this.$grid.attr('aria-activedescendant'); 3543 3544 3545 if (e.shiftKey) { 3546 return true; 3547 } 3548 3549 3550 if (e.ctrlKey) { 3551 this.showPrevYear(); 3552 } 3553 else { 3554 this.showPrevMonth(); 3555 } 3556 3557 if ($('#' + active).attr('id') == undefined) { 3558 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 3559 $('#' + this.calendarName + '-' + lastDay).addClass('focus').attr('aria-selected', 'true'); 3560 } 3561 else { 3562 $('#' + this.calendarName + '-' + active).addClass('focus').attr('aria-selected', 'true'); 3563 } 3564 3565 e.stopPropagation(); 3566 return false; 3567 } 3568 case this.keys.pagedown: { 3569 var active = this.$grid.attr('aria-activedescendant'); 3570 3571 3572 if (e.shiftKey) { 3573 return true; 3574 } 3575 3576 if (e.ctrlKey) { 3577 this.showNextYear(); 3578 } 3579 else { 3580 this.showNextMonth(); 3581 } 3582 3583 if ($('#' + active).attr('id') == undefined) { 3584 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 3585 $('#' + this.calendarName + '-' + lastDay).addClass('focus').attr('aria-selected', 'true'); 3586 } 3587 else { 3588 $('#' + this.calendarName + '-' + active).addClass('focus').attr('aria-selected', 'true'); 3589 } 3590 3591 e.stopPropagation(); 3592 return false; 3593 } 3594 case this.keys.home: { 3595 3596 if (e.ctrlKey || e.shiftKey) { 3597 return true; 3598 } 3599 3600 $curDay.removeClass('focus').attr('aria-selected', 'false'); 3601 3602 $('#' + this.calendarName + '-day1').addClass('focus').attr('aria-selected', 'true'); 3603 3604 this.$grid.attr('aria-activedescendant', this.calendarName + '-day1'); 3605 3606 e.stopPropagation(); 3607 return false; 3608 } 3609 case this.keys.end: { 3610 3611 if (e.ctrlKey || e.shiftKey) { 3612 return true; 3613 } 3614 3615 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 3616 3617 $curDay.removeClass('focus').attr('aria-selected', 'false'); 3618 3619 $('#' + this.calendarName + '-' + lastDay).addClass('focus').attr('aria-selected', 'true'); 3620 3621 this.$grid.attr('aria-activedescendant', this.calendarName + '-' + lastDay); 3622 3623 e.stopPropagation(); 3624 return false; 3625 } 3626 } 3627 3628 return true; 3629 3630} // end handleGridKeyDown() 3631 3632//
3633// handleGridKeyPress() is a member function to consume keypress events for browsers that 3634// use keypress to scroll the screen and manipulate tabs 3635// 3636// @input (e obj) e is the event object associated with the event 3637// 3638// @return (boolean) false if consuming event, true if propagating 3639// 3640swDatepicker.prototype.handleGridKeyPress = function (e) { 3641 3642 if (e.altKey) { 3643 return true; 3644 } 3645 3646 switch (e.keyCode) { 3647 case this.keys.tab: 3648 case this.keys.enter: 3649 case this.keys.space: 3650 case this.keys.esc: 3651 case this.keys.left: 3652 case this.keys.right: 3653 case this.keys.up: 3654 case this.keys.down: 3655 case this.keys.pageup: 3656 case this.keys.pagedown: 3657 case this.keys.home: 3658 case this.keys.end: { 3659 e.stopPropagation(); 3660 return false; 3661 } 3662 } 3663 3664 return true; 3665 3666} // end handleGridKeyPress() 3667 3668// 3669// handleGridClick() is a member function to process mouse click events for the datepicker grid 3670// 3671// @input (id obj) e is the id of the object triggering the event 3672// 3673// @input (e obj) e is the event object associated with the event 3674// 3675// @return (boolean) false if consuming event, true if propagating 3676// 3677swDatepicker.prototype.handleGridClick = function (id, e) { 3678 var $cell = $(id); 3679 3680 if ($cell.is('.empty')) { 3681 return true; 3682 } 3683 3684 this.$grid.find('.focus').removeClass('focus').attr('aria-selected', 'false'); 3685 $cell.addClass('focus').attr('aria-selected', 'true'); 3686 this.$grid.attr('aria-activedescendant', $cell.attr('id')); 3687 3688 var $curDay = $('#' + this.$grid.attr('aria-activedescendant')); 3689 3690 /*console.log($curDay); 3691 var isLastMonth = $curDay.hasClass('last-month'); 3692 3693 var monthSelected = this.month + 1; 3694 var yearSelected = this.year; 3695 3696 if (isLastMonth) { 3697 monthSelected--; 3698 3699 if (monthSelected == 0) 3700 monthSelected = 12; 3701 3702 yearSelected = $curDay.data('year'); 3703 } 3704 3705 console.log("month selected: " + monthSelected); 3706 console.log("year selected: " + yearSelected);*/ 3707 3708 // update the target box 3709 if(this.type == 'dateRangeSelect'){ 3710 if ($curDay.hasClass('muted')) 3711 return true; 3712 3713 var $rangeSelDate = new Date((this.month + 1) + '/' + $curDay.children('.calendar-day').text() + '/' + this.year); 3714 if(this.fromDateRange == '' && this.toDateRange == ''){ 3715 //no dates selected yet, store this in the from date range for now 3716 this.fromDateRange = $rangeSelDate; 3717 }else{ 3718 //we've previously selected at least one date here, so figure out which one it should be 3719 if($rangeSelDate < this.fromDateRange){ 3720 this.toDateRange = this.fromDateRange; 3721 this.fromDateRange = $rangeSelDate; 3722 }else{ 3723 this.toDateRange = $rangeSelDate; 3724 } 3725 } 3726 3727 var objDateRange = {} 3728 objDateRange.from = this.fromDateRange; 3729 objDateRange.to = this.toDateRange; 3730 this.$target.val(JSON.stringify(objDateRange)).change(); 3731 if(objDateRange.from != '' && objDateRange.to != ''){ 3732 this.hideDlg(); //NOTE: this only works if the date range is a modal, for other calendars you'll need to manage display according to needs based on current values. 3733 } 3734 e.stopPropagation(); 3735 return false; 3736 } 3737 if (!this.forceDateSelection || $cell.hasClass("highlight-day")) { 3738 this.$target.val((this.month + 1) + '/' + $curDay.children('.calendar-day').text() + '/' + this.year).change(); 3739 // dismiss the dialog box 3740 this.hideDlg(); 3741 } 3742 e.stopPropagation(); 3743 return false; 3744 3745} // end handleGridClick() 3746 3747// 3748// handleGridFocus() is a member function to process focus events for the datepicker grid 3749// 3750// @input (e obj) e is the event object associated with the event 3751// 3752// @return (boolean) true 3753// 3754swDatepicker.prototype.handleGridFocus = function (e) { 3755 var active = this.$grid.attr('aria-activedescendant'); 3756 3757 if ($('#' + active).attr('id') == undefined) { 3758 var lastDay = 'day' + this.calcNumDays(this.year, this.month); 3759 $('#' + lastDay).addClass('focus').attr('aria-selected', 'true'); 3760 } 3761 else { 3762 $('#' + active).addClass('focus').attr('aria-selected', 'true'); 3763 } 3764 3765 return true; 3766 3767} // end handleGridFocus() 3768 3769// 3770// handleGridBlur() is a member function to process blur events for the datepicker grid 3771// 3772// @input (e obj) e is the event object associated with the event 3773// 3774// @return (boolean) true 3775// 3776swDatepicker.prototype.handleGridBlur = function (e) { 3777 $('#' + this.$grid.attr('aria-activedescendant')).removeClass('focus').attr('aria-selected', 'false'); 3778 3779 return true; 3780 3781} // end handleGridBlur() 3782 3783//
3784// showDlg() is a member function to show the datepicker and give it focus. This function is only called if 3785// the datepicker is used in modal dialog mode. 3786// 3787// @return N/A 3788// 3789swDatepicker.prototype.showDlg = function () { 3790 if (!this.bModal) 3791 return; 3792 3793 var thisObj = this; 3794 var thisNode = this.$id; 3795 3796 this.highlightDays(); 3797 3798 this.active = true; 3799 3800 //prevent calendar from pushing out of the right side of the window 3801 if (thisNode.parent()[0].getBoundingClientRect().left > (window.innerWidth / 2)) 3802 thisNode.addClass("right-side"); 3803 3804 $(".content-wrap").bind('click', function (e) { 3805 if (!thisNode[0].contains(e.target) && e.target != thisObj.$target[0]) { 3806 thisObj.hideDlg(); 3807 } 3808 }); 3809 3810 // show the dialog 3811 this.$id.attr('aria-hidden', 'false'); 3812 3813 this.$grid.focus(); 3814 3815} // end showDlg() 3816 3817// 3818// hideDlg() is a member function to hide the datepicker and remove focus. This function is only called if 3819// the datepicker is used in modal dialog mode. 3820// 3821// @return N/A 3822// 3823swDatepicker.prototype.hideDlg = function () { 3824 if (!this.bModal) 3825 return; 3826 3827 this.active = false; 3828 var thisNode = this.$id; 3829 3830 // unbind the modal event sinks 3831 $(document).unbind('click'); 3832 3833 // hide the dialog 3834 this.$id.attr('aria-hidden', 'true'); 3835 3836 // set focus on the focus target 3837 //this.$target.focus(); 3838 3839} // end showDlg() 3840 3841//function to highlight days with performances or valid information 3842//to prevent rewriting the calendar each time a date is added, popGrid() should be called after all dates have been added 3843swDatepicker.prototype.addHighlightDay = function (date) { 3844 var datesplit = String(date).split("/"); 3845 for(var i = 0;i < datesplit.length; i++){ 3846 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3847 } 3848 date = datesplit.join("/"); 3849 if (datesplit.length != 3) { 3850 //date didn't come in in m/d/yyyy format, kick it back in the console 3851 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3852 console.log(date); 3853 return; 3854 3855 } 3856 this.highlightDates.push(date); 3857 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3858 $("#" + this.calendarName + "-day" + datesplit[1]).addClass("highlight-day"); 3859 } 3860} 3861swDatepicker.prototype.addDateInfoBox = function (date, infoBoxText) { 3862 var datesplit = String(date).split("/"); 3863 for(var i = 0;i < datesplit.length; i++){ 3864 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3865 } 3866 date = datesplit.join("/"); 3867 if (datesplit.length != 3) { 3868 //date didn't come in in m/d/yyyy format, kick it back in the console 3869 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3870 console.log(date); 3871 return; 3872 3873 } 3874 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3875 $("#" + this.calendarName + "-day" + datesplit[1]).append('<span class="date-info-box">' + infoBoxText + '</span>'); 3876 } 3877} 3878swDatepicker.prototype.addDateSubNote = function (date, noteText) { 3879 var datesplit = String(date).split("/"); 3880 for(var i = 0;i < datesplit.length; i++){ 3881 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3882 } 3883 date = datesplit.join("/"); 3884 if (datesplit.length != 3) { 3885 //date didn't come in in m/d/yyyy format, kick it back in the console 3886 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3887 console.log(date); 3888 return; 3889 3890 } 3891 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3892 var spanClass = this.isMultiplePerformanceIndicator ? 'date-info-box date-sub-note multiple-performancetime-subnote' : 'date-info-box date-sub-note'; 3893 $("#" + this.calendarName + "-day" + datesplit[1]).append('<span class="' + spanClass + '">' + noteText + '</span>'); 3894 } 3895} 3896swDatepicker.prototype.setDaySoldOut = function (date) { 3897 var datesplit = String(date).split("/"); 3898 for(var i = 0;i < datesplit.length; i++){ 3899 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3900 } 3901 date = datesplit.join("/"); 3902 if (datesplit.length != 3) { 3903 //date didn't come in in m/d/yyyy format, kick it back in the console 3904 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3905 console.log(date); 3906 return; 3907 3908 } 3909 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3910 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('sold-out'); 3911 3912 this.addDateInfoBox(date, "Sold Out"); 3913 $("#" + this.calendarName + "-day" + datesplit[1]).children(".date-info-box").removeClass("date-info-box").addClass("sold-out-info-box"); 3914 } 3915} 3916swDatepicker.prototype.setcustomStatus = function (date,showPhoneNumber,currenStatus) { 3917 var datesplit = String(date).split("/"); 3918 for(var i = 0;i < datesplit.length; i++){ 3919 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3920 } 3921 date = datesplit.join("/"); 3922 if (datesplit.length != 3) { 3923 //date didn't come in in m/d/yyyy format, kick it back in the console 3924 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3925 console.log(date); 3926 return; 3927 3928 } 3929 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3930 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('sold-out'); 3931 var phoneNumber = " <br> [email protected] " 3932 if (!showPhoneNumber) 3933 phoneNumber=""; 3934 this.addDateInfoBox(date, currenStatus +phoneNumber); 3935 3936 $("#" + this.calendarName + "-day" + datesplit[1]).children(".date-info-box").removeClass("date-info-box").addClass("sold-out-info-box"); 3937 } 3938} 3939swDatepicker.prototype.setDayLimitedAvailabilty = function (date) { 3940 var datesplit = String(date).split("/"); 3941 for(var i = 0;i < datesplit.length; i++){ 3942 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3943 } 3944 date = datesplit.join("/"); 3945 if (datesplit.length != 3) { 3946 //date didn't come in in m/d/yyyy format, kick it back in the console 3947 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3948 console.log(date); 3949 return; 3950 3951 } 3952 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3953 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('limited-availability'); 3954 3955 this.addDateSubNote(date, 'Selling Quickly'); 3956 //$("#" + this.calendarName + "-day" + datesplit[1]).children(".date-info-box").removeClass("date-info-box").addClass("sold-out-info-box"); 3957 } 3958 if($(".limited-availability-legend-item").length == 0){ 3959 3960 $(".calendar-notes-wrap").append('<div class="limited-availability-legend-item"><span classs="calendar-limited-availability-legend-icon">!</span> - Selling Quickly</div>') 3961 3962 // $("#streamlinedCalendarLimitedAvailabilityLegend").append('<div class="limited-availability-legend-item"><span class="calendar-limited-availability-legend-icon">!</span> - Selling Quickly</div>') 3963 } 3964} 3965swDatepicker.prototype.setMultiplePerformanceTimes = function (date) { 3966 var datesplit = String(date).split("/"); 3967 for(var i = 0;i < datesplit.length; i++){ 3968 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3969 } 3970 3971 date = datesplit.join("/"); 3972 if (datesplit.length != 3) { 3973 //date didn't come in in m/d/yyyy format, kick it back in the console 3974 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3975 return; 3976 3977 } 3978 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 3979 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('multipleperformancetimes'); 3980 3981 } 3982 if($(".multiple-performancetimes-notes").length == 0){ 3983 3984 } 3985 3986} 3987swDatepicker.prototype.setMutedDay = function (date) { 3988 var datesplit = String(date).split("/"); 3989 for(var i = 0;i < datesplit.length; i++){ 3990 datesplit[i] = datesplit[i].replace(/^0+/, ''); 3991 } 3992 date = datesplit.join("/"); 3993 if (datesplit.length != 3) { 3994 //date didn't come in in m/d/yyyy format, kick it back in the console 3995 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 3996 return; 3997 3998 } 3999 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 4000 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('muted'); 4001 } 4002} 4003swDatepicker.prototype.clearMutedDay = function (date) { 4004 var datesplit = String(date).split("/"); 4005 for(var i = 0;i < datesplit.length; i++){ 4006 datesplit[i] = datesplit[i].replace(/^0+/, ''); 4007 } 4008 date = datesplit.join("/"); 4009 if (datesplit.length != 3) { 4010 //date didn't come in in m/d/yyyy format, kick it back in the console 4011 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 4012 return; 4013 4014 } 4015 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 4016 $("#" + this.calendarName + "-day" + datesplit[1]).removeClass('muted'); 4017 } 4018} 4019swDatepicker.prototype.setCouponMutedDay = function (date) { 4020 var datesplit = String(date).split("/"); 4021 for(var i = 0;i < datesplit.length; i++){ 4022 datesplit[i] = datesplit[i].replace(/^0+/, ''); 4023 } 4024 date = datesplit.join("/"); 4025 if (datesplit.length != 3) { 4026 //date didn't come in in m/d/yyyy format, kick it back in the console 4027 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 4028 return; 4029 4030 } 4031 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 4032 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('coupon-muted'); 4033 } 4034}
4035swDatepicker.prototype.setPasswordHiddenDay = function (date) { 4036 var datesplit = String(date).split("/"); 4037 for(var i = 0;i < datesplit.length; i++){ 4038 datesplit[i] = datesplit[i].replace(/^0+/, ''); 4039 } 4040 date = datesplit.join("/"); 4041 if (datesplit.length != 3) { 4042 //date didn't come in in m/d/yyyy format, kick it back in the console 4043 console.log("invalid date sent, datepicker accepts m/d/yyyy only - " + date); 4044 return; 4045 4046 } 4047 if (parseInt(datesplit[0]) - 1 == this.month && parseInt(datesplit[2]) == this.year) { 4048 $("#" + this.calendarName + "-day" + datesplit[1]).addClass('password-hidden'); 4049 $("#" + this.calendarName + "-day" + datesplit[1]).removeClass('highlight-day'); 4050 } 4051} 4052swDatepicker.prototype.clearAllMutedDays = function () { 4053 $(".muted").removeClass('muted'); 4054} 4055swDatepicker.prototype.clearHighlightDays = function () { 4056 this.highlightDates = []; 4057 this.highlightDays(); 4058} 4059//highlights all days in the highlightDates array 4060swDatepicker.prototype.highlightDays = function () { 4061 $("#" + this.calendarName + " .highlight-day").removeClass("highlight-day"); 4062 var curYear = this.year; 4063 var curMonth = this.month; 4064 var calName = this.calendarName; 4065 var IEFix = new RegExp(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g); 4066 4067 this.highlightDates.forEach(function (o, i, a) { 4068 var datesplit = o.split("/"); 4069 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 4070 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '')).addClass("highlight-day"); 4071 } 4072 }); 4073 this.setColors(); 4074} 4075swDatepicker.prototype.setColors = function () { 4076 /* 4077 Custom color functionality. Utilized by dropping calendar-colors.txt file in root of custom folder 4078 requires json content of text file formatted as follows: 4079 { 4080 "events": 4081 {"528": 4082 [ 4083 {"date":"12/1/2025", "color": "#ccc"}, 4084 {"date":"12/2/2025", "color": "#ccc"} 4085 ] 4086 , 4087 "529": 4088 [ 4089 {"date":"12/8/2025", "color": "#ccc"}, 4090 {"date":"12/9/2025", "color": "#ccc"} 4091 ] 4092 } 4093 , 4094 "bundles":[], 4095 "generic": 4096 {"dates": 4097 [ 4098 {"date":"12/23/2025", "color": "#def"}, 4099 {"date":"12/22/2025", "color": "#1a1"} 4100 ] 4101 , 4102 "weekdays": 4103 [ 4104 {"day":"Saturday", "color": "#2a2"}, 4105 {"day":"Thursday", "color": "#3a3"} 4106 ] 4107 } 4108 } 4109 } 4110 */ 4111 var thisDP = this; 4112 try{ 4113 $.getJSON("/calendar-colors.txt") 4114 .done(function (data) { 4115 thisDP.renderColors(data); 4116 }) 4117 .fail(function (jqxhr, textStatus, error) { 4118 console.log("No Custom Calendar Colors Found"); 4119 return; 4120 }); 4121 }catch(e){ 4122 console.log("parsing error:"); 4123 console.log(e); 4124 return; 4125 } 4126} 4127swDatepicker.prototype.renderColors = function (colorData) { 4128 var curYear = this.year; 4129 var curMonth = this.month; 4130 var calName = this.calendarName; 4131 var IEFix = new RegExp(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g); 4132 //set generic colors 4133 if(colorData.generic){ 4134 if(colorData.generic.dates.length > 0){ 4135 colorData.generic.dates.forEach(function (o, i, a) { 4136 var datesplit = o.date.split("/"); 4137 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 4138 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '') + ' .calendar-day').css("background-color", o.color); 4139 } 4140 }); 4141 } 4142 if(colorData.generic.weekdays && colorData.generic.weekdays.length > 0){ 4143 colorData.generic.weekdays.forEach(function (o, i, a) { 4144 $("td[headers*=" + o.day + "] .calendar-day").css("background-color", o.color); 4145 }); 4146 } 4147 } 4148 if(colorData.events && colorData.events[this.eventID] && this.eventID !== -1){
4149 colorData.events[this.eventID].forEach(function (o, i, a) { 4150 var datesplit = o.date.split("/"); 4151 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 4152 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '') + ' .calendar-day').css("background-color", o.color); 4153 } 4154 }); 4155 } 4156 if(colorData.bundles && colorData.bundles[this.bundleID] && this.bundleID !== -1){ 4157 colorData.bundles[this.bundleID].forEach(function (o, i, a) { 4158 var datesplit = o.date.split("/"); 4159 if (parseInt(datesplit[0].replace(IEFix, '')) - 1 == parseInt(curMonth) && parseInt(datesplit[2].replace(IEFix, '')) == parseInt(curYear)) { 4160 $("#" + calName + "-day" + datesplit[1].replace(IEFix, '') + ' .calendar-day').css("background-color", o.color); 4161 } 4162 }); 4163 } 4164} 4165swDatepicker.prototype.fetchDates = function(){ 4166 var thisCalendar = this; 4167 var haveDates = thisCalendar.fetchLocalDates(); 4168 if (thisCalendar.categoryID >= 0) 4169 haveDates = false; 4170 this.clearHighlightDays(); 4171 if(haveDates){ 4172 //valid local dates stored 4173 try{ 4174 haveDates = JSON.parse(haveDates); 4175 if (haveDates.length > 0) { 4176 haveDates.forEach(function(o){ 4177 thisCalendar.addHighlightDay(o); 4178 }) 4179 thisCalendar.highlightDays(); 4180 } 4181 } catch (e) { 4182 console.log("Failed to grab dates. Date object not valid: ", haveDates); 4183 console.log(e); 4184 } 4185 } else { 4186 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 4187 { 4188 action: thisCalendar.type, 4189 calMonth: thisCalendar.activeMonth, 4190 iEvent: thisCalendar.eventID, 4191 iBundle: thisCalendar.bundleID, 4192 iCategory : thisCalendar.categoryID, 4193 cp : thisCalendar.corporatePartnerPage 4194 }) 4195 .done(function (data) { 4196 thisCalendar.storeDates(data.performancedates); 4197 try { 4198 if (data.performancedates.length > 0) { 4199 data.performancedates.forEach(function (o) { 4200 4201 thisCalendar.addHighlightDay(o); 4202 }) 4203 thisCalendar.highlightDays(); 4204 } 4205 } catch (e) { 4206 console.log("Failed to grab dates. Date object not valid: " + haveDates); 4207 console.log(e); 4208 } 4209 $(".calendar-loading").hide(); 4210 }) 4211 .fail(function (jqxhr, textStatus, error) { 4212 var err = textStatus + ", " + error; 4213 console.log("Request Failed: " + err); 4214 $(".calendar-loading").hide(); 4215 }); 4216 } 4217} 4218swDatepicker.prototype.getCalendarDetails = function(){ 4219 var thisCalendar = this; 4220 this.clearHighlightDays(); 4221 $("#" + this.calendarName).removeClass("has-muted-days"); 4222 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 4223 { 4224 action: thisCalendar.type, 4225 calMonth: thisCalendar.activeMonth, 4226 iEvent: thisCalendar.eventID, 4227 iBundle: thisCalendar.bundleID, 4228 iCategory : thisCalendar.categoryID, 4229 cp : thisCalendar.corporatePartnerPage, 4230 bValidCoupon : thisCalendar.bValidCoupon, 4231 couponCode : thisCalendar.couponCode 4232 }) 4233 .done(function (data) { 4234 //to save on request time, we need to resolve the data on the client a bit before we store it 4235 var performanceDates = []; 4236 data.performanceDateData.forEach(function(dd){ 4237 4238 if(dd.DoNotShowPublic == 0){ 4239 var detailsObj = {}; 4240 var currentDateIndex = fetchDateIndex(dd.CalendarDate, performanceDates); 4241 if(currentDateIndex == -1){ 4242 detailsObj.date = dd.CalendarDate; 4243 detailsObj.performances = []; 4244 detailsObj.performances.push(dd.PerformanceCode); 4245 detailsObj.defaultPrice = dd.LowestDefaultPrice; 4246 detailsObj.PerformanceName = dd.PerformanceName; 4247 detailsObj.PerformanceTime = dd.PerfTime; 4248 detailsObj.PerformanceStartTimeAlias = dd.PerformanceStartTimeAlias; 4249 detailsObj.DisplayType = dd.DisplayType; 4250 detailsObj.CalendarViewShowPrice = dd.CalendarViewShowPrice; 4251 detailsObj.CalendarViewShowPerformanceName = dd.CalendarViewShowPerformanceName; 4252 detailsObj.CalendarViewShowPerformanceTime = dd.CalendarViewShowPerformanceTime; 4253 detailsObj.CalendarViewShowBuyButton = dd.CalendarViewShowBuyButton; 4254 detailsObj.defaultPricingCode = dd.LowestDefaultPricingCode; 4255 detailsObj.secondaryPrice = dd.LowestSecondaryPrice; 4256 detailsObj.secondaryPricingCode =dd.LowestSecondaryPricingCode; 4257 detailsObj.NoCouponAvailable = dd.NoCouponAvailable; 4258 detailsObj.passwordMatch = dd.passwordMatch; 4259 detailsObj.qualifierPasswordMatch = dd.qualifierPasswordMatch; 4260 detailsObj.hasPassword = dd.hasPassword; 4261 detailsObj.hasQualifierPassword = dd.hasQualifierPassword; 4262 detailsObj.hasCoupons = dd.hasCoupons; 4263 detailsObj.IsSalesPeriodEnded = dd.IsSalesPeriodEnded; 4264 detailsObj.SaleIcon = dd.SaleIcon; 4265 detailsObj.BSaleIcon = dd.BSaleIcon; 4266 4267 detailsObj.hasQualifiers = dd.hasQualifiers;
4268 performanceDates.push(detailsObj) 4269 4270 }else{ 4271 performanceDates[currentDateIndex].performances.push(dd.PerformanceCode); 4272 performanceDates[currentDateIndex].NoCouponAvailable = dd.NoCouponAvailable; 4273 performanceDates[currentDateIndex].passwordMatch = dd.passwordMatch; 4274 performanceDates[currentDateIndex].acMatch = dd.acMatch; 4275 performanceDates[currentDateIndex].qualifierPasswordMatch = dd.qualifierPasswordMatch; 4276 performanceDates[currentDateIndex].hasPassword = dd.hasPassword; 4277 performanceDates[currentDateIndex].hasQualifierPassword = dd.hasQualifierPassword; 4278 performanceDates[currentDateIndex].hasCoupons = dd.hasCoupons; 4279 performanceDates[currentDateIndex].PerformanceName = dd.PerformanceName; 4280 performanceDates[currentDateIndex].PerformanceTime = dd.PerfTime; 4281 performanceDates[currentDateIndex].PerformanceStartTimeAlias = dd.PerformanceStartTimeAlias; 4282 performanceDates[currentDateIndex].CalendarViewShowPrice = dd.CalendarViewShowPrice; 4283 performanceDates[currentDateIndex].CalendarViewShowPerformanceName = dd.CalendarViewShowPerformanceName; 4284 performanceDates[currentDateIndex].CalendarViewShowPerformanceTime = dd.CalendarViewShowPerformanceTime; 4285 performanceDates[currentDateIndex].CalendarViewShowBuyButton = dd.CalendarViewShowBuyButton; 4286 performanceDates[currentDateIndex].IsSalesPeriodEnded = dd.IsSalesPeriodEnded; 4287 performanceDates[currentDateIndex].SaleIcon = dd.SaleIcon; 4288 performanceDates[currentDateIndex].BSaleIcon = dd.BSaleIcon; 4289 performanceDates[currentDateIndex].hasQualifiers = dd.hasQualifiers; 4290 //check for lowest price 4291 if(performanceDates[currentDateIndex].defaultPrice > dd.LowestDefaultPrice && dd.LowestDefaultPrice != null){ 4292 performanceDates[currentDateIndex].defaultPrice = dd.LowestDefaultPrice; 4293 performanceDates[currentDateIndex].defaultPricingCode = dd.LowestDefaultPricingCode; 4294 } 4295 if(performanceDates[currentDateIndex].hasCoupons == 1 && performanceDates[currentDateIndex].defaultPrice < dd.LowestDefaultPrice && dd.LowestDefaultPrice != null && false){ 4296 performanceDates[currentDateIndex].defaultPrice = dd.LowestDefaultPrice; 4297 performanceDates[currentDateIndex].defaultPricingCode = dd.LowestDefaultPricingCode; 4298 } 4299 if(performanceDates[currentDateIndex].secondaryPrice > dd.LowestSecondaryPrice && dd.LowestSecondaryPrice != null){ 4300 performanceDates[currentDateIndex].secondaryPrice = dd.LowestSecondaryPrice; 4301 performanceDates[currentDateIndex].secondaryPricingCode = dd.LowestSecondaryPricingCode; 4302 } 4303 4304 4305 } 4306 //set limited availaibility by matching up results from query with performances 4307 for(perf in data.performances){ 4308 if(data.performances[perf].id == dd.PerformanceID){ 4309 data.performances[perf].LimitedAvailability = dd.LimitedAvailability; 4310 data.performances[perf].TimeZone = dd.TimeZone.replace('"', ""); 4311 data.performances[perf].SingleAreaVenueAreaID = dd.SingleAreaVenueAreaID; 4312 data.performances[perf].NoCouponAvailable = dd.NoCouponAvailable; 4313 data.performances[perf].passwordMatch = dd.passwordMatch; 4314 data.performances[perf].acMatch = dd.acMatch; 4315 data.performances[perf].qualifierPasswordMatch = dd.qualifierPasswordMatch; 4316 data.performances[perf].hasPassword = dd.hasPassword; 4317 data.performances[perf].hasQualifierPassword = dd.hasQualifierPassword; 4318 } 4319 } 4320 } 4321 4322 }) 4323 4324 data.performanceDates = performanceDates; 4325 delete data.performanceDateData; 4326 try { 4327 if (thisCalendar.couponCode != "" && $("#couponCode").length > 0) 4328 { 4329 if($("#coupon-notify").length > 0) 4330 $("#coupon-notify").remove(); 4331 4332 var notifyMessage = document.createElement("div"); 4333 notifyMessage.setAttribute("id","coupon-notify"); 4334 notifyMessage.setAttribute("class",data.hasValidCoupon ? 'coupon-notify-message' : 'coupon-error-message'); 4335 notifyMessage.innerHTML = (data.hasValidCoupon ? "Code <b>" + thisCalendar.couponCode + "</b> has been applied to valid dates and times." : "The code entered is either invalid, or no longer available."); 4336 $("#plCalendar").prepend(notifyMessage); 4337 window.scrollTo(0,0); 4338 } 4339 4340 thisCalendar.doCalendarDetailed(data); 4341 } catch (e) { 4342 console.log("Failed to parse details. Date object not valid: ", data); 4343 console.log(e); 4344 } 4345 }) 4346 .fail(function (jqxhr, textStatus, error) { 4347 var err = textStatus + ", " + error; 4348 console.log("Request Failed: " + err); 4349 }); 4350} 4351swDatepicker.prototype.doCalendarDetailed = function(detailData){ 4352 var thisCalendar = this; 4353 this.detailData = detailData; 4354 var defaultPricingLegend = [], secondaryPricingLegend = [];
4355 detailData.performanceDates.forEach(function(d){ 4356 thisCalendar.addHighlightDay(d.date); 4357 if (d.NoCouponAvailable > 0) 4358 thisCalendar.setCouponMutedDay(d.date); 4359 4360 //check if date sold out 4361 var dateSoldOut = true; 4362 var customStatus = false; 4363 var showPhoneNumber =false; 4364 var dateLimitedAvailability = false; 4365 var performanceStatus=""; 4366 var performanceOnSale = false; 4367 var IsSalesPeriodEnded = false; 4368 var aggregatedMentaInfo = { 4369 buttonVisible: false, 4370 buttonText: "", 4371 buttonUrl: "", 4372 totalCount: 0 4373 }; 4374 4375 var isMentaResaleAvailable = false; 4376 var performanceTimesLength = 0; 4377 var QualiferButton = false; 4378 d.performances.forEach(function(datePerformance){ 4379 var performanceKey = String(datePerformance).toLowerCase(); 4380 var currentPerformance = detailData.performances[performanceKey]; 4381 4382 if (!currentPerformance) { 4383 var perfIndex = d.performances.indexOf(datePerformance); 4384 if (perfIndex !== -1) { 4385 d.performances.splice(perfIndex, 1); 4386 } 4387 console.log("Date Trimmed, child performance not contained in performance data: " + datePerformance); 4388 return; 4389 } 4390 4391 //let currentPerformance = detailData.performances[String(datePerformance).toLowerCase()]; 4392 performanceTimesLength ++; 4393 4394 if(detailData.performances[String(datePerformance).toLowerCase()] && detailData.performances[String(datePerformance).toLowerCase()].status == "On Sale"){ 4395 dateSoldOut = false; 4396 performanceOnSale=true; 4397 if(currentPerformance.LimitedAvailability == 1) 4398 dateLimitedAvailability = true; 4399 4400 IsSalesPeriodEnded = currentPerformance.IsSalesPeriodEnded==1 4401 } 4402 else{ 4403 4404 if ((currentPerformance.status != "Sold Out") && (currentPerformance.status != "On Sale") ){ 4405 4406 customStatus=true; 4407 performanceStatus=currentPerformance.status; 4408 dateSoldOut = false; 4409 //dateLimitedAvailability=false; 4410 if ( currentPerformance.bSalePhone==1 || currentPerformance.SalePhone==1){ 4411 showPhoneNumber=true; 4412 } 4413 } 4414 var mentaMarketplace = currentPerformance.MentaMarketplace; 4415 var hasMentaOption = currentPerformance.IsMentaEnabled == 1 && mentaMarketplace && mentaMarketplace.buttonVisible; 4416 4417 if (hasMentaOption) { 4418 var availableCount = parseInt(mentaMarketplace.totalCount, 10); 4419 if (!isNaN(availableCount) && availableCount > 0) { 4420 aggregatedMentaInfo.totalCount += availableCount; 4421 } 4422 if (mentaMarketplace.buttonText && aggregatedMentaInfo.buttonText === "") { 4423 aggregatedMentaInfo.buttonText = mentaMarketplace.buttonText; 4424 } 4425 if (mentaMarketplace.buttonUrl && aggregatedMentaInfo.buttonUrl === "") { 4426 aggregatedMentaInfo.buttonUrl = mentaMarketplace.buttonUrl; 4427 } 4428 aggregatedMentaInfo.buttonVisible = true; 4429 dateSoldOut = false; 4430 showPhoneNumber=false; 4431 customStatus=true; 4432 } 4433 } 4434 4435 // If date is sold out or custom status (not 'on sale'), check if qualifier access code or password match 4436 if (dateSoldOut || customStatus) { 4437 if (currentPerformance.acMatch == 1 || (currentPerformance.qualifierPasswordMatch == 1 && currentPerformance.hasQualifierPassword == 1)) { 4438 dateSoldOut = false; 4439 customStatus = false; 4440 performanceOnSale = true; 4441 showPhoneNumber = false; 4442 } 4443 } 4444 // If date is sold out or custom status (not 'on sale'), check if it has a public qualifier -- hasQualifiers is set on CalendarRequests.asp when qualifiers exist for performance 4445 if (currentPerformance.hasQualifiers) { 4446 dateSoldOut = false; 4447 customStatus = false; 4448 performanceOnSale = true; 4449 showPhoneNumber = false; 4450 QualiferButton = true; 4451 // If performance has qualifier but status is "On Sale", do not show "Premium Access" text on calendar date 4452 if (currentPerformance.status == "On Sale") { 4453 QualiferButton = false; 4454 } 4455 4456 } 4457 }) 4458 4459 if (aggregatedMentaInfo.buttonVisible && aggregatedMentaInfo.buttonText === "") { 4460 aggregatedMentaInfo.buttonText = "Official Resale Available"; 4461 } 4462 var hasMentaCtaForDate = aggregatedMentaInfo.buttonVisible && (aggregatedMentaInfo.totalCount > 0 || aggregatedMentaInfo.buttonUrl !== ""); 4463 isMentaResaleAvailable = hasMentaCtaForDate && !performanceOnSale; 4464 d.MentaMarketplace = aggregatedMentaInfo; 4465 4466 if(dateLimitedAvailability && !dateSoldOut){ 4467 thisCalendar.setDayLimitedAvailabilty(d.date); 4468 } 4469 if (thisCalendar.isMultiplePerformanceIndicator == 1 && performanceTimesLength > 1) { 4470 thisCalendar.setMultiplePerformanceTimes(d.date); 4471 } 4472 if ( IsSalesPeriodEnded) { 4473 performanceStatus=d.SaleIcon; 4474 } 4475 else{ 4476 if(isMentaResaleAvailable && !performanceOnSale){ 4477 4478 thisCalendar.addDateSubNote(d.date, 'Sold Out'); 4479 //thisCalendar.setDaySoldOut(d.date); 4480 //thisCalendar.addDateInfoBox(d.date, "Sold Out"); 4481 thisCalendar.configureMentaSettings(d); 4482 } 4483 else{ 4484 performanceStatus=d.BSaleIcon; 4485 } 4486 4487 } 4488 4489 if (performanceStatus == null || performanceStatus == "") 4490 performanceStatus="sold out"; 4491 4492 if(dateSoldOut){ 4493 thisCalendar.setDaySoldOut(d.date); 4494 }else{ 4495 if ( (customStatus && !dateLimitedAvailability && !performanceOnSale && !isMentaResaleAvailable) || IsSalesPeriodEnded) 4496 { 4497 thisCalendar.setcustomStatus(d.date,showPhoneNumber,performanceStatus) 4498 } 4499 else{ 4500 //date not sold out, add details, add to legend if one exists 4501 var detailString = ""; 4502 4503 // if the price option is checked in event landing page in the admin 4504 if(d.CalendarViewShowPrice != 0){ 4505 //for now, we'll just add the pricing, this would be a spot to modify what is displayed on the dates by changing the contents of this string 4506 if(d.defaultPrice != null){ 4507 if (QualiferButton) { // SHOWDEV-22142 - If date has public qualifier, show qualifier text (Premium Access) instead of price and buy button 4508 detailString = detailString + "<span class='display-perfbuybutton'>Premium Access</span>"; 4509 }else { 4510 4511 detailString = "<span class='display-perfprice'>" + thisCalendar.currencySymbol + d.defaultPrice.toFixed(2).replace('.00','') + "</span>"; 4512 4513 } 4514 4515 if(defaultPricingLegend.indexOf(d.defaultPricingCode) === -1) 4516 defaultPricingLegend.push(d.defaultPricingCode); 4517 } 4518 if(d.secondaryPricingCode != "" && d.secondaryPricingCode != null){ 4519 if(secondaryPricingLegend.indexOf(d.secondaryPricingCode) === -1) 4520 secondaryPricingLegend.push(d.secondaryPricingCode); 4521 4522 if (d.DisplayType === "calendar" || d.DisplayType === "streamlined") { 4523 4524 detailString = "<span class='display-perfprice-withchild'>" + thisCalendar.currencySymbol + d.secondaryPrice.toFixed(2).replace('.00','') + "/</span>" + detailString; 4525 4526 } 4527 } 4528 } 4529 if(d.CalendarViewShowPerformanceName != 0){ 4530 detailString = detailString + "<span class='display-perfname'>" + d.PerformanceName + "</span> "; 4531 } 4532 4533 if(d.CalendarViewShowPerformanceTime != 0){ 4534 if(d.PerformanceStartTimeAlias != ""){ // Performance Alias time is present 4535 detailString = detailString + " <span class='display-perft
4535ime'>" + d.PerformanceStartTimeAlias + "</span>"; 4536 } else { 4537 detailString = detailString + " <span class='display-perftime'>" + d.PerformanceTime + "</span>"; 4538 } 4539 4540 } 4541 if(d.CalendarViewShowBuyButton != 0){ 4542 var styleString = ""; 4543 if (d.DisplayType === "streamlined") 4544 styleString = " style='width: 100%;'"; 4545 var buttonText = (isMentaResaleAvailable && d.OverrideBuyTicketsButtonText) ? d.OverrideBuyTicketsButtonText : thisCalendar.buyTicketsButtonText; 4546 detailString = detailString + "<span class='button display-perfbuybutton'"+styleString+">" + buttonText + "</span>"; 4547 } 4548 4549 thisCalendar.addDateInfoBox(d.date, detailString); 4550 } 4551 } 4552 4553 }) 4554 //for now, we only generate the legend if there are one or two prices pesent 4555 if(defaultPricingLegend.length === 1 && secondaryPricingLegend.length === 1){ 4556 $("#calendarLegend").html(secondaryPricingLegend[0] +" / " + defaultPricingLegend[0]) 4557 4558 $("#calendarLegend").show(); 4559 }else{ 4560 if(defaultPricingLegend.length === 1){ 4561 $("#calendarLegend").html(defaultPricingLegend[0]) 4562 4563 $("#calendarLegend").show(); 4564 }else{ 4565 $("#calendarLegend").hide(); 4566 } 4567 } 4568 if(typeof(setFilterOptions) == 'function'){ 4569 setFilterOptions(thisCalendar); 4570 } 4571 if (detailData.hasValidCoupon) { 4572 $("#plCalendar").append("<input type='hidden' id='hasValidCoupon' value='1' />"); 4573 } else { 4574 $("#plCalendar").append("<input type='hidden' id='hasValidCoupon' value='0' />"); 4575 } 4576 $(".calendar-loading").hide(); 4577} 4578swDatepicker.prototype.configureMentaSettings = function (dateDetail) { 4579 // Set Menta Resale Settings 4580 4581} 4582 4583swDatepicker.prototype.getFirstDate = function(defaultMonth){ 4584 var thisCalendar = this; 4585 //this should only happen once on calendar load - currently only enabled for bundles 4586 if(thisCalendar.bundleID == 0 || thisCalendar.bundleID == -1) 4587 return defaultMonth; //currently only developed for bundles TODO: add event, category, standard support. 4588 4589 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 4590 { 4591 action: 'initialBundleDate', 4592 iBundle: thisCalendar.bundleID, 4593 cp : thisCalendar.corporatePartnerPage 4594 }) 4595 .done(function (data) { 4596 try { 4597 if (data.performancedates.length > 0) { 4598 4599 4600 var firstMonth = Number(String(data.performancedates).split("/")[0]) - 1; 4601 var firstYear = Number(String(data.performancedates).split("/")[2]); 4602 thisCalendar.month = firstMonth - 1; //to make this simple, we're using the showNextMonth() function, which means we need to set the month to 1 less than our target, as that function increments the month itself 4603 thisCalendar.year = firstYear; 4604 thisCalendar.showNextMonth(); 4605 }else{ 4606 return defaultMonth; 4607 } 4608 }catch(e){ 4609 console.log("getFirstDate returned invalid date. Default used"); 4610 console.log(e); 4611 return defaultMonth; 4612 } 4613 }) 4614 .fail(function (jqxhr, textStatus, error) { 4615 var err = textStatus + ", " + error; 4616 console.log("Request Failed: " + err); 4617 }); 4618} 4619swDatepicker.prototype.fetchLocalDates = function () { 4620 //utliize storage to store months 4621 var CalendarExpireTime = new Date().getTime(); var isExpired = false; var datesData = ""; 4622 var calendarIDString = this.calendarName + this.type + this.eventID + this.bundleID + "-" + this.corporatePartnerPage + "_" + this.activeMonth; 4623 try { 4624 //check for local storage support 4625 isExpired = CalendarExpireTime > Number(localStorage.getItem("CalendarExpireTime_" + calendarIDString)); 4626 if (isExpired) { 4627 //item expired, clear local results 4628 localStorage.setItem("ShowareDates_" + calendarIDString, ""); 4629 localStorage.setItem("CalendarExpireTime_" + calendarIDString, CalendarExpireTime + (1000 * 60 * 30)); //item information expires after 30 minutes 4630 return false; 4631 } 4632 localStorage.setItem("CalendarExpireTime_" + calendarIDString, CalendarExpireTime + (1000 * 60 * 30)); //item information expires after 30 minutes 4633 if (localStorage.getItem("ShowareDates_" + calendarIDString) != null && localStorage.getItem("ShowareDates_" + calendarIDString) != "" && localStorage.getItem("ShowareDates_" + calendarIDString) != []) { 4634 return localStorage.getItem("ShowareDates_" + calendarIDString); 4635 } else { 4636 //date info not stored 4637 return false; 4638 } 4639 } catch (e) { 4640 return false; 4641 } 4642} 4643swDatepicker.prototype.storeDates = function (dateData) { 4644 4645 var calendarIDString = this.calendarName + this.type + this.eventID + this.bundleID + "-" + this.corporatePartnerPage + "_" + this.activeMonth; 4646 try { 4647 localStorage.setItem("ShowareDates_" + calendarIDString, JSON.stringify(dateData)); 4648 } catch (e) { 4649 //no local storage 4650 } 4651} 4652swDatepicker.prototype.getDateRangeEvents = function (dateRangeData) { 4653 var thisCalendar = this; 4654 try{ 4655 $.getJSON("/include/widgets/calendar/calendarRequests.asp", 4656 { 4657 action: 'getDateRangeEvents', 4658 dateRange: JSON.stringify(dateRangeData), 4659 }) 4660 .done(function (data) { 4661 try { 4662 thisCalendar.dateRangeEvents = data; 4663 }catch(e){ 4664 console.log("getDateRangeEvents returned invali
4664d response."); 4665 console.log(data, e); 4666 return []//return empty array; 4667 } 4668 }) 4669 .fail(function (jqxhr, textStatus, error) { 4670 var err = textStatus + ", " + error; 4671 console.log("Request Failed: " + err); 4672 }); 4673 4674 }catch(e){ 4675 console.log("Unable to fetch date range events:", e) 4676 } 4677} 4678swDatepicker.prototype.clearDateRange = function () { 4679 this.fromDateRange = ''; 4680 this.toDateRange = ''; 4681} 4682function fetchDateIndex(dateString, dateObjectArray){ 4683 try{ 4684 for(var i = 0;i < dateObjectArray.length;i++){ 4685 if(dateObjectArray[i].date == dateString){ 4686 return i; 4687 break; 4688 } 4689 } 4690 return -1; 4691 }catch(e){ 4692 //this function requires specific objects with a date property, it will fail otherwise and we'll just return what one would expect from a failed indexof 4693 return -1; 4694 } 4695} 4696function swapMonthDay(d){ 4697 //expects dd/mm/yyyy format 4698 try{ 4699 let splitDate = d.split("/"); 4700 let newDate = splitDate[1] + '/' + splitDate[0] + "/" + splitDate[2]; 4701 return newDate; 4702 }catch(e){ 4703 console.log("could not swap date:",d,e); 4704 return d; 4705 } 4706} 4707 4708</script>
4708 4709<link rel="stylesheet" type="text/css" href="//www.cincyticket.com/include/accessodesign-core-addition.css?ver=20228b0075"> 4710 4711<link rel="stylesheet" type="text/css" href="//www.cincyticket.com/include/style.css?ver=20228b0075"> 4712 4713 <link rel="stylesheet" type="text/css" media="only screen and (max-width: 1024px)" href="//www.cincyticket.com/include/mobile.css?ver=20228b0075"> 4714 4715</head> 4716 4717<body class="body-class default-font"> 4718 4719 <!-- CLIENT Google Tag Manager -->
vendor: 75 bytes, lines 4719-4720
4719 4720 <noscript><iframe src="//www.googletagmanager.com/ns.html?id=
4720GTM-WZ8HC5
vendor: 109 bytes, lines 4720-4722
4720" 4721 height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 4722
4722<!-- End CLIENT Google Tag Manager --> 4723 4724 <!-- PRIMARY Google Tag Manager -->
vendor: 79 bytes, lines 4724-4725
4724 4725 <noscript><iframe src="//www.googletagmanager.com/ns.html?id=
4725GTM-MDGF2K
vendor: 117 bytes, lines 4725-4727
4725" 4726 height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 4727
4727<!-- End PRIMARY Google Tag Manager --> 4728 4729<div style="position:relative;"> 4730<button class="skip-nav" title="Skip to Main Content">Skip to Main Content</button> 4731</div>
4732<script type="text/javascript"> 4733 $(function(){ 4734 $(".main-container").attr("tabindex", 0); 4735 }) 4736 $(".skip-nav").on("click", function(){ 4737 console.log("s"); 4738 $(".main-container").focus(); 4739 }); 4740</script>
4740 4741
4742<script type="text/javascript"> 4743 window.SW_ADS_CONFIG = { 4744 cacheUrl: "//www.cincyticket.com/data/adLocations/adLocationCache.txt?ver=20228", 4745 writerUrl: "https://www.cincyticket.com/include/modules/Advertising/request/saveAdLocationCache.asp", 4746 logUrl: "https://www.cincyticket.com/include/modules/Advertising/request/logAdImpression.asp" 4747 }; 4748</script>
vendor: 2 bytes, line 4748
4748
4749<script type="text/javascript" src="//www.cincyticket.com/include/modules/Advertising/banner-ads.js?ver=20228"></script>
4749 4750 4751 4752 4753 <div id="page-wrap"><!--Main Page Wrap - Ends in HTMLfooter--> 4754 <div id="fb-root"></div> 4755 4756
4756<script> 4757 (function(d, s, id) { 4758 var js, fjs = d.getElementsByTagName(s)[0]; 4759 if (d.getElementById(id)) return; 4760 js = d.createElement(s); js.id = id; 4761 js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=0"; 4762 fjs.parentNode.insertBefore(js, fjs); 4763 }(document, 'script', 'facebook-jssdk')); 4764 </script>
4764 4765 4766 4767 <!-- BEGIN Mobile Navigation BEGIN --> 4768 <nav class="navigation sw-nav mobile-only"> 4769 <i id="menu-icon" class="sw-icon-menu" style="display:inline-block;" onClick="actMenu();hideWidgets();"></i> 4770 <div class="tab-nav-wrap"> 4771 4772 <a class="tab-nav" HREF="https://www.cincyticket.com/myaccount.asp?gifrompage=1&gitopage=1">my account</a> 4773 </div> 4774 <ul id="mobile-menu" onClick="actMenu();"> 4775 <!--<li><a HREF="/">home</a></li> <!--CLIENT Home URL--> 4776 <li><a HREF="https://www.cincyticket.com/default.asp">ticketing home</a></li> 4777 <li class="mobile-only"><a HREF="https://www.cincyticket.com/myaccount.asp?gifrompage=1&gitopage=1">my account</a></li> 4778 <li class="sw-sep mobile-only"></li> 4779 4780 <li class="sw-sep no-tab"></li> 4781 4782 <li><a onClick="actSearch();actMenu();return 0">search</a></li> 4783 4784 <li class="mobile-calendar-option"><a onClick="actWidget('calendar');return 0;">calendar</a></li> 4785 4786 <li><a onClick="actWidget('categories');return 0;">categories</a></li> 4787 4788 <li><a onClick="actWidget('venues');return 0;">venues</a></li> 4789 4790 <li class="sw-sep"></li> 4791 <li><a HREF="https://www.cincyticket.com/basket.asp">shopping cart</a></li> 4792 4793 <li class="sw-sep"></li> 4794 <li><a href="https://www.cincyticket.net/help">contact us</a></li> 4795 <li><a href="https://www.cincyticket.net/faq">FAQ</a></li> 4796 <li><a href="https://www.cincyticket.net/">Sell Tickets With Us</a></li> 4797 <li class="sw-sep"></li> 4798 <li onClick="actMenu();hideWidgets();"><a >close</a></li> 4799 </ul> 4800 <a style="color:inherit;" href="http://www.cincyticket.com/basket.asp"><i class="sw-icon-basket" style="float:right;"></i></a> 4801 4802 <i class="sw-icon-search" style="float:right;" onClick="actSearch();"></i> 4803 <div id="swSearch" style="display:none;"> 4804 <input type="text" id="swSearchTxt" value="" placeholder="search events, venues, artists etc..." /> 4805
4805<script type="text/javascript"> 4806 $('#swSearchTxt').keyup(function (e) { 4807 if (e.which === 13) { 4808 //update the performance list 4809 updatePerformanceList_Search($("#swSearchTxt").val()) 4810 } 4811 }) 4812 4813 </script>
4813 4814 </div> 4815 4816 </nav> 4817 <!--END Mobile Navigation END --> 4818 <header class="mobile-header mobile-only"> 4819 <!--custom branding location for mobile --> 4820 <!--Header Ads can be placed here if client desires: 4821 <div class='sw-banner-ad' data-sw-ad-location='header_mobile'></div> 4822 --> 4823 <a href="https://www.cincyticket.com/"><img src="../Images/mobile-logo.png"></a> 4824 </header> 4825
4825<script type="text/javascript"> 4826 $(function () { 4827 $(".control-box").append("<a class='close-widget mobile-only' onclick='hideWidgets()'>close</a>"); 4828 }) 4829 </script>
4829 4830 4831 <header class="head-wrap no-mobile"> 4832 <!--This header will not be present on mobile. Use the mobile header area if a branding location for mobile is required.--> 4833 <div class="head-inner center-div site-width"> 4834 <a href="https://www.cincyticket.com/"><img src="../Images/top_header.jpg" border="0" hidefocus="true" style="width: 100%;"></a> 4835 4836 <div class="clear-float"></div> 4837 <div class="nav-container"> 4838 <ul class="showare-nav"> 4839 <li><img src="../Images/left_nav.gif" border="0" usemap="#Map2" hidefocus="true"> 4840 <map name="Map2"> 4841 <area shape="rect" coords="8,4,84,22" href="http://www.cincyticket.com/default.asp"> 4842 <area shape="rect" coords="119,4,178,23" href="https://www.cincyticket.net/faq"> 4843 <area shape="rect" coords="217,4,336,23" href="https://www.cincyticket.net/help"> 4844 <area shape="rect" coords="370,4,550,23" href="https://www.cincyticket.net/"></map> 4845 </li> 4846 <li class="basket-widget"><div id="ShoWareBasketWidget" class="internal"></div></li> 4847 <li style="float: right;"><a href="http://www.cincyticket.com/myaccount.asp?gifrompage=1&gitopage=1"><img src="../Images/nav-account.gif"></a></li> 4848 </ul> 4849 <div class="clear-float"></div> 4850 </div> 4851 4852 </div><!--END head-inner END--> 4853 </header><!--END head-wrap END--> 4854 4855 4856 4857 4858 <!--MAIN BODY--> 4859 <div class="content-wrap"><!--Main Content Wrap - this and content-inner end in HTMLfooter--> 4860 <div class="content-inner center-div site-width"> 4861 4862 <!--LEFT SIDE--> 4863 <div class="control-wrap show-wrap"> 4864 4865 <div class="control-box search-control"> 4866 <span class="heading-text">Search</span> 4867 <!--<img src="images/hdrCategories.gif" width="162" height="20" alt="" border="0"><br>--> 4868 4869<input class="search-text showare-text" type="text" size="16" name="SearchText" value="" placeholder="search..."><input id="searchButton" class="search-button; " type="button" name="Go" value="Go"/>
4870<script language="javascript"> 4871 $('.search-text').keyup(function(e) { 4872 if(e.which === 13){ 4873 //update the performance list 4874 4875 updatePerformanceList_Search($(".search-text").val()); 4876 4877 } 4878 }) 4879 $("#searchButton").click(function(){ 4880 4881 updatePerformanceList_Search($(".search-text").val()) 4882 4883 }); 4884 function updatePerformanceList_Search(searchVal) { 4885 4886 $(".featured-wrap").hide(); 4887 $(".pl-wrap").show(); 4888 clearPerformanceList(); 4889 performanceListArgs.searchString = searchVal; 4890 doPerformanceList(); 4891 updatePage(null, ["search"], [searchVal], {"performanceList": performanceListArgs}); 4892 4893 } 4894 function updateStreamlinedEventList_Search(searchVal) { 4895 4896 $("input[name='search']").val(searchVal); 4897 4898 // Remove any existing search filter-item from list 4899 $('.filter-item').each(function(ind) { 4900 if ($(this).data("filtertype") == "search") 4901 $(this).remove(); 4902 }); 4903 4904 // Create a new filter item span with close button 4905 // (built via safe DOM APIs so searchVal can never be interpreted as HTML) 4906 var filterItem = $('<span>', { "class": "filter-item", "data-filtertype": "search" }); 4907 filterItem.append(document.createTextNode("Search: '" + searchVal + "' ")); 4908 filterItem.append($('<span>', { "class": "close-option" }).text("x")); 4909 $('.options-wrap').append(filterItem); 4910 4911 toggleViewAllButton(); 4912 4913 updateEventList(); 4914 4915 } 4916</script>
4916 4917 </div> 4918 4919 <div id="categoriesWidget" class="control-box categories-control"> 4920 <span class="heading-text">Categories</span> 4921 <!--<img src="images/hdrCategories.gif" width="162" height="20" alt="" border="0"><br>--> 4922 4923 4924<select id="categorySelect" class="showare-select" aria-label="Select a Category"> 4925 <option value="0">Select a Category</option> 4926</select>
4927<script language="javascript"> 4928 var CategoriesExpireTime = new Date().getTime(); var isExpired = false; var CategoriesData = ""; 4929 try { 4930 //check for local storage support 4931 isExpired = CategoriesExpireTime > Number(localStorage.getItem("CategoriesExpireTime")); 4932 if(isExpired){ 4933 //item expired, clear local results 4934 localStorage.setItem("ShoWareCategories", ""); 4935 } 4936 localStorage.setItem("CategoriesExpireTime", CategoriesExpireTime + (1000 * 60 * 60 * 24)); //item information expires after 24 hours 4937 CategoriesData = localStorage.getItem("ShoWareCategories"); 4938 } catch(e){ 4939 CategoriesData = ""; 4940 } 4941 function getCategories(){ 4942 //attempt to get local data for widget 4943 if(CategoriesData == "" || CategoriesData == null){ 4944 //no data found, pull data from request 4945 $.getJSON("https://www.cincyticket.com/include/widgets/controls/RequestCategories.asp") 4946 .done(function (data) { 4947 //build select box 4948 populateCategories(data); 4949 try{ 4950 localStorage.setItem("ShoWareCategories",JSON.stringify(data)); 4951 }catch(e){ 4952 console.log("No local storage"); 4953 } 4954 }) 4955 .fail(function (jqxhr, textStatus, error) { 4956 var err = textStatus + ", " + error; 4957 console.log("Request Failed: " + err); 4958 }) 4959 }else{ 4960 CategoriesData = JSON.parse(CategoriesData); 4961 populateCategories(CategoriesData); 4962 } 4963 } 4964 function populateCategories(categoryOptions){ 4965 oSelect = document.getElementById("categorySelect"); 4966 for(var i = 0; i < categoryOptions.length; i++){ 4967 //add an option for each category in data 4968 if (categoryOptions[i].CatActive == 1 && categoryOptions[i].IsHidden != 1) 4969 { 4970 var opt = document.createElement("option"); 4971 opt.value = categoryOptions[i].ID; 4972 if(categoryOptions[i].Rank == 1){ 4973 opt.innerHTML = categoryOptions[i].Name; 4974 opt.style.fontWeight = "bold"; 4975 }else{ 4976 opt.innerHTML = " " + categoryOptions[i].Name; 4977 } 4978 oSelect.appendChild(opt); 4979 } 4980 } 4981 $("#categorySelect").val(0); 4982 } 4983 getCategories(); 4984 var gCategoryVal = 0 4985 $("#categorySelect").change(function(){ 4986 updatePerformanceList_Category($(this).val()) 4987 gCategoryVal = $(this).val(); 4988 }); 4989 function updatePerformanceList_Category(categoryVal) { 4990 4991 //performance list display style 4992 $(".pl-wrap").hide(); 4993 $(".featured-wrap").show(); 4994 clearEventList(); 4995 eventListArgs.category = categoryVal; 4996 doEventList(); 4997 updatePage(null, ["category"], [categoryVal], {"eventList": eventListArgs}); 4998 4999 } 5000 5001 var headerDP = ""; 5002 if ($("#categorySelect").length == 0 || 'True' == 'False'){ 5003 headerDP = buildDatepicker({ "calendarID": "headerCalendar", "linkedInputID": "headerCalendarInput", "isModal": false, "forceDates": true, "defaultDate": "9/1/2026"}); 5004 } 5005 function updateCalendarDateByCategory(categoryVal) 5006 { 5007 5008 if ($("#categorySelect").length > 0) 5009 { 5010 if (headerDP == "") 5011 headerDP = buildDatepicker({ "calendarID": "headerCalendar", "linkedInputID": "headerCalendarInput", "isModal": false, "forceDates": true, "CategoryID": gCategoryVal, "defaultDate": "9/1/2026"}); 5012 else 5013 { 5014 headerDP.clearHighlightDays(); 5015 headerDP.categoryID = categoryVal; 5016 headerDP.fetchDates(); 5017 } 5018 } 5019 5020 5021 5022 } 5023</script>
5023 5024 </div> 5025 5026 <div id="calendarWidget" class="control-box calendar-control"> 5027 <span class="heading-text">Browse Dates</span> 5028 <!--<img src="images/hdrDates.gif" width="162" height="20" alt="" border="0"><br>--> 5029 5030<input type="hidden" id="headerCalendarInput" value=""/> 5031<div id="headerCalendar" class="sw-datepicker"><link rel="stylesheet" href="/include/font-awesome/css/font-awesome.min.css" /> 5032<div tabindex="0" class="calendar-object" style="position:relative;"> 5033 <style type="text/css" scoped> 5034 .sw-datepicker 5035 { 5036 font-size:inherit;/*Calendar size is determined by parent's font size.*/ 5037 } 5038 .sw-datepicker.large-datepicker 5039 { 5040 margin-top: 20px; 5041 } 5042 .sw-datepicker[aria-hidden=true] 5043 { 5044 display:none; 5045 } 5046 5047 .sw-datepicker.is-modal{ 5048 margin: 10px; 5049 padding: 2px; 5050 -webkit-border-radius: 4px; 5051 -moz-border-radius: 4px; 5052 border-radius: 4px; 5053 position: absolute; 5054 top:30px; 5055 left:0px; 5056 z-index:99; 5057 background-color: #fff; 5058 border: 1px solid #ccc; 5059 box-shadow: 0px 0px 6px RGBA(0,0,0,0.4); 5060 } 5061 .sw-datepicker.is-modal.right-side 5062 { 5063 left:auto; 5064 right:0px; 5065 } 5066 .sw-datepicker .month-wrap 5067 { 5068 background-color: #337ab7; 5069 border: 1px solid #2e6da4; 5070 -webkit-border-radius: 4px; 5071 -moz-border-radius: 4px; 5072 border-radius: 4px; 5073 text-align:center; 5074 } 5075 .sw-datepicker .bn_next, div.bn_prev{ 5076 margin: 2px; 5077 border:1px solid transparent; 5078 line-height:1.3em; 5079 color:#fff; 5080 padding:0 .25em; 5081 font-weight:bold; 5082 cursor:pointer; 5083 } 5084 .sw-datepicker .bn_prev 5085 { 5086 float: left; 5087 } 5088 5089 .sw-datepicker .bn_next 5090 { 5091 float: right; 5092 } 5093 5094 .sw-datepicker .bn_prev:hover, 5095 .sw-datepicker .bn_prev:focus, 5096 .sw-datepicker .bn_next:hover, 5097 .sw-datepicker .bn_next:focus 5098 { 5099 margin: 2px; 5100 background-color: #4fbae0; 5101 border: 1px solid #00a4df; 5102 -webkit-border-radius: 4px; 5103 -moz-border-radius: 4px; 5104 border-radius: 4px; 5105 } 5106 5107 .sw-datepicker .bn_img 5108 { 5109 margin: 0; 5110 padding: 2px; 5111 } 5112 5113 .sw-datepicker .month 5114 { 5115 display:inline-block; 5116 line-height:1.5em; 5117 font-weight: bold; 5118 font-size: 1.2em; 5119 color:#fff; 5120 } 5121 5122 .sw-datepicker .cal 5123 { 5124 font-size: 1.2em; 5125 text-align: center; 5126 } 5127 5128 5129 .sw-datepicker .offscreen 5130 { 5131 position: absolute; 5132 left: -200em; 5133 top: -100em; 5134 } 5135 .sw-datepicker td.day-cell.highlight-day{ 5136 cursor:pointer; 5137 } 5138 td span.calendar-day{ 5139 display:inline-block; 5140 height:1.5em; 5141 width:1.5em; 5142 line-height:1.5em; 5143 border-radius:3px; 5144 margin:.1em; 5145 position:relative; 5146 } 5147 td.highlight-day span.calendar-day{ 5148 border:1px solid #337ab7; 5149 background:#fcfcfc; 5150 color:#00458A; 5151 cursor:pointer; 5152 } 5153 td.limited-availability:after{ 5154 content:'!'; 5155 display:inline-block; 5156 font-weight:bold; 5157 position:absolute; 5158 top:3px; 5159 right:5px; 5160 font-size:3vw; 5161 color:#aa0; 5162 } 5163 .sw-datepicker abbr{ 5164 text-decoration:none; 5165 opacity:1; 5166 display:inline-block; 5167 margin:.3em 0; 5168 } 5169 td.today{ 5170 background:#eee; 5171 } 5172 td.focus{ 5173 background:#8ecae0; 5174 } 5175 .sw-datepicker td{ 5176 position:relative; 5177 } 5178 .sw-datepicker.large-datepicker, .sw-datepicker.large-datepicker table{ 5179 width:100%; 5180 } 5181 .sw-datepicker.large-datepicker .month-wrap{ 5182 font-size:1.5em; 5183 background:RGBA(255,255,255,0.0); 5184 border:none; 5185 border-bottom:1px solid #eee; 5186 } 5187 .sw-datepicker.large-datepicker .month-wrap *{ 5188 color:inherit!important; 5189 } 5190 .sw-datepicker.large-datepicker .day-cell{ 5191 height:8vh; 5192 width:14%; 5193 border:1px solid #eee; 5194 opacity:.7; 5195 transition:opacity .5s; 5196 } 5197 .sw-datepicker.large-datepicker .day-cell.highlight-day{ 5198 opacity:1; 5199 } 5200 .sw-datepicker.large-datepicker td span.calendar-day{ 5201 position:absolute; 5202 top:5px; 5203 left:5px; 5204 font-size:.7em; 5205 text-align:center; 5206 font-weight:bold; 5207 height:2em; 5208 width:2em; 5209 padding:.25em; 5210 line-height:1.3em; 5211 display:inline-block; 5212 background:RGBA(255,255,255,0.0); 5213 border:none; 5214 pointer-events:none; 5215 } 5216 .sw-datepicker .date-info-box{ 5217 font-size: 1.5vw; 5218 padding: 30px 5px 15px; 5219 display: block; 5220 position: relative; 5221 } 5222 .sw-datepicker .date-info-box .display-perfstatus{ 5223 font-size: .72vw; 5224 display: block; 5225 text-align: center!important; 5226 padding: 5px 10px; 5227 border: 1px solid var(--gap-error); 5228 border-radius: 8px; 5229 color: var(--gap-error); 5230 width: 90%; 5231 margin: auto; 5232 box-sizing: border-box; 5233 background: rgba(222,27,60,.05); 5234 } 5235 .sw-datepicker .date-info-box .display-perfprice{ 5236 font-size: 1vw; 5237 } 5238 .sw-datepicker .date-info-box .display-perfprice-withchild{ 5239 font-size: 1vw; 5240 } 5241 .sw-datepicker .date-info-box .display-perfname{ 5242 font-size: .8vw; 5243 display: block; 5244 text-align: center; 5245 padding: 0px 10px; 5246 5247 }
5248 .sw-datepicker .date-info-box .display-perftime{ 5249 font-size: .93vw; 5250 display: block; 5251 padding-top: 5px; 5252 } 5253 .sw-datepicker .date-info-box .display-perfbuybutton{ 5254 font-size: .7vw; 5255 display: block; 5256 padding: 5px 10px; 5257 width: 90%; 5258 margin: 5px auto; 5259 } 5260 .sw-datepicker .date-sub-note{ 5261 font-style: italic; 5262 font-size: .93vw; 5263 opacity: .8; 5264 position: absolute; 5265 bottom: auto; 5266 top: 0px; 5267 padding-bottom: 20px; 5268 padding-top: 15px; 5269 margin-bottom: 30px; 5270 width: 100%; 5271 } 5272 @media only screen and (max-width: 1500px){ 5273 .sw-datepicker .date-info-box .display-perfname{ 5274 font-size: 1.1vw; 5275 } 5276 .sw-datepicker .date-info-box .display-perftime, 5277 .sw-datepicker .date-info-box .display-perfprice, 5278 .sw-datepicker .date-info-box .display-perfprice-withchild{ 5279 font-size: 1.2vw; 5280 } 5281 .sw-datepicker .date-info-box .display-perfbuybutton{ 5282 font-size: 1vw; 5283 } 5284 } 5285 @media only screen and (max-width: 1300px){ 5286 .sw-datepicker .date-info-box .display-perfname{ 5287 font-size: 1.3vw; 5288 } 5289 .sw-datepicker .date-info-box .display-perftime, 5290 .sw-datepicker .date-info-box .display-perfprice, 5291 .sw-datepicker .date-info-box .display-perfprice-withchild{ 5292 font-size: 1.3vw; 5293 } 5294 } 5295 @media only screen and (max-width: 1024px){ 5296 .sw-datepicker .date-sub-note{ 5297 display:none!important; 5298 } 5299 .sw-datepicker .date-info-box .display-perfname{ 5300 font-size: 12px; 5301 } 5302 .sw-datepicker .date-info-box .display-perftime, 5303 .sw-datepicker .date-info-box .display-perfprice, 5304 .sw-datepicker .date-info-box .display-perfprice-withchild{ 5305 font-size: 12px; 5306 } 5307 .sw-datepicker .date-info-box .display-perfbuybutton{ 5308 font-size: 12px; 5309 white-space: unset; 5310 line-height: 1.2; 5311 } 5312 /* adjustment for coupon codes on mobile*/ 5313 .couponecode-wrap { 5314 display: flex; 5315 flex-direction: row-reverse; 5316 align-items: stretch; 5317 flex-wrap: nowrap; 5318 gap: 20px; 5319 width: 100%; 5320 } 5321 #FilterSelect { 5322 margin-bottom: 8px; 5323 } 5324 #couponCodeSubmitButton { 5325 margin-top: 0; 5326 } 5327 #couponCode { 5328 flex: 1; 5329 height: auto; 5330 } 5331 } 5332 @media only screen and (max-width: 800px){ 5333 .sw-datepicker.large-datepicker .day-cell { 5334 height: auto!important; 5335 width: 14%; 5336 min-height: 50px; 5337 border: 1px solid #eee; 5338 opacity: .7; 5339 transition: opacity .5s; 5340 } 5341 .sw-datepicker.large-datepicker table td.empty, 5342 .sw-datepicker.large-datepicker table th { 5343 width: 14%; 5344 min-width: 14%; 5345 } 5346 .sw-datepicker .date-info-box .display-perfbuybutton { 5347 width: 100%; 5348 line-height: 1.1!important; 5349 font-size: 11px!important; 5350 white-space: unset; 5351 padding: 5px!important; 5352 } 5353 .sw-datepicker .date-info-box .display-perftime, 5354 .sw-datepicker .date-info-box .display-perfprice, 5355 .sw-datepicker .date-info-box .display-perfprice-withchild, 5356 .sw-datepicker .date-info-box .display-perfname{ 5357 font-size: 11px; 5358 5359 } 5360 .sw-datepicker table tr { 5361 display: flex; 5362 justify-content: space-evenly; 5363 } 5364 .sw-datepicker .date-info-box .display-perfname{ 5365 padding: 5px 0px 0; 5366 } 5367 .sw-datepicker .date-info-box { 5368 overflow-wrap: normal; 5369 } 5370 .sw-datepicker.large-datepicker table td.empty, 5371 .sw-datepicker.large-datepicker table th, 5372 .sw-datepicker table td.empty, 5373 .sw-datepicker table th 5374 { 5375 width: calc((100% / 7) - 4px); 5376 min-width: 10%; 5377 } 5378 .sw-datepicker.large-datepicker .day-cell, 5379 .sw-datepicker .day-cell { 5380 width: calc((100% / 7) - 4px); 5381 } 5382 .sw-datepicker .day-cell.sold-out{ 5383 padding-top: 35px!important; 5384 line-height: 1.2!important; 5385 } 5386 } 5387 @media only screen and (max-width: 550px){ 5388 #epPerformanceList #eventCalendar { 5389 width: 100%; 5390 } 5391 .sw-datepicker .date-info-box .display-perfbuybutton { 5392 font-size: 7px!important; 5393 font-weight: 400!important; 5394 }
5395 .sw-datepicker .date-info-box .display-perftime, 5396 .sw-datepicker .date-info-box .display-perfprice, 5397 .sw-datepicker .date-info-box .display-perfprice-withchild, 5398 .sw-datepicker .date-info-box .display-perfname{ 5399 font-size: 10px; 5400 5401 } 5402 .sw-datepicker .day-cell.sold-out{ 5403 padding-top: 30px!important; 5404 line-height: .9!important; 5405 } 5406 .sw-datepicker.large-datepicker table tr{ 5407 display: flex; 5408 justify-content: space-evenly; 5409 } 5410 .sw-datepicker.large-datepicker table td.empty, 5411 .sw-datepicker.large-datepicker table th, 5412 .sw-datepicker.large-datepicker table td, 5413 .sw-datepicker.large-datepicker .day-cell { 5414 width: calc(96vw / 7); 5415 } 5416 #TimeSelectModalBody { 5417 width: 100%!important; 5418 } 5419 } 5420 .sw-datepicker .day-cell.sold-out{ 5421 opacity:.7!important; 5422 color:#a00; 5423 pointer-events:none; 5424 } 5425 .sw-datepicker .day-cell.muted{ 5426 opacity:.3!important; 5427 } 5428 5429 .sw-datepicker .day-cell.coupon-muted{ 5430 opacity:.3!important; 5431 } 5432 5433 .sw-datepicker .day-cell.password-hidden .date-info-box{ 5434 display: none!important; 5435 } 5436 5437 .sw-datepicker .day-cell.muted .calendar-day{ 5438 color:inherit!important; 5439 border:none!important; 5440 cursor:default!important; 5441 } 5442 5443 .sw-datepicker .day-cell.coupon-muted .calendar-day{ 5444 color:inherit!important; 5445 border:none!important; 5446 } 5447 .sw-datepicker .day-cell.sold-out .date-info-box{ 5448 display:none; 5449 } 5450 .sw-datepicker .day-cell.sold-out .calendar-day{ 5451 color:#a00; 5452 border:none; 5453 text-decoration:line-through; 5454 } 5455 @media only screen and (max-width: 1024px){ 5456 .sw-datepicker .date-info-box, .sw-datepicker .sold-out-info-box{ 5457 font-size:2vw; 5458 } 5459 } 5460 .calendar-loading{ 5461 position:absolute; 5462 top:50%; 5463 left:50%; 5464 font-size:4vw; 5465 font-weight:bold; 5466 color:RGBA(0,0,0,0.4); 5467 width:66vw; 5468 margin-left:-33vw; 5469 height:20vw; 5470 margin-top:-10vh; 5471 line-height:20vw; 5472 text-align:center; 5473 background:RGBA(255,255,255,0.9); 5474 border-radius:1em; 5475 border:1px solid RGBA(0,0,0,0.4); 5476 box-shadow:2px 2px 4px RGBA(0,0,0,0.2); 5477 } 5478 .limited-availability-legend-item{ 5479 text-align:right; 5480 } 5481 .calendar-limited-availability-legend-icon{ 5482 font-weight:bold; 5483 color:#aa0; 5484 } 5485 .calendar-dayoftheweek {display: none!important;} 5486 #calendarWidget .calendar-dayoftheweek {display: none!important;} 5487 </style> 5488 5489 <div class="month-wrap"> 5490 <div class="bn_prev" role="button" aria-labelledby="bn_prev-label" tabindex="0" title="Previous Month"><i class="fa fa-backward" aria-hidden="true"></i></div> 5491 <div tabindex="0" class="month" role="heading" aria-live="assertive" aria-atomic="true">Loading...</div> 5492 <div class="bn_next" role="button" aria-labelledby="bn_next-label" tabindex="0" title="Next Month"><i class="fa fa-forward" aria-hidden="true"></i></div> 5493 </div> 5494 <table title="Search Date - Select a date to search" class="cal" role="grid" aria-labelledby="month" tabindex="0" style="margin: 0px auto;outline:none!important;"> 5495 <thead> 5496 <tr class="weekdays"> 5497 <th class="Sunday"><abbr title="Sunday">Su</abbr></th> 5498 <th class="Monday"><abbr title="Monday">Mo</abbr></th> 5499 <th class="Tuesday"><abbr title="Tuesday">Tu</abbr></th> 5500 <th class="Wednesday"><abbr title="Wednesday">We</abbr></th> 5501 <th class="Thursday"><abbr title="Thursday">Th</abbr></th> 5502 <th class="Friday"><abbr title="Friday">Fr</abbr></th> 5503 <th class="Saturday"><abbr title="Saturday">Sa</abbr></th> 5504 </tr> 5505 </thead> 5506 <tbody> 5507 <tr><td class="errMsg" colspan="7">Loading...</td></tr> 5508 </tbody> 5509 </table> 5510 <div class="bn_prev-label offscreen">Go to previous month</div> 5511 <div class="bn_next-label offscreen">Go to next month</div> 5512 <div class="calendar-loading" style="display:none;"><i class="fa fa-spin fa-spinner" style="margin-right:.5em;"></i>Loading...</div> 5513</div> 5514<div class="calendar-notes-wrap"></div> 5515</div>
5516<script type="text/javascript"> 5517 var headerDP = ""; 5518 if ($("#categorySelect").length == 0 || 'True' == 'False') 5519 headerDP = buildDatepicker({ "calendarID": "headerCalendar", "linkedInputID": "headerCalendarInput", "isModal": false, "forceDates": true, "defaultDate": "9/1/2026", "corporatePartnerPage":0}); 5520 $("#headerCalendarInput").on("change", function () { 5521 var properDate = /^\d{1,2}\/\d{1,2}\/\d{4}$/; 5522 if (!properDate.test($(this).val())) { 5523 console.log("Main calendar attempted an invalid date: " + $(this).val()); 5524 return;//invalid date 5525 } 5526 5527 window.location.href= "/default.asp?searchdate="+$(this).val()+""; 5528 }); 5529 extractIcons(); 5530</script>
5530 5531 5532 5533 5534 </div> 5535 5536 <div id="venuesWidget" class="control-box venue-control"> 5537 <span class="heading-text">Browse by Venue</span> 5538 5539 5540 5541 5542<select id="venueSelect" class="showare-select" name="venue" aria-label="Choose Venue"> 5543 <option value="0"> Choose Venue </option> 5544</select> 5545<div align="right"> 5546 <a class="button small-button sw-button-muted" style="margin-top:1em;margin-right:0px;" href="//www.cincyticket.com/venuelisting.asp">View Venue listing</a> 5547</div> 5548
5549<script language="javascript"> 5550 var VenuesExpireTime = new Date().getTime(); var isExpired = false; var VenuesData = ""; 5551 try { 5552 //check for local storage support 5553 isExpired = VenuesExpireTime > Number(localStorage.getItem("VenuesExpireTime")); 5554 if(isExpired){ 5555 //item expired, clear local results 5556 localStorage.setItem("ShoWareVenues", ""); 5557 } 5558 localStorage.setItem("VenuesExpireTime", VenuesExpireTime + (1000 * 60 * 60 * 24)); //item information expires after 24 hours 5559 VenuesData = localStorage.getItem("ShoWareVenues"); 5560 } catch(e){ 5561 VenuesData = ""; 5562 } 5563 function getVenues(){ 5564 //attempt to get local data for widget 5565 if(VenuesData == "" || VenuesData == null){ 5566 //no data found, pull data from request 5567 $.getJSON("https://www.cincyticket.com/include/widgets/controls/RequestVenues.asp") 5568 .done(function (data) { 5569 //build select box 5570 populateVenues(data); 5571 try{ 5572 localStorage.setItem("ShoWareVenues",JSON.stringify(data)); 5573 }catch(e){ 5574 console.log("No local storage"); 5575 } 5576 }) 5577 .fail(function (jqxhr, textStatus, error) { 5578 var err = textStatus + ", " + error; 5579 console.log("Request Failed: " + err); 5580 }); 5581 }else{ 5582 VenuesData = JSON.parse(VenuesData); 5583 populateVenues(VenuesData); 5584 } 5585 } 5586 function populateVenues(venueOptions){ 5587 oSelect = document.getElementById("venueSelect"); 5588 for(var i = 0; i < venueOptions.length; i++){ 5589 //add an option for each venue in data 5590 var opt = document.createElement("option"); 5591 opt.value = venueOptions[i].ID; 5592 opt.innerHTML = venueOptions[i].Name; 5593 oSelect.appendChild(opt); 5594 } 5595 $("#venueSelect").val(0); 5596 } 5597 getVenues(); 5598 5599 $("#venueSelect").change(function(){ 5600 updatePerformanceList_Venue($(this).val()) 5601 }); 5602 function updatePerformanceList_Venue(venueVal) { 5603 5604 5605 $(".featured-wrap").hide(); 5606 $(".pl-wrap").show(); 5607 clearPerformanceList(); 5608 performanceListArgs.venue = venueVal; 5609 doPerformanceList(); 5610 updatePage(null, ["venue"], [venueVal], {"performanceList": performanceListArgs}); 5611 5612 } 5613</script>
5613 5614 </div> 5615 5616 <div id="infoWidget" class="control-box info-control"> 5617 <span class="heading-text">Information</span> 5618 <!--<img src="images/hdrInfo.gif" width="162" height="20" alt="" border="0"><br>--> 5619 <span class="info-text small-text"><p><strong>Customer Service:</strong><br /> <span style="text-decoration: underline;"><span style="font-size: medium;"><a href="https://www.cincyticket.net/help">CONTACT US</a></span></span><br /><br /> 9891 Montgomery Rd.<br />Suite 189<br /> Cincinnati, OH 45242</p> 5620<a href="https://www.facebook.com/cincyticket" target="_blank"><img src="https://www.cincyticket.com/uplimage/icon_facebook.png" alt="" width="35" height="35" /></a> <a href="https://www.twitter.com/cincyticket" target="_blank"><img src="https://www.cincyticket.com/uplimage/icon_twitter.png" alt="" width="35" height="35" /><br /></a> 5621<p><a href="https://www.cincyticket.net" target="_blank"><img src="../uplimage/sellticketswithus_new.png" alt="" border="0" /></a></p> 5622<center><em><br />Ticketing System by</em><br /><a href="https://www.cincyticket.net" target="_blank"><img src="../uplimage/cincyticket_logo_clearbg.png" alt="" border="0" /></a></center><!-- Meta Pixel Code -->
5623<script>// <![CDATA[
vendor: 408 bytes, lines 5623-5632
5623 5624!function(f,b,e,v,n,t,s) 5625{if(f.fbq)return;n=f.fbq=function(){n.callMethod? 5626n.callMethod.apply(n,arguments):n.queue.push(arguments)}; 5627if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; 5628n.queue=[];t=b.createElement(e);t.async=!0; 5629t.src=v;s=b.getElementsByTagName(e)[0]; 5630s.parentNode.insertBefore(t,s)}(window, document,'script', 5631'https://connect.facebook.net/en_US/fbevents.js'); 5632fbq('init', '
5632802935397828854
vendor: 32 bytes, lines 5632-5633
5632'); 5633fbq('track', 'PageView');
5634// ]]></script>
5634 5635<noscript><img height="1" width="1" style="display:none" 5636src="https://www.facebook.com/tr?id=802935397828854&ev=PageView&noscript=1" 5637/></noscript><!-- End Meta Pixel Code --></span> 5638 </div> 5639 5640 <a class="reporting-link" href="/reporting/login.asp">Promoter Login</a> 5641 5642 <div class="ads-control"> 5643 <center> 5644 <div class='sw-banner-ad' data-sw-ad-location='side_01'></div><div class='sw-banner-ad' data-sw-ad-location='side_02'></div><div class='sw-banner-ad' data-sw-ad-location='side_03'></div><div class='sw-banner-ad' data-sw-ad-location='side_04'></div><div class='sw-banner-ad' data-sw-ad-location='side_05'></div><div class='sw-banner-ad' data-sw-ad-location='side_06'></div><div class='sw-banner-ad' data-sw-ad-location='side_07'></div><div class='sw-banner-ad' data-sw-ad-location='side_08'></div><div class='sw-banner-ad' data-sw-ad-location='side_09'></div><div class='sw-banner-ad' data-sw-ad-location='side_10'></div> 5645 </center> 5646 </div> 5647 5648 </div><!--END control-wrap END--> 5649 <!--END LEFT SIDE--> 5650 <div id="epImage2"></div> 5651 5652 <div class="main-container main-constrain-width"> 5653 <!-- Main Area --> 5654 5655 <!-- end HTMLheader.asp --> 5656 5657 <div class="featured-wrap"> 5658 5659 <span tabindex="0" class="heading-text large-text featured-head">Featured Events</span> 5660 <div id="swEventList" class="featured-items" aria-live="polite" role="complementary"></div> 5661
5661<script src="//www.cincyticket.com/include/widgets/events/EventList.js?v2" id="swEventListScript" language="javascript"></script>
5661 5662 </div> 5663 5664 5665 <div id="plFeatList" class="pl-wrap" > 5666 <span tabindex="0" class="heading-text large-text upcoming-head">Upcoming</span> 5667 <div id="swPerformanceList" data-style="PerformanceBlockDateList" class="performance-list" data-listmaxsize="200" data-listpagesize="10" aria-live="polite" role="complementary"></div> 5668
5668<script src="//www.cincyticket.com/include/widgets/events/PerformanceList.js?v3" id="swPerformanceListScript" language="javascript"></script>
5668 5669 </div> 5670 5671 5672<!-- This code is to show the Performance list in the Corporate Partner context -->
5673<script type="text/javascript"> 5674 5675 $(document).ready(function(){$(".corporate-header").hide();}); 5676 5677 5678</script>
5678 5679 5680 5681 <div class="clear-float"></div> 5682 </div><!--End main-container #END--> 5683 <!-- end main arean --> 5684 <div class="clear-float"></div><!--force inner-content pas floated left and right sections--> 5685 5686 </div><!--END content-inner END--> 5687 </div><!--END content-wrap END--> 5688 5689 <div class="foot-wrap"> 5690 <div class="foot-inner center-div site-width"> 5691 5692 <center><div class='sw-banner-ad' data-sw-ad-location='footer'></div> </center> 5693 5694 <span class="copyright-text"> 5695 Copyright © 2026 CincyTicket, All Rights Reserved. <span class="no-mobile">-</span> <br class="mobile-only" /> 5696 Ticketing System by <a class="Copyrightlink" target="_blank" href="https://www.cincyticket.net">CincyTicket Solutions</a><br><br> 5697 <span class="copyright-text">Please read our <a href="Javascript:popUp('Privacy Statement','privacystatement.asp',350,420,'no','yes','no','no')">Privacy Statement</a> and <a href="Javascript:popUp('Terms of Use','termsofuse.asp',350,420,'no','yes','no','no')">Terms of Use</a>.</span> 5698 <br><br> 5699 </span><!--END copyright-text span END--> 5700 5701 5702
5702<script language="JavaScript" type="text/javascript"> 5703 //variable defined via external script from HTMLHeadClose.asp 5704 if (typeof TrustLogo !== "undefined") { 5705 TrustLogo("https://www.cincyticket.com/images/comodo.png", "CL1", "none"); 5706 } 5707 </script>
5707 5708 5709 </div><!--END foot-inner END--> 5710 </div><!--END foot-wrap END--> 5711 5712 5713 5714</div><!--END page-wrap END--> 5715 5716
5717<script language="javascript"> 5718 $(function () { 5719 //activate modals 5720 hoverModal(); 5721 }); 5722</script>
5722 5723 5724 5725
5725<script async src="//www.cincyticket.com/include/widgets/basket/basketwidget.js?ver=20228b0075" id="showarebasketscript" type="text/javascript"></script>
5725 5726 5727
5728<script> 5729 var cb = function() { 5730 var l = document.createElement('link'); l.rel = 'stylesheet'; 5731 l.href = '/include/jqueryui-themes/default/jquery-ui.css'; 5732 var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h); 5733 }; 5734 var raf = window.requestAnimationFrame || 5735 window.webkitRequestAnimationFrame || 5736 window.mozRequestAnimationFrame || 5737 window.oRequestAnimationFrame || 5738 window.msRequestAnimationFrame ; 5739 if (raf) raf(cb); 5740 else window.addEventListener('load', cb); 5741</script>
5741 5742
5743<script type="text/javascript"> 5744 $("body").addClass("/default"); 5745 if(window.location.hostname.toLowerCase() != "www.cincyticket.com"){ 5746 Showare.Logger.warn("Bad Domain Request","www.cincyticket.com - " + window.location.hostname); 5747 window.location.replace("//www.cincyticket.com"); 5748 } 5749 5750</script>
5750 5751 5752<!-- ARIA ACCESSABILITY FEATURES -->
5753<script type="text/javascript"> 5754 try{ 5755 5756 $(".main-container").attr("role","main"); 5757 $("ul.showare-nav").attr("role","list"); 5758 $("ul.showare-nav li").attr("role","listitem"); 5759 $("ul.showare-nav li a").attr("role","button"); 5760 $(".search-control").attr("role","listitem"); 5761 $("input.search-text").attr("aria-label","Search"); 5762 $(".theme-custom-field-set input").attr("aria-labelledby","custom-field-label").attr("aria-label","Additional Information box"); 5763 $(".theme-custom-field-set select").attr("role","listbox").attr("aria-labelledby","custom-field-label").attr("aria-label","Additional Information list"); 5764 $(".control-wrap").attr("role","complementary").attr("aria-label","Side Navigation"); 5765 $("header.head-wrap").attr("role","banner"); 5766 $("div.foot-wrap").attr("role","contentinfo"); 5767 $("a.header-logo-link h1").attr("aria-hidden","true"); 5768 $(".copyright-text:last").find("a").attr("role", "button"); 5769 $(".tab-nav-wrap").find("a").attr("role", "button"); 5770 $("#mobile-menu").attr("role","list"); 5771 $("#mobile-menu li").attr("role","listitem"); 5772 $("#mobile-menu li a").attr("role","button"); 5773 $(".heading-text").attr("role","heading").attr("aria-level","2"); 5774 5775 $("a.bodylink").attr("role","button"); 5776 $("a.getmembership-link").attr("role","button"); 5777 5778 $("a.header-logo-link h1").attr("aria-level","1"); 5779 $("#demo-div").attr("role","region").attr("aria-label","Only a Demo Site"); 5780 $("#swCustomListings").attr("aria-label","Featured Custom Listing"); 5781 5782 5783 $(".ad-image").attr("role","presentation"); 5784 5785 5786 //add a basket link for aria to read 5787 $("li.basket-widget").prepend('<a tabindex="0" class="aria-basket-link" href="basket.asp?fw=1">Shopping Cart</a>'); 5788 5789 //adds aria-label explaining that the link is opening a new tab if the link has target="blank" on it and no aria-label added 5790 $('a[target="_blank"]').each(function() { 5791 if (!$(this).attr('aria-label')) { 5792 $(this).attr('aria-label', 'Opens in a new tab.'); 5793 } 5794 }); 5795 // address the "button can not be empty" - add the Next Month and Previous month to the arrow buttons 5796 var spanNextMonth = $('<span>', {id: 'bn_next-label', class: 'sr-only', text: 'Next Month'}); 5797 var spanPrevMonth = $('<span>', {id: 'bn_prev-label', class: 'sr-only', text: 'Previous Month'});
5798 $('.bn_next').prepend(spanNextMonth); 5799 $('.bn_prev').prepend(spanPrevMonth); 5800 5801 // add ID attribute to main sections 5802 $("header.head-wrap.no-mobile").attr("id","mainheadwrap"); 5803 $("div.content-wrap").attr("id","maincontentwrap"); 5804 $("div.foot-wrap").attr("id","mainfootwrap"); 5805 5806 // adding Skip link 5807 var skipLinkToHeader = $('<a>', {href: '#mainheadwrap', class: 'skip-link', text: 'Skip to header content', 'aria-label': 'Skip to header content', 'role': 'link'}); 5808 var skipLinkToMainContent = $('<a>', {href: '#maincontentwrap', class: 'skip-link', text: 'Skip to main content', 'aria-label': 'Skip to main content', 'role': 'link'}); 5809 var skipLinkToFooterContent = $('<a>', {href: '#mainfootwrap', class: 'skip-link', text: 'Skip to footer content', 'aria-label': 'Skip to footer content', 'role': 'link'}); 5810 5811 // add created skip link above the main sections 5812 $(skipLinkToHeader).insertBefore("header.head-wrap.no-mobile"); 5813 $(skipLinkToMainContent).insertBefore("div.content-wrap"); 5814 $(skipLinkToFooterContent).insertBefore("div.foot-wrap"); 5815 5816 // use setTimeout to make sure all are loaded before adding attributes 5817 setTimeout(function() { 5818 $('html').attr('lang', 'en'); 5819 $(".day-cell.highlight-day").attr("tabindex", "0"); // address the interactive elements should be navigable using the keyboard 5820 $("#ShoWareBasketWidget").find(".cart-item").attr("role", "button").attr("tabindex", "0"); 5821 $("#ShoWareBasketWidget .cart-item .cart-item-pic").attr("role", "cart presentation"); 5822 $("#ShoWareBasketWidget .cart-item .cart-item-pic .sw-i-cart").attr("role", "cart presentation"); 5823 $(".featured-items-item .streaming-note").attr("role","presentation"); 5824 $(".pl-item a.pl-popup-link").attr("role","button"); 5825 $(".pl-date-block-image").attr("role","img"); 5826 $("#epImage2 img").attr("alt","Event Banner"); 5827 $('.navigation.sw-nav > a[href*="basket.asp"]').attr({ 5828 'title': 'View Basket', 5829 'aria-label': 'View Basket' 5830 }); 5831 5832 // address the "Incorrect use of aria-describedy" - this is used in the header cart but there's no ID to refer it to 5833 var cartTitle = $('.cart-item-desc').attr('title'); 5834 var spanCartItemDesc = $('<span>', {id: 'cart-text', class: 'sr-only', text: cartTitle}); 5835 $('.cart-item-desc').prepend(spanCartItemDesc); 5836 5837 // address the "Incorrect use of aria-describedy" - this is used in the calendar and no ID to refer it to 5838 var calendarTableTitle = $('.calendar-object table:first').attr('title'); 5839 var spanCalendarIDAdded = $('<span>', {id: 'month', class: 'sr-only', text: calendarTableTitle}); 5840 $('.calendar-object table:first').prepend(spanCalendarIDAdded); 5841 $('img[src$="sectigo_trust_seal_lg_140x54.png"]').attr({alt: "Sectigo Seal", 'aria-label': "Sectigo Seal"}); 5842 $("a.aria-basket-link").attr("role","button").attr("aria-label","Shopping Cart"); 5843 $(".month-wrap .month").attr("aria-level","3"); 5844 5845 var $metaViewport = $('meta[name="viewport"]'); 5846 if ($metaViewport.length) { 5847 $metaViewport.attr('content', 'width=device-width, initial-scale=1.0, minimum-scale=1.0'); 5848 } else { 5849 $('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0">'); 5850 } 5851 5852 }, 1200); 5853 5854 setTimeout(function() { 5855 $('[data-index]').removeAttr('data-index'); 5856 $('[tabindex]').removeAttr('tabindex'); 5857 $('[tabindes]').removeAttr('tabindes'); 5858 5859 let HeaderElements = $('.head-inner').find('.logo-container a, .showare-nav-inner a, select, textarea, input, a.button,#ShoWareBasketWidget .cart-item'); 5860 let SideBarElements = $('.show-wrap').find('a, .sw-datepicker td.highlight-day, .bn_prev, .month, .bn_next'); 5861 let allElements = $('.main-container').find('input, select, textarea, a.button, .info-box a, button, h2 a, h3 a, a.pl-popup-link, #basket a, .login-form a'); // find all elements that needed tab index 5862 5863 // Header 5864 HeaderElements.each(function() { 5865 $(this).removeAttr('tabindex'); 5866 }); 5867 $(".showare-nav li").removeAttr('tabindex'); 5868 $("#ShoWareBasketWidget .cart-item").removeAttr('tabindex'); 5869 $(".aria-basket-link").removeAttr('tabindex'); 5870 $("#searchButton").removeAttr('tabindex'); 5871 $(".show-wrap .control-box").removeAttr('tabindex'); 5872 5873 HeaderElements.each(function(index) { 5874 $(this).attr('tabindex', 0); 5875 }); 5876 // Sidebar 5877 SideBarElements.each(function() { 5878 $(this).removeAttr('tabindex'); 5879 }); 5880 5881 SideBarElements.each(function(index) { 5882 $(this).attr('tabindex', 0); 5883 }); 5884 5885 // Main Content 5886 allElements.each(function() { 5887 $(this).removeAttr('tabindex'); 5888 }); 5889 5890 allElements.each(function(index) { 5891 if (!$(this).attr('tabindex')) { 5892 $(this).attr('tabindex', 0); 5893 } 5894 }); 5895 5896 $(".performance-block-date-link").attr('tabindex', -1); 5897 $(".basket-widget a.aria-basket-link").attr('tabindex', -1); 5898 $("a.skip-link").attr('tabindex', -1); 5899 $(".copyright-text a").each(function(index) { 5900 $(this).attr('tabindex', 0); 5901 }); 5902 5903 $(".highlightinfo-wrap .prevevent-btn").attr("aria-label", "Previous Event"); 5904 $(".highlightinfo-wrap .nextevent-btn").attr("aria-label", "Next Event"); 5905 $(".highlightinfo-wrap .button-wrap a.button").attr("role", "button").attr("aria-label", "Buy Tickets"); 5906 $(".featuredevent-box .bottominfo-wrap a.button.featured-togglelink").attr("role", "button").attr("aria-label", "Toggle Down to Open event information"); 5907 $('img[src$="sectigo_trust_seal_lg_140x54.png"]').attr({alt: "Sectigo Seal", 'aria-label': "Sectigo Seal"}); 5908 $(".info-box a").attr("role", "button").attr("aria-label", "Venue Link"); 5909 $("a.forgot-password-link").attr("role", "button").attr("aria-label", "Forgot Password"); 5910 5911 $("#EventInformationWrap").attr("tabindex", "0"); 5912 $("#venuesWidget .right a.button").attr("role", "button"); 5913 $("table.cal thead th").attr('scope', 'col'); 5914 $('.otherimages img').each(function () { 5915 var src = $(this).attr('src'); 5916 if (src) { 5917 var filename = src.substring(src.lastIndexOf('/') + 1); // Get the filename 5918 $(this).attr('alt', filename); // Set as alt 5919 } 5920 }); 5921 $('.mainimage img').each(function () { 5922 var src = $(this).attr('src'); 5923 if (src) { 5924 var filename = src.substring(src.lastIndexOf('/') + 1); // Get the filename 5925 $(this).attr('alt', filename); // Set as alt 5926 } 5927 }); 5928 $('.bundle-event-container').each(function() { 5929 var altText = $(this).find('.event-container-header').text().trim(); 5930 $(this).find('.bundle-event-image').attr('alt', altText); 5931 }); 5932 $('.related-event').each(function() { 5933 var altTextH3 = $(this).find('h3').text().trim(); 5934 $(this).find('img').attr('alt', altTextH3); 5935 }); 5936 5937 }, 3500); 5938 5939 5940 }catch(e){ 5941 console.log("Failed to update header for accessability:"); 5942 console.log(e); 5943 } 5944</script>
5944 5945<style> 5946*:focus {box-shadow: 0 0 0 3px #fff,0 0 4px 6px #ccc!important;} 5947 5948/* Hide visually but keep accessible to screen readers */ 5949 .sr-only { 5950 position: absolute !important; 5951 width: 1px !important; 5952 height: 1px !important; 5953 padding: 0 !important; 5954 margin: -1px !important; 5955 overflow: hidden !important; 5956 clip: rect(0, 0, 0, 0) !important; 5957 border: 0 !important; 5958 } 5959 .skip-link { 5960 position: absolute; 5961 left: -10000px; 5962 top: auto; 5963 width: 1px; 5964 height: 1px; 5965 overflow: hidden; 5966 } 5967/* Style for focused interactive elements visible to accessibility readers */ 5968 :focus-visible { 5969 outline: 2px solid #ccc; /* Show the outline for accessibility readers */ 5970 outline-offset: 2px; /* Optional: Adjust the spacing between the element and the outline */ 5971 } 5972</style> 5973
5974<script> 5975setTimeout(function() { 5976 $( document ).ready(function() { 5977 $('#mobile-menu li a').each(function(){ 5978 if($(this).is(':contains("close")')) { 5979 $(this).attr("onclick","actWidget('');"); 5980 } 5981 if($(this).is(':contains("search")')) { 5982 $(this).attr("onclick","actSearch();return 0;"); 5983 } 5984 5985 if($(this).is(':contains("shopping cart")')) { 5986 $(this).attr("HREF","https://www.cincyticket.com/basket.asp?fw=1"); 5987 } 5988 }); 5989 $('#mobile-menu').removeAttr("onclick"); 5990 }); 5991}, 300); 5992</script>
5992 5993
5994<script> 5995// Add control wrap's height as the min-height for main-constrain-width so the sidebar won't overlap to the footer 5996setTimeout(function() { 5997 $( document ).ready(function() { 5998 varControlWrapHeight = $(".control-wrap").height() + "px"; 5999 $(".main-constrain-width").css( "min-height", varControlWrapHeight ); 6000 }); 6001}, 300); 6002</script>
6002 6003
6004<script> 6005setInterval(function() { 6006 $(document).ready(function(){ 6007 $(".pl-first-col").each(function () { 6008 var PerformanceNameToSwitch = $(" h3.pl-performance-name", $(this)); 6009 var EventNameToSwitch = $(" h3.pl-event-name", $(this)); 6010 $(PerformanceNameToSwitch).insertBefore(EventNameToSwitch); 6011 if ( $(PerformanceNameToSwitch).html() == "") { // Event and Peformance are the same, switch the class of the event name so it will get the new style of the performance name 6012 $(EventNameToSwitch).removeClass("pl-event-name"); 6013 $(EventNameToSwitch).addClass("pl-performance-name"); 6014 } 6015 }); 6016 }); 6017}, 500); 6018</script>
6018 6019<style> 6020 .performance-list .pl-performance-name { 6021 font-size: 1.1em; 6022 font-weight: bold; 6023 margin-top: 0px; 6024 padding-top: 0px; 6025 opacity: 1; 6026 } 6027 .performance-list .pl-event-name { 6028 opacity: 0.8; 6029 width: 100%; 6030 font-weight: normal; 6031 } 6032 .performance-list .pl-item.block-date-item .pl-performance-name { 6033 font-size: 28px; 6034 line-height: 26px; 6035 margin-bottom: 0px; 6036 font-weight: bold; 6037 } 6038 .performance-list .pl-item.block-date-item .pl-event-name { 6039 margin: 0px; 6040 font-size: 1em; 6041 font-weight: normal; 6042 } 6043 .pl-first-col .pl-popup-link { 6044 line-height: 26px; 6045 } 6046 6047</style> 6048 6049 6050 6051</body> 6052</html>
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.