GIF89a; %PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
Server IP : 134.29.175.74 / Your IP : 216.73.216.160 Web Server : nginx/1.10.2 System : Windows NT CST-WEBSERVER 10.0 build 19045 (Windows 10) i586 User : Administrator ( 0) PHP Version : 7.1.0 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/nginx/html/Scheduler/Schedule/ |
Upload File : |
"use strict"; // Schedule/schedule.js // _Initialize() .................................................. Initialize js. // _Resized() ..................................................... Resize js. // _Scrolled() ..................................................a.. Scroll js. // AddClassMeeting() .............................................. Add a new meeting to the Schedule Class dialog. // AddClassMeeting_Done(divId) .................................... Wait until the Meeting loads and call ScheduleClassDialog_SetWidth(). // ChangeInstructorColor(e) ....................................... Change the color of the Instructor for Highlight/Instructor. // ClassMeeting_SetHeight(by) ..................................... Align display (visible height) of Schecule Class dialog meetings. // ClassmeetingArranged(e) ........................................ Show or hide class meeting time and days form elements based on Arranged checked. // ClassmeetingOffCampus(e) ....................................... Show or hide class meeting rooms form elements based on Off campus checked. // ClearTextSelection() ........................................... Clear any text selection on the page. // CloseTextbox() ................................................. Close and empty the textboxDiv. // ConvertMinutesToTime(dayminutes, flags) ........................ Convert day minutes to time. Default is 24 hr clock with two digit hour and ':00' seconds. // ConvertTimeTo12hr(timeofday) ................................... Convert time to 12hr with meridiem. Seconds will be ignored if present. // ConvertTimeToMinutes(timeofday) ................................ Convert time to minutes. Seconds will be ignored if present. // CreateSortedClasses() .......................................... Create an array (EVENTS_ORDERED) of ScheduleClasses sorted by course number and section. // DisplaySchedule(by) ............................................ Display the classes on the schedule. // DisplaySchedule_SetSize() ........................................ Set scheduleTime, scheduleCell, and scheduleHead widths and heights. // DisplaySchedule_Highlight_Conflicts() .......................... Check schedule for class Degree/year, room, or instructor conflicts and change meeting styles to show them. // DisplaySchedule_Highlight_Instructors() ........................ Highlight the different Instructors. // DisplayScheduleShowHide() ...................................... Show or hide the scheduleHead, scheduleTimes, and scheduleCells and calculate left and width of cells. // EventListeners_Add() ........................................... Add event listeners to the schedule classes. // EventListeners_Remove() ........................................ Remove event listeners to the calendar_class divs. // Events_Add( day ) .............................................. Add events for this day to EVENTS_TO_DISPLAY for positioning schedule classes. // Events_Overlapping(day) ........................................ Check all events for overlap and add to EVENTS_OVERLAPPING. // Events_Prepare( day ) .......................................... Adds additional properties to EVENTS_TO_DISPLAY, so that they can be positioned properly on the schedule. // Events_Prepare_GetLeft( overlapObject, eventKey, day, width ) .. Calculate left overlapping events. // Events_Prepare_MaxOverlap(overlapObject, eventKey) ............. Calculate max overlap length for positioning schedule classes. // Events_Sort( EVENT ) ........................................... Sorts array of event objects by their begin and position paremeters. // HighlightLikeMe() .............................................. Highlight all sibling class meetings with something to make them noticeable. // MoveCLass_Cancel() ............................................. Cancel the class move and put the calendar_class divs back to their original locations. // OpenDialog(scheduleclassId, CallCount) ......................... Open the dialogDiv with the scheduleclass info loaded. // OpenTextbox(evt, title, text, buttons, returnFunction) ......... Open the textboxDiv. // Print() ........................................................ Print the contents of the 'eId' element. // RemoveChildren(e) .............................................. Remove all child elements from e. // ScheduleChange() ............................................... Display the schedule change form. // ScheduleChange_ChangeScheduleButtonCheck(e) .................... Enable/disable Change schedule button. // ScheduleChange_CreateScheduleButtonCheck(e) .................... Enable/disable Create schedule button. // ScheduleClass_MoveSingleMeetingDiv() ........................... Move class meeting div to the drop day/time, update db and redraw. // ScheduleClass_OpenAddDialog() .................................. Add a class to the schedule. // ScheduleClass_OpenEditDialog(evt) .............................. Edit the class. // ScheduleClass_RemoveClassMeetingVerify(scmId, thisTask) ........ Verify removal of class meeting. // ScheduleClass_RemoveClassVerify(thisTask) ...................... Verify removal of schedule class. // ScheduleClassDialog_SetWidth(by) ............................... Set the wicth of the Schedule Class dialogDiv. // ScheduleClassDialogDrag(e) ..................................... Handles the drag event from the Schedule Class dialog. // ScheduleClassDragBegin(evt) .................................... Begin the schedule class drag. // ScheduleClassDragCheck(evt) .................................... Determine if this is a click or a drag of a schedule class. // ScheduleClassDragCheckWait(evt) ................................ Wait 50 ms to ensure this is a drag vs a click. // ScheduleClassDragMove(evt) ..................................... Follow the mouse with the schedule class being dragged. // ScheduleClassDragMoveAbortCheck(evt) ........................... Check for ESC key to abort sheedule class drag. // ScheduleClassDrop(evt) ......................................... handle schedule class drop. // ScheduleImportClasses(thisTask) ................................ Handle class import from another schedule. // ScheduleImportClasses_ParseButtonCheck(e) ...................... Enable/disable Change schedule button. // ScheduleImportClasses_ScheduleButtonCheck(e) ................... Enable/disable Change schedule button. // ScheduleTaskHide() ............................................. Hide the schedule and display the div_ScheduleFunctionsContainer. // ScheduleTaskShow() ............................................. Show the schedule and hide the div_ScheduleFunctionsContainer. // ScheduleViewSettings(makeChange) ............................... Set schedule settings: calendar_dayview, calendar_timebegin, calendar_timeend, calendar_timeincrement, and calendar_incrementheight. // ScrollDialogDiv() .............................................. Reposition the Schedule Class dialog on page scroll // Search_FindMeetings(search) .................................... Find and highlight class meetings that match search. // Search_HighlightMeetings() ..................................... Hightlight meetings found by search. // Search_UnhighlightMeetings() ................................... Unhighlight and clear meetings found by search. // Search_UpdateDatalist(e) ....................................... Populate schedule search datalist from input. // SetClassEndTime(e) ............................................. Set the class end time based on the # credits / meeting days. // SetupBuildingSelectOptions(e) .................................. Set the options for the building select. // SetupInstructorOptions() ....................................... Set the options for the next instructor select. // SetupNextCampusSelectOptions(scmId, campusIndex) ............... Set the options for the next campus select. // SetupRoomSelectOptions() ....................................... Set the options for the room select. // ShowInstructorButton(e) ........................................ Show + add instructor button. // ShowInstructorNext(e) .......................................... Show next select element for instructor. // Room_RoomLine_Show(scmId, campusIndex_Next) ......................... Show next select element for campus. // RoomLine_RemoveAddButtons_ShowHide(scmId, campusIndex) ............................. Show + add room button. // SidenavToggle(sidenavClass) .................................... Show / hide side nav sub menu. // SortObject(obj) ................................................ Sort an object by key. // UnhighlightLikeMe() ............................................ Unhighlight all siblin class meetings. //"use strict"; // Variables let ClassMeetingIndex = 1; // Used to set the id for new class meetings (add meeting). let EVENTS_ORDERED = []; // an array of ScheduleClasses sorted by course number and section. let EVENTS_OVERLAPPING; // Events as keys with an array of their overlapping events. let EVENTS_READY; // Events with position and width set. let EVENTS_TO_DISPLAY; // Events to be rendered on the schedule let ScheduleClassOpenCount = 0; let ScheduleDayTimePositions = {}; let ScheduleInstructions_class = '<span class="actionback nowrap">Click to edit.</span> <span class="action nowrap">--or--</span><br><span class="actionback nowrap">Mouse-down / drag / drop to move.</span>'; let ScheduleInstructions_arranged = '<span class="actionback nowrap">Click to edit.</span> <span class="nowrap"> </span>'; let ScheduleTop; let bcrt = 0; // Used by AutoscrollPage() by Garrett Wiley. let buildingId = 0; let campusId = 0; let currentOpenScheduleClassId; let dialogDivContents; let dragElementTL; let mXprevious; let mYprevious; let mousedownFlag = ''; let mousedownTimer = 0; //let roomId = 0; // unused 2022/04/06 jfm let schedulecontainerTL; let scheduleHeads; let scrollTL = {}; let viewportTL = {}; let dragElementOriginalTL; var _Initialize = function() { console.log(PC+'_Initialize_Tooltip[] schedule.js:105',CH); PositionSidenav(); EventListeners_Add(); DisplaySchedule_SetSize(); DisplaySchedule('_Initialize schedule.js:109'); }; var _Resized = function() { console.log(PC+'_Resized[] schedule.js:112',CH); PositionSidenav(); console.log("document.getElementById('schedulecontainer').style.display="+document.getElementById('schedulecontainer').style.display); if ( document.getElementById('schedulecontainer').style.display !== 'none' ) { setTimeout(DisplaySchedule_SetSize,50); setTimeout(DisplaySchedule,100); } }; var _Scrolled = function() { //console.warn('_Scrolled[] schedule.js'); PositionSidenav(); }; // ChangeInstructorColor(e) // Change the color of the Instructor for Highlight/Instructor. // Change is stored in the database and session. function ChangeInstructorColor(e) { //alert(evt.target.id);. // let userId = e.getAttribute("data-userId"); // data-userId is not currently output in the code. let idParts = e.id.split('_'); let Id = idParts[1]; for (let i = 0; i < ScheduleInstructor.length; i++ ) { if ( ScheduleInstructor[i].instructorId == Id ) { ScheduleInstructor[i].color = e.value.substr(1); console.log(`ScheduleInstructor[i].color = ${ScheduleInstructor[i].color}`); // Need Ajax call to save color. URI = ROOT_http + '/User/UserUpdate.php?task=ChangeColor'; URI += '&userId='+ScheduleInstructor[i].instructorId; URI += '&color='+ScheduleInstructor[i].color; UpdateInclude(URI, false, false, false); } } DisplaySchedule_Highlight_Instructors(); } // END ChangeInstructorColor. // DisplaySchedule_Highlight_Instructors() // Highlight the different Instructors. function DisplaySchedule_Highlight_Instructors() { var DEBUG = true; if ( DEBUG ) { console.groupCollapsed(PC+'DisplaySchedule_Highlight_Instructors[]',CG); } if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); } DisplaySchedule_Highlight_None(); let eHighlightInstructor = document.getElementById('ulHighlightInstructor'); RemoveChildren(eHighlightInstructor); let ScheduleInstructorCount = ScheduleInstructor.length; // Modify the DOM by creating and adding DOM elements. for ( let i = 0; i < ScheduleInstructorCount; i++ ) { let li = document.createElement('li'); li.style.border = '2px solid #' + ScheduleInstructor[i].color; var att = document.createAttribute("data-userId"); att.value = ScheduleInstructor[i].instructorId; li.setAttributeNode(att); li.id = `user_highlight_${ScheduleInstructor[i].instructorId}`; li.innerHTML = li.innerHTML + `<input type="text" id="inp_${ScheduleInstructor[i].instructorId}" style="display: none;" onchange="ChangeInstructorColor(this)">`; li.innerHTML = li.innerHTML + ' ' + ScheduleInstructor[i].Name; //li.addEventListener('click',fn.spectrum); //$(`#inp_${ScheduleInstructor[i].instructorId}`).spectrum({}); eHighlightInstructor.appendChild(li); $(`#inp_${ScheduleInstructor[i].instructorId}`).spectrum({ color:`${ScheduleInstructor[i].color}`, preferredFormat:'hex' }); } let li = document.createElement('li'); li.style.border = "2px solid orange"; //li.style.color = 'orange'; li.innerHTML=li.innerHTML + 'none'; eHighlightInstructor.appendChild(li); let CalendarClassDivs = document.querySelectorAll('div[id^="calendar_class_"]'); ////let CalendarClassDivsCount = CalendarClassDivs.length; CalendarClassDivs.forEach(function(e, index) { console.log(PC+CalendarClassDivs[index].innerHTML,CI); // Highlight border. let InstructorCount = 0; ScheduleInstructor.forEach(function(instructor, IDX) { console.log(PC+`${IDX}: ${ScheduleInstructor[IDX].Name}`,CL); if (CalendarClassDivs[index].innerHTML.indexOf(ScheduleInstructor[IDX].Name) !== -1) { CalendarClassDivs[index].style.border = `3px solid #${ScheduleInstructor[IDX].color}`; InstructorCount++; } // Need to deal with instructor none and multiple instructors. console.log(e.id, InstructorCount); }); }); if ( DEBUG ) { console.groupEnd(); } } // END DisplaySchedule_Highlight_Instructors. // EventListeners_Add() // Add event listeners to the calendar_class divs. function EventListeners_Add() { var DEBUG = false; if ( DEBUG ) { console.warn('EventListeners_Add[]'); } //window.addEventListener('resize',_Resized); // Add resize to re-display the schedule. Resized DisplaySchedule var this_calendar_meeting; var i; var calendar_classes = document.getElementsByClassName('calendar_class'); for ( i=0; i<calendar_classes.length; i++) { this_calendar_meeting = calendar_classes[i]; if ( DEBUG ) { console.log('Adding click EventListener for '+this_calendar_meeting.id); } this_calendar_meeting.addEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit. if ( DEBUG ) { console.log('Adding mousedown EventListener for '+this_calendar_meeting.id); } this_calendar_meeting.addEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop. this_calendar_meeting.addEventListener('mouseenter',HighlightLikeMe,{ useCapture:true }); // Add mouseover for highlighting sibling classes. this_calendar_meeting.addEventListener('mouseleave',UnhighlightLikeMe,{ useCapture:true }); // Add mouseout to end highlighting sibling classes. } var calendar_arranged = document.getElementsByClassName('calendar_arranged'); for ( i=0; i<calendar_arranged.length; i++) { this_calendar_meeting = calendar_arranged[i]; if ( DEBUG ) { console.log('Adding click EventListener for '+this_calendar_meeting.id); } this_calendar_meeting.addEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit. if ( DEBUG ) { console.log('Adding mousedown EventListener for '+this_calendar_meeting.id); } //this_calendar_meeting.addEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop. this_calendar_meeting.addEventListener('mouseenter',HighlightLikeMe,{ useCapture:true }); // Add mouseover for highlighting sibling classes. this_calendar_meeting.addEventListener('mouseleave',UnhighlightLikeMe,{ useCapture:true }); // Add mouseout to end highlighting sibling classes. } } // END EventListeners_Add. // EventListeners_Remove() // Remove event listeners to the calendar_class divs. function EventListeners_Remove() { var DEBUG_EventListeners_Remove = false; if ( DEBUG_EventListeners_Remove ) { console.warn('EventListeners_Remove[]'); } let this_calendar_class; // let this_calendar_meeting; // unused 2022/04/06 jfm let i; let calendar_classes = document.getElementsByClassName('calendar_class'); for ( i=0; i<calendar_classes.length; i++) { this_calendar_class = calendar_classes[i]; if ( DEBUG_EventListeners_Remove ) { console.log('Adding click EventListener for '+this_calendar_class.id); } this_calendar_class.removeEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit. if ( DEBUG_EventListeners_Remove ) { console.log('Adding mousedown EventListener for '+this_calendar_class.id); } this_calendar_class.removeEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop. } var calendar_arranged = document.getElementsByClassName('calendar_arranged'); for ( i=0; i<calendar_arranged.length; i++) { this_calendar_class = calendar_arranged[i]; if ( DEBUG_EventListeners_Remove ) { console.log('Adding click EventListener for '+this_calendar_class.id); } this_calendar_class.removeEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit. if ( DEBUG_EventListeners_Remove ) { console.log('Adding mousedown EventListener for '+this_calendar_class.id); } this_calendar_class.removeEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop. } } // END EventListeners_Remove. // ClassMeeting_SetHeight(by) // Align display (visible height) of Schecule Class dialog meetings. // This is done by changing the paddingBottom, not by setting the height. function ClassMeeting_SetHeight(by) { var DEBUG_ClassMeeting_SetHeight = false; if ( DEBUG_ClassMeeting_SetHeight ) { console.warn('ClassMeeting_SetHeight[by='+by+']'); } var divClassMeetings = document.getElementsByClassName('divClassMeeting'); // Get the divClassMeetings. if ( DEBUG_ClassMeeting_SetHeight ) { console.log('divClassMeetings.length='+divClassMeetings.length); } var thisClassMeetingDiv; // BEGIN Get height and bottom margin for each divClassMeeting. var ClassMeetingHeight = []; // Height of each divClassMeeting. var Row_Max_Height = []; // Max height (less the paddingBottom) of divClassMeetings on each row. var Row_Min_Padding = []; // Max paddingBottom of divClassMeetings on each row. //var thisMarginBottom; // unused 2022/04/06 jfm var thisPaddingBottom; // Preload row max height and min paddingBottom. var rowIndex = 0; var meetingIndex; for ( meetingIndex=0; meetingIndex<divClassMeetings.length; meetingIndex++ ) { // Loop thru divClassMeetings. if ( meetingIndex % 2 === 0 ) { Row_Max_Height[rowIndex] = 0; Row_Min_Padding[rowIndex] = 99999; rowIndex++; // Increase row after even divClassMeeting. } } // Loop thru divClassMeetings. // Get divClassMeeting paddingBottom and height less paddingBottom. rowIndex = 0; for ( meetingIndex=0; meetingIndex<divClassMeetings.length; meetingIndex++ ) { // Loop thru divClassMeetings. thisClassMeetingDiv = divClassMeetings[meetingIndex]; if ( DEBUG_ClassMeeting_SetHeight ) { console.log('thisClassMeetingDiv.id='+thisClassMeetingDiv.id); } // Get paddingBottom. thisPaddingBottom = window.getComputedStyle(thisClassMeetingDiv,null).paddingBottom.replace('px',''); if ( thisPaddingBottom < Row_Min_Padding[rowIndex] ) { Row_Min_Padding[rowIndex] = parseFloat(thisPaddingBottom); } // Get height less paddingBottom. ClassMeetingHeight[meetingIndex] = window.getComputedStyle(thisClassMeetingDiv,null).height.replace('px','') - thisPaddingBottom; if ( ClassMeetingHeight[meetingIndex] > Row_Max_Height[rowIndex] ) { Row_Max_Height[rowIndex] = ClassMeetingHeight[meetingIndex]; } if ( meetingIndex % 2 !== 0 ) { rowIndex++; // Increase row after odd divClassMeeting. } } // Loop thru divClassMeetings. if ( DEBUG_ClassMeeting_SetHeight ) { console.log('ClassMeetingHeight ='+JSON.stringify(ClassMeetingHeight)); console.log('Row_Max_Height='+JSON.stringify(Row_Max_Height)); //console.log('Row_Min_Margin ='+JSON.stringify(Row_Min_Margin)); console.log('Row_Min_Padding='+JSON.stringify(Row_Min_Padding)); } // END Get height and bottom margin for each divClassMeeting. // BEGIN Set the paddingBottom to even out the divClassMeetings height in each row. var newPaddingBottom; rowIndex = 0; for ( meetingIndex=0; meetingIndex<divClassMeetings.length; meetingIndex++ ) { // Loop thru divClassMeetings. thisClassMeetingDiv = divClassMeetings[meetingIndex]; newPaddingBottom = Row_Max_Height[rowIndex] - ClassMeetingHeight[meetingIndex] + Row_Min_Padding[rowIndex]; if ( meetingIndex % 2 !== 0 ) { newPaddingBottom += 0.01; // Add 0.01 to odd meetings because of browser rounding. } if ( DEBUG_ClassMeeting_SetHeight ) { console.log(meetingIndex+' newPaddingBottom='+newPaddingBottom); } thisClassMeetingDiv.style.paddingBottom = newPaddingBottom + 'px'; // Set divClassMeeting paddingBottom. if ( meetingIndex % 2 !== 0 ) { rowIndex++; // Increase row after odd divClassMeeting. } } // Loop thru divClassMeetings. // END Set the paddingBottom to even out the divClassMeetings height in each row. } // END ClassMeeting_SetHeight. // ClassmeetingArranged(e) // Show or hide class meeting time and days form elements based on Arranged checked. function ClassmeetingArranged(e) { // id_scheduleclassmeetingArranged_240 id_scheduleclassmeetingArranged_add1 var DEBUG_ClassmeetingArranged = true; if ( DEBUG_ClassmeetingArranged ) { console.warn('ClassmeetingArranged['+e.id+']'); } var eIdParts = e.id.split('_'); var eId = eIdParts[2]; if ( typeof eIdParts[3] !== 'undefined' ) { eId = 'add'+eIdParts[3]; } if ( DEBUG_ClassmeetingArranged ) { console.log('eId='+eId); } //console.log('e.checked='+e.checked); if ( e.checked ) { if ( document.getElementById('id_meetingTimes_'+eId) ) { document.getElementById('id_meetingTimes_'+eId).style.display = 'none'; document.getElementById('id_meetingDays_'+eId).style.display = 'none'; } } else { if ( document.getElementById('id_meetingTimes_'+eId) ) { document.getElementById('id_meetingTimes_'+eId).style.display = 'block'; document.getElementById('id_meetingDays_'+eId).style.display = 'block'; } } Validate_ScheduleClass(); } // END ClassmeetingArranged. // ClassmeetingOffCampus(e) // e = The chkClassIsOffCampus element. // Show or hide class meeting rooms form elements based on Off campus checked. function ClassmeetingOffCampus(e) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}ClassmeetingOffCampus[e.id=${e.id}]`,CG); }//Collapsed if ( DEBUG ) { console.log(`${PC}e.checked=${e.checked}`,CL); } // Get divRoomsId from checkbox id. let eIdParts = e.id.split('_'); let scmId = eIdParts[1]; let divRoomsId = 'divRooms_'+scmId; //if ( DEBUG ) { console.log('divRoomsId='+divRoomsId); } if ( e.checked ) { if ( document.getElementById(divRoomsId) ) { if ( DEBUG ) { console.log(`${PC}${divRoomsId} hidden`,CF); } document.getElementById(divRoomsId).style.display = 'none'; } } else { if ( document.getElementById(divRoomsId) ) { if ( DEBUG ) { console.log(`${PC}${divRoomsId} shown`,CT); } document.getElementById(divRoomsId).style.display = 'block'; Room_RoomLine_Show(scmId, 0); // Show campusIndex 0 RoomLine. } } Validate_ScheduleClass(); if ( DEBUG ) { console.log(`${PC}END ${PC}ClassmeetingOffCampus`,SE,ST); console.groupEnd(); } } // END ClassmeetingOffCampus. // ClearTextSelection() // Clear any text selection on the page. function ClearTextSelection() { //console.log('Clear text selection.'); if ( document.selection ) { //console.log('document.selection'); document.selection.empty(); } else if ( window.getSelection ) { //console.log('window.getSelection'); window.getSelection().removeAllRanges(); } } // END ClearTextSelection. // CloseTextbox() // Close and empty the textboxDiv. function CloseTextbox() { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}CloseTextbox]`,CG); }//Collapsed let eTextboxDiv = document.getElementById('textboxDiv'); eTextboxDiv.style.display = 'none'; eTextboxDiv.innerHTML = ''; if ( DEBUG ) { console.groupEnd(); console.log(PC+'END '+PC+'CloseTextbox',SE,ST); } } // END CloseTextbox. // ConvertMinutesToTime(dayminutes, flags) // Convert day minutes to time. Default is 24 hr clock with two digit hour and ':00' seconds. // dayminutes = day minutes. // flags = time format options. // a = 12 hour format with 'am' or 'pm' meridiem appended. Overrides P. // h = One digit hour possible. // P = 12 hour format with 'AM' or 'PM' meridiem appended. // s = Append ':00' seconds. // _ = Put a space before the meridiem. Has no effect without a or P. // . = Put dot after meridiem letters (a.m.). Has no effect without a or P. // Examples using 810 dayminutes: // flags = return value // none = 13:30:00 // a = 01:30:00pm // ah = 1:30:00pm // ah_ = 1:30:00 pm // ah. = 1:30:00p.m. // ah_. = 1:30:00 p.m. // ahs = 1:30pm // ahs_ = 1:30 pm // ahs. = 1:30p.m. // ahs_. = 1:30 p.m. // a_ = 01:30:00 pm // a. = 01:30:00p.m. // a_. = 01:30:00 p.m. // as = 01:30pm // as_ = 01:30 pm // as. = 01:30p.m. // as_. = 01:30 p.m. // P = Same as 'a' except the meridiem is in uppercase. // s = 13:30 function ConvertMinutesToTime(dayminutes, flags) { var DEBUG_ConvertMinutesToTime = false; if ( typeof flags === 'undefined' ) { flags = ''; } if ( DEBUG_ConvertMinutesToTime ) { console.warn('ConvertMinutesToTime[dayminutes='+dayminutes+', flags='+flags+']'); } var hr = parseInt(parseInt(dayminutes)/60); var mn = parseInt(dayminutes) - (hr*60); if ( DEBUG_ConvertMinutesToTime ) { console.log('hr='+hr+' mn='+mn); } var AMPM = ''; var meridiemDot = ''; var meridiem = ''; var meridiemA = ''; var meridiemM = ''; var meridiemP = ''; var meridiemSpace = ''; if ( flags.indexOf('a') !== -1 ) { meridiemA = 'a'; meridiemM = 'm'; meridiemP = 'p'; } else { if ( flags.indexOf('P') !== -1 ) { meridiemA = 'A'; meridiemM = 'M'; meridiemP = 'P'; } } if ( meridiemA !== '' ) { if ( flags.indexOf('_') !== -1 ) { meridiemSpace = ' '; } if ( flags.indexOf('.') !== -1 ) { meridiemDot = '.'; } } if ( meridiemA !== '' ) { if ( hr >= 12 ) { meridiem = meridiemP; if ( hr !== 12 ) { hr -= 12; } } else { meridiem = meridiemA; if ( hr === 0 ) { hr = 12; } } AMPM = meridiemSpace + meridiem + meridiemDot + meridiemM + meridiemDot; } hr = hr.toString(); if ( hr.length < 2 && flags.indexOf('h') === -1 ) { hr = '0'+hr; } mn = mn.toString(); if ( mn.length < 2 ) { mn = '0'+mn; } if ( DEBUG_ConvertMinutesToTime ) { console.log('hr='+hr+' mn='+mn+' AMPM='+AMPM); } var timeofday = hr + ':' + mn; if ( flags.indexOf('s') !== -1 ) { timeofday += ':00'; } if ( DEBUG_ConvertMinutesToTime ) { console.log('timeofday='+timeofday); } return timeofday + AMPM; } // ENE ConvertMinutesToTime. // ConvertTimeTo12hr(timeofday) // Convert time to 12hr with meridiem. Seconds will be ignored if present. function ConvertTimeTo12hr(timeofday) { var timeofdayParts = timeofday.split(':'); var hr = parseInt(timeofdayParts[0]); var hr12 = hr; //var min = parseInt(timeofdayParts[1]); // unused 2022/04/06 jfm if ( hr12 > 12 ) { hr12 -= 12; } var timeofdayNoSeconds = hr12+':'+timeofdayParts[1]; var Time12hr; if ( hr < 12 ) { Time12hr = timeofdayNoSeconds+'am'; } else { Time12hr = timeofdayNoSeconds+'pm'; } return Time12hr; } // END ConvertTimeTo12hr. // ConvertTimeToMinutes(timeofday) // Convert time to minutes. Seconds will be ignored if present. // i.e. 11:30:00 returns 690. // timeofday = the time to convert. function ConvertTimeToMinutes(timeofday) { var DEBUG = false; if ( DEBUG ) { console.group(`${PC}ConvertTimeToMinutes[timeofday=${timeofday}]`,CG); }//Collapsed var AM = ( timeofday.toUpperCase().indexOf('A') !== -1 ); var PM = ( timeofday.toUpperCase().indexOf('P') !== -1 ); var timeParts = timeofday.toUpperCase().replace('A','').replace('M','').replace('P','').split(':'); if ( DEBUG ) { console.log('AM='+AM+' PM='+PM+' timeParts='+timeParts); } if ( AM && parseInt(timeParts[0]) === 12 ) { timeParts[0] = 0; } if ( PM && parseInt(timeParts[0]) !== 12 ) { timeParts[0] = parseInt(timeParts[0]) + 12; } var DayMinutes = parseInt(timeParts[0]) * 60 + parseInt(timeParts[1]); //if ( isNaN(DayMinutes) ) { DayMinutes = 0; } if ( DEBUG ) { console.log('DayMinutes='+DayMinutes); } if ( DEBUG ) { console.log(`${PC}END ${PC}ConvertTimeToMinutes`,SE,ST); console.groupEnd(); } return DayMinutes; } // END ConvertTimeToMinutes. // CreateSortedClasses() // Create an array (EVENTS_ORDERED) of ScheduleClasses sorted by course number and section. function CreateSortedClasses() { var DEBUG = false; if ( DEBUG ) { console.group(`${PC}CreateSortedClasses[]`,CG); }//Collapsed. EVENTS_ORDERED = []; let unsortedScheduleClasses = {}; for ( var scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ let section = ScheduleClass[scId].Section.substr(0,2); if ( section.length < 2 ) { section = '0' + section; } let sort = ScheduleClass[scId].Course + '_' + section; unsortedScheduleClasses[sort] = { scId:scId }; }} if ( DEBUG ) { console.log(`${PC}unsortedScheduleClasses=${JSON.stringify(unsortedScheduleClasses)}`,CL); } let sortedScheduleClasses = SortObject(unsortedScheduleClasses); if ( DEBUG ) { console.log(`${PC}sortedScheduleClasses=${JSON.stringify(sortedScheduleClasses)}`,CI); } for ( var sort in sortedScheduleClasses ){if(sortedScheduleClasses.hasOwnProperty(sort)){ EVENTS_ORDERED.push(parseInt(sortedScheduleClasses[sort].scId)); }} if ( DEBUG ) { console.log(`${PC}EVENTS_ORDERED=${JSON.stringify(EVENTS_ORDERED)}`,CS); } if ( DEBUG ) { console.groupEnd(); } } // END CreateSortedClasses. // DisplaySchedule(by) // Display the class meetings on the schedule. // Class meetings are converted to EVENTS for each day and then displayed. let DAY_TO_DEBUG = ''; function DisplaySchedule(by) { //return; CreateSortedClasses(); // Create an array (EVENTS_ORDERED) of ScheduleClasses sorted by course number and section. var DEBUG = false; if ( DisplaySchedule.counter == 1 ) {DEBUG = DEBUG_ON; } let DEBUG_ORIGINAL = DEBUG; if ( DEBUG || DAY_TO_DEBUG ) { console.groupCollapsed(PC+`DisplaySchedule[] by=${by}`,CG); } else { console.log(PC+`DisplaySchedule[] by=${by} counter=${DisplaySchedule.counter}`,CH); } //return; // Uncomment to stop schedule display. var MeetingDivs = document.getElementsByClassName("calendar_class"); if ( DEBUG ) { console.log('MeetingDivs.length='+MeetingDivs.length); } //DisplaySchedule_SetSize(); DisplayScheduleShowHide(); for ( var d=0; d<ScheduleViewDays.length; d++ ) { // Loop thru schedule days. work: M=0, T=1, W=2, H=3, F=4 full: U=0, M=1, T=2, W=3, H=4, F=5, S=6 var day = ScheduleViewDays[d]; if ( day === DAY_TO_DEBUG ) { DEBUG = DEBUG_ON; } else { DEBUG = DEBUG_ORIGINAL; } EVENTS_TO_DISPLAY = []; EVENTS_OVERLAPPING = {}; EVENTS_READY = {}; if ( Events_Add(day) ) { if ( DEBUG ) { console.log(day+' EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); } Events_Overlapping(day); if ( DEBUG ) { console.log(day+' EVENTS_OVERLAPPING='+JSON.stringify(EVENTS_OVERLAPPING)); } Events_Prepare(day); if ( DEBUG ) { console.log(day+' EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); } if ( DEBUG ) { console.log(day+' EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); } if ( DEBUG ) { console.log(day+' EVENTS_READY='+JSON.stringify(EVENTS_READY)); } } // Position the classmeetings. for ( var ci=0; ci<EVENTS_TO_DISPLAY.length; ci++ ) { // Loop thru EVENTS_TO_DISPLAY. var thisMeeting = EVENTS_TO_DISPLAY[ci]; //if ( DEBUG ) { console.log('thisMeeting.divId='+thisMeeting.divId); } if ( document.getElementById(thisMeeting.divId) ) { let classMeetingElement = document.getElementById(thisMeeting.divId); var innerDiv = classMeetingElement.children[0]; //var backgroundDiv = innerDiv.lastChild; //console.log('backgroundDiv.id='+backgroundDiv.id); if ( DEBUG ) { console.log('281 thisMeeting.divId='+thisMeeting.divId+ 'thisMeeting.top='+thisMeeting.top+' ScheduleDayTimePositions['+thisMeeting.day+'].left='+ScheduleDayTimePositions[thisMeeting.day].left); } var styleLeft = thisMeeting.left + ScheduleDayTimePositions[thisMeeting.day].left; classMeetingElement.style.position = 'absolute'; classMeetingElement.style.left = styleLeft + 'px'; classMeetingElement.style.width = thisMeeting.width - 2 + 'px'; // -2 to show some space between meetings. classMeetingElement.style.display = 'block'; //if ( classMeetingElement.id === 'calendar_class_8_M600' ) { var styleTop = thisMeeting.top * ScheduleHeightMultiplier + ScheduleTop; if ( DEBUG ) { console.log('281 thisMeeting.divId='+thisMeeting.divId+ 'thisMeeting.top='+thisMeeting.top+' ScheduleHeightMultiplier='+ScheduleHeightMultiplier+' ScheduleTop='+ScheduleTop+' styleTop='+styleTop); } //} classMeetingElement.style.top = styleTop + 'px';//thisMeeting.top * ScheduleHeightMultiplier + ScheduleTop + 'px'; // + 1 classMeetingElement.style.height = thisMeeting.height * ScheduleHeightMultiplier + 'px'; innerDiv.style.height = thisMeeting.height * ScheduleHeightMultiplier + 'px'; //var backgroundDivTop = classMeetingElement.style.top + classMeetingElement.style.height - 21 + 'px'; if ( DEBUG ) { var ceb = ElementBounds(classMeetingElement,'schedule.js 445'); console.log(PC+ScheduleClass[EVENTS_TO_DISPLAY[ci].scId].Course+' bounds = '+ JSON.stringify(ceb),CI); } } else { console.info("\t"+thisMeeting.divId+' not found.'); } } // Loop thru EVENTS_TO_DISPLAY. } // Loop thru schedule days. if ( DEBUG ) { console.groupEnd(); } DisplaySchedule_Highlight(); DisplaySchedule.counter++; } // END DisplaySchedule. DisplaySchedule.counter = 0; // DisplaySchedule_SetSize() // Set scheduleTime, scheduleCell, and scheduleHead widths and heights. function DisplaySchedule_SetSize() { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}DisplaySchedule_SetSize[] ${DisplaySchedule.counter}`,CG); }//Collapsed let dayIndex; // Loop varable. // BEGIN Calculate scheduleCell width. // Hide the schedule so it does not effect width of page. // Need to get scrollbar width before hiding schedulecontainer. let scrollbarWidth = GetScrollbarWidth(); document.getElementById('schedulecontainer').style.display = 'none'; // When this is done, the table width changes. WHY??? // Show calendarCells so the scheduleCell widths can be calculated. // Show the schedule table. let eTable = document.getElementById('tbl_scheduleTable'); eTable.style.display = 'table'; console.dir(eTable); //eTable.width = "auto"; eTable.style.width = ""; // Remove style width so the table will redraw to 100%; let tableBounds = ElementBounds('tbl_scheduleTable'); if ( DEBUG ) { console.log(`${PC}scrollbarWidth=${scrollbarWidth} table.width=${tableBounds.width}`,CI); } // Do not subtract the scrollbarWidth when the page forst loads. Why??? if ( DisplaySchedule.counter > 0 ) { eTable.style.width = tableBounds.width - scrollbarWidth + 'px'; } //eTable.style.width = tableBounds.width - scrollbarWidth + 'px'; tableBounds = ElementBounds('tbl_scheduleTable'); if ( DEBUG ) { console.log(`${PC}scrollbarWidth=${scrollbarWidth} table.width=${tableBounds.width}`,CS); } //if ( DisplaySchedule.counter == 1 ) { return; } let calendarCells = document.getElementsByClassName('calendarCell'); if ( DEBUG ) { console.log('calendarCells.length='+calendarCells.length); } for ( dayIndex=0; dayIndex<calendarCells.length; dayIndex++ ) { //if ( DEBUG ) { console.log('calendarCells['+dayIndex+'].title='+calendarCells[dayIndex].title+' .className='+calendarCells[dayIndex].className+' .offsetWidth='+calendarCells[dayIndex].offsetWidth); } if ( ScheduleViewDays.indexOf(calendarCells[dayIndex].title.substr(0,1)) !== -1 ) { // Is this day in ScheduleViewDays ('UMTWHFS' or 'MTWHF'). if ( DEBUG ) { console.log('Show '+calendarCells[dayIndex].title); } calendarCells[dayIndex].className = 'calendarCell'; } else { if ( DEBUG ) { console.log('Hide '+calendarCells[dayIndex].title); } calendarCells[dayIndex].className = 'calendarCell hidden'; } } // Is this day in ScheduleViewDays ('UMTWHFS' or 'MTWHF'). // Calculate scheduleCell width. if ( DEBUG ) { console.log('calendarCells[3].className='+calendarCells[3].className+' calendarCells[3].offsetWidth='+calendarCells[3].offsetWidth); } // var setWidth = parseInt(calendarCells[3].offsetWidth); var setWidth = calendarCells[3].offsetWidth; var setWidthdivWidthDivisor = 2; var calculatedWidth = setWidth;//parseInt(setWidth/setWidthdivWidthDivisor) * setWidthdivWidthDivisor - 0;//4; // Changed to subtract 0 px 1/28/20 jfm if ( DEBUG ) { console.log('calculatedWidth='+calculatedWidth); } // Hide the schedule table. //eTable.style.display = 'none'; // Show the schedule. //if ( DisplaySchedule.counter == 1 ) { return; } document.getElementById('schedulecontainer').style.display = 'block'; //if ( DisplaySchedule.counter == 1 ) { return; } // END Calculate scheduleCell width. // Set scheduleTime heights. var scheduleTimes = document.getElementsByClassName('scheduleTime'); if ( DEBUG ) { console.log('scheduleTimes.length='+scheduleTimes.length); } for ( var scheduleCellindex=0; scheduleCellindex<scheduleTimes.length; scheduleCellindex++ ) { if ( scheduleTimes[scheduleCellindex].className.indexOf('scheduleHead') === -1 ) { // Is this a schedule time (not the head 'Time')? scheduleTimes[scheduleCellindex].style.height = ScheduleIncrementHeight + 'px'; } // Is this a schedule time (not the head 'Time')? } // Is this a schedule time (not the head 'Time')? // Set scheduleCell heights and widths. var scheduleCells = document.getElementsByClassName('scheduleCell'); if ( DEBUG ) { console.log('scheduleCells.length='+scheduleCells.length); } for ( scheduleCellindex=0; scheduleCellindex<scheduleCells.length; scheduleCellindex++ ) { scheduleCells[scheduleCellindex].style.width = calculatedWidth + 'px'; scheduleCells[scheduleCellindex].style.height = ScheduleIncrementHeight + 'px'; //scheduleCells[scheduleCellindex].style.lineHeight = ScheduleIncrementHeight - 5 + 'px'; } // Set scheduleHead widths. scheduleHeads = document.getElementsByClassName('scheduleHead'); if ( DEBUG ) { console.log('scheduleHeads.length='+scheduleHeads.length); } for ( scheduleCellindex=0; scheduleCellindex<scheduleHeads.length; scheduleCellindex++ ) { if ( scheduleHeads[scheduleCellindex].className.indexOf('scheduleTime') === -1 ) { // Is this a weekday (not the time). scheduleHeads[scheduleCellindex].style.width = calculatedWidth + 'px'; } // Is this a weekday (not the time). } if ( DEBUG ) { console.log(`${PC}END ${PC}DisplaySchedule_SetSize`,SE,ST); console.groupEnd(); } } // END DisplaySchedule_SetSize. // DisplaySchedule_Highlight_Change(highlightType) // Change the highlight type and redisplay the schedule. function DisplaySchedule_Highlight_Change(highlightType) { let highlightTypes = ['none', 'Conflict', 'Credential', 'Instructor', 'Room', ]; if (highlightTypes.indexOf(highlightType) !== -1) { ScheduleHighlightView = highlightType; DisplaySchedule('DisplaySchedule_Highlight_Change'); } else { console.log(`${PC}=ERROR! DisplaySchedule_Highlight: Invalid highlight type sent:${xxxhighlightType}`,CE); } } // END DisplaySchedule_Highlight_Change // DisplaySchedule_Highlight_Conflicts(); // Check schedule for class 1) Degree/year, 2) room, or 3) Instructor conflicts and change meeting styles to show them. function DisplaySchedule_Highlight_Conflicts() { //return; var DEBUG_All = false; var DEBUG_MultipleNone = false; var DEBUG_Conflicts = false; if ( DEBUG_All ) { DEBUG_MultipleNone = true; DEBUG_Conflicts = true; } if ( DEBUG_MultipleNone || DEBUG_Conflicts ) { console.groupCollapsed(`${PC}DisplaySchedule_Highlight_Conflicts[]`,CG); } if ( DEBUG_MultipleNone || DEBUG_Conflicts ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); } DisplaySchedule_Highlight_None(); let AnyConflicts, eCalendarClassDiv, calendar_class_div_base, calendar_class_div_id, campus1, campus2, ccmTime, ClassConflicts, courseId1, courseId2, courseNumber1, // courseNumber2, // unused 2022/04/06 jfm credential1, credential2, // credentialConflict, // unused 2022/04/06 jfm credentials1, credentials2, day, DayConflicts, days, d1, // d2, // unused 2022/04/06 jfm elementExists, eoId, instructor1, instructor2, // instructorConflict, // unused 2022/04/06 jfm instructors1, instructors2, m1, m2, meetingCount1, o1, // o2, // unused 2022/04/06 jfm overlap, r1, r2, room1, room2, rooms1, rooms2, scId, scmId, scId1; // BEGIN Highlight multiple and none. if ( DEBUG_MultipleNone ) { console.groupCollapsed(`${PB}Highlight multiple and none.`,SB,CD); } for ( scId1 in ScheduleClass ) {if(ScheduleClass.hasOwnProperty(scId1)) { // Loop thru 1st classes. calendar_class_div_base = 'calendar_class_'+scId1+'_'; for ( m1=0; m1<SCMnow[scId1].length; m1++ ) { // Loop thru class meetings. scmId = SCMnow[scId1][m1].scmId; if ( DEBUG_MultipleNone ) { console.log(PC+`${ScheduleClass[scId1].Course}`,CI); } if ( DEBUG_MultipleNone ) { console.log(PC+`SCMnow[{$scId1}][{$m1}] = ${JSON.stringify(SCMnow[scId1][m1])}`,CL); } days = ['',...SCMnow[scId1][m1].days]; if ( DEBUG_MultipleNone ) { console.log(PC+`days = ${days}`,CL); } for ( d1=0; d1<days.length; d1++ ) { // Loop thru days including a null one. courseId1 = ScheduleClass[scId1].courseId; courseNumber1 = Course[courseId1].Dept + Course[courseId1].Number; credentials1 = Course[courseId1].credentials; instructors1 = SCMnow[scId1][m1].instructors; rooms1 = SCMnow[scId1][m1].rooms; ccmTime = ConvertTimeToMinutes(SCMnow[scId1][m1].bTime); if ( isNaN(ccmTime) ) { ccmTime = 0; } calendar_class_div_id = calendar_class_div_base + days[d1] + ccmTime; eCalendarClassDiv = document.getElementById(calendar_class_div_id); elementExists = eCalendarClassDiv instanceof HTMLElement; if ( elementExists ) { if ( DEBUG_MultipleNone ) { console.log(PC+'calendar_class_div_id='+calendar_class_div_id,CI); } if ( DEBUG_MultipleNone ) { console.log(PC+'Checking '+courseNumber1+' '+calendar_class_div_id,CL); } eCalendarClassDiv = document.getElementById(calendar_class_div_id); // If the ccmTime is 0 change this div to a relative position. if ( ccmTime === 0 ) { eCalendarClassDiv.style.position = 'relative'; } // Remove all highlights. var Highlights = [ 'class_Credential_Conflict', 'class_Credential_None', 'class_Instructor_Conflict', 'class_Instructor_Multiple', 'class_Instructor_None', 'class_Room_Conflict', 'class_Room_Multiple', 'class_Room_None' ]; for ( var h=0; h<Highlights.length; h++ ) { // Loop thru Highlights. if ( eCalendarClassDiv.className.indexOf(Highlights[h]) !== -1 ) { // Is a highlight in the className? eCalendarClassDiv.className = eCalendarClassDiv.className.replace(' '+Highlights[h],''); } // Is a highlight in the className? } // Loop thru Highlights. // Check credentials. if ( !credentials1.length ) { if ( DEBUG_MultipleNone ) { console.info("\t\t"+'No credential'); } if ( eCalendarClassDiv.className.indexOf('class_Credential_None') === -1 ) { eCalendarClassDiv.className += ' class_Credential_None'; } } // Check instructors. if ( instructors1.length ) { if ( instructors1.length > 1 ) { if ( DEBUG_MultipleNone ) { console.info("\t\t"+'Multiple instructors'); } if ( eCalendarClassDiv.className.indexOf('class_Instructor_Multiple') === -1 ) { eCalendarClassDiv.className += ' class_Instructor_Multiple'; } } } else { if ( DEBUG_MultipleNone ) { console.info("\t\t"+'No instructor'); } if ( eCalendarClassDiv.className.indexOf('class_Instructor_None') === -1 ) { eCalendarClassDiv.className += ' class_Instructor_None'; } } // Check rooms. if ( rooms1.length ) { if ( rooms1.length > 1 ) { if ( DEBUG_MultipleNone ) { console.info("\t\t"+'Multiple rooms'); } if ( eCalendarClassDiv.className.indexOf('class_Room_Multiple') === -1 ) { eCalendarClassDiv.className += ' class_Room_Multiple'; } } } else { if ( SCMnow[scId1][m1].onCampus === '1' ) { if ( DEBUG_MultipleNone ) { console.info("\t\t"+calendar_class_div_id+' not found.'); } if ( eCalendarClassDiv.className.indexOf('class_Room_None') === -1 ) { eCalendarClassDiv.className += ' class_Room_None'; } } } } else { if ( DEBUG_MultipleNone ) { console.log(PC+`Element ${calendar_class_div_id} does not exist.`,CF); } } } // Loop thru days including a null one. } // Loop thru class meetings. }} if ( DEBUG_MultipleNone ) { console.log(`${PC}END ${PC}Highlight multiple and none.`,SE,CD); console.groupEnd(); } // END Highlight multiple and none. // BEGIN Highlight conflicts. AnyConflicts = 0; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Highlight conflicts.`,CD); } for ( var ScheduleViewDayIndex=0; ScheduleViewDayIndex<ScheduleViewDays.length; ScheduleViewDayIndex++ ) { // Loop thru ScheduleViewDays days. day = ScheduleViewDays[ScheduleViewDayIndex]; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PB}Check ${day} for conflicts.`,SB,ST); } DayConflicts = 0; EVENTS_TO_DISPLAY = []; EVENTS_OVERLAPPING = {}; EVENTS_READY = {}; if ( Events_Add(day) ) { Events_Overlapping(day); Events_Prepare(day); } for ( eoId in EVENTS_OVERLAPPING ) {if(EVENTS_OVERLAPPING.hasOwnProperty(eoId)) { // Loop EVENTS_OVERLAPPING. scId = EVENTS_OVERLAPPING[eoId].scId; calendar_class_div_base = `calendar_class_${scId}_`; if ( EVENTS_OVERLAPPING[eoId].length ) { ClassConflicts = 0; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}${ScheduleClass[scId].Course}, scmId = ${EVENTS_OVERLAPPING[eoId].scmId}, has ${EVENTS_OVERLAPPING[eoId].length} overlap(s) = ${JSON.stringify(EVENTS_OVERLAPPING[eoId].overlaps)}`,CD); } meetingCount1 = SCMnow[scId].length; if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} class has ${meetingCount1} meeting(s)`,CL); } for ( m1 = 0; m1 < meetingCount1; m1++ ) { // Loop thru first class meetings. if ( SCMnow[scId][m1].days.indexOf(day) !== -1 ) { // Does the first class meeting meet today? if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} SCMnow[${m1}] meets on ${day}.`,CT); } courseId1 = ScheduleClass[scId].courseId; credentials1 = Course[courseId1].credentials; instructors1 = [...SCMnow[scId][m1].instructors]; rooms1 = SCMnow[scId][m1].rooms; ccmTime = ConvertTimeToMinutes(SCMnow[scId][m1].bTime); calendar_class_div_id = `${calendar_class_div_base}${day}${ccmTime}`; eCalendarClassDiv = document.getElementById(calendar_class_div_id); campus1 = []; SCMnow[scId][m1].rooms.forEach(function(room) { if ( !campus1.includes(RoomLookup[room].campusId) ) { campus1.push(RoomLookup[room].campusId); } });DisplaySchedule_Highlight for (o1 = 0; o1 < EVENTS_OVERLAPPING[eoId].overlaps.length; o1++ ) { // Loop thru overlaps. overlap = EVENTS_OVERLAPPING[eoId].overlaps[o1]; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Checking against ${ScheduleClass[overlap.scId].Course}`,CI); } let CourseConflicts = 0; if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} overlap scmId = ${overlap.scmId}`,CL); } let meetingCount2 = SCMnow[overlap.scId].length; if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} class has ${meetingCount2} meeting(s)`,CL); } for ( m2 = 0; m2<meetingCount2; m2++ ) { // Loop thru overlap class meetings. if ( SCMnow[overlap.scId][m2].scmId === overlap.scmId ) { // Is this the overlaping meeting? if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} class meeting[${m2}] scmId ${SCMnow[overlap.scId][m2].scmId} matches overlap.scmId ${overlap.scmId}.`,CT); } courseId2 = ScheduleClass[overlap.scId].courseId; credentials2 = Course[courseId2].credentials; instructors2 = SCMnow[overlap.scId][m2].instructors; rooms2 = SCMnow[overlap.scId][m2].rooms; /**/ // BEGIN Check for credintial conflicts. let credentialConflict = false; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Check for credintial conflicts.`,CS); } if ( credentials1.length && credentials2.length ) { if ( DEBUG_Conflicts ) { console.log(`${PC}credentials1 = ${JSON.stringify(credentials1)}`,CD); } if ( DEBUG_Conflicts ) { console.log(`${PC}credentials2 = ${JSON.stringify(credentials2)}`,CI); } credentialConflict = false; //credential_dance: for ( r1=0; r1<credentials1.length; r1++ ) { // Loop thru 1st credintials. credential1 = credentials1[r1]; if ( DEBUG_Conflicts ) { console.log(`${PC}credential1.Id = ${credential1.Id}, Yr = ${credential1.Yr}`,CD); } for ( r2=0; r2<credentials2.length; r2++ ) { // Loop thru 2nd credintials. credential2 = credentials2[r2]; if ( DEBUG_Conflicts ) { console.log(`${PC}credential2.Id = ${credential2.Id}, Yr = ${credential2.Yr}`,CI); } if ( credential1.Id === credential2.Id && credential1.Yr === credential2.Yr ) { // Is there a credential conflict? // There is a potential conflict. Need to test meeting dates. if ( ( SCMnow[scId][m1].sDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].sDate <= SCMnow[overlap.scId][m2].eDate ) || ( SCMnow[scId][m1].eDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].eDate <= SCMnow[overlap.scId][m2].eDate ) ) { // There is a potential conflict. Need to test campus. campus2 = []; SCMnow[overlap.scId][m2].rooms.forEach(function(room) { if ( !campus2.includes(RoomLookup[room].campusId) ) { campus2.push(RoomLookup[room].campusId); } }); if ( DEBUG_Conflicts ) { console.log(`${PC}campus1 = ${campus1}`,CL); } if ( DEBUG_Conflicts ) { console.log(`${PC}campus2 = ${campus2}`,CL); } /** / // Old code using Array.diff if ( DEBUG_Conflicts ) { console.log(`Campus match: ${campus1.diff(campus2)}`); } let difference = campus1.filter(x => !campus2.includes(x)); if ( campus1.diff(campus2).length ) { credentialConflict = true; } /**/ /**/ let difference = campus1.filter(x => !campus2.includes(x)); if ( DEBUG_Conflicts ) { console.log(`Campus match: ${difference}`); } if ( difference.length ) { credentialConflict = true; } /**/ } else { if ( DEBUG_Conflicts ) { console.log(`${PC}Dates do not overlap ${ScheduleClass[scId].Course} = ${SCMnow[scId][m1].sDate}-${SCMnow[scId][m1].eDate}, ${ScheduleClass[overlap.scId].Course} = ${SCMnow[overlap.scId][m2].sDate}-${SCMnow[overlap.scId][m2].eDate}.`,CL); } } if ( credentialConflict ) { DayConflicts++; ClassConflicts++; CourseConflicts++; AnyConflicts++; if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} has a credential conflict with ${ScheduleClass[overlap.scId].Course} for ${Credintial[credential1.Id].Title} yr ${credential1.Yr}.`,CW); } try { if ( eCalendarClassDiv.className.indexOf('class_Credential_Conflict') === -1 ) { eCalendarClassDiv.className += ' class_Credential_Conflict'; } } catch(err) { console.log(`${PC}Element ${calendar_class_div_id} does not exist.`,CE); } //break credential_dance; } } // Is there a credential conflict? } // Loop thru 2nd credintials. } // Loop thru 1st credintials. } else { if ( DEBUG_Conflicts ) { console.log(`${PC}credentials1.length = ${credentials1.length}, credentials2.length = ${credentials2.length}`,CL); } } if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Check for credintial conflicts.`,SE,CS); console.groupEnd(); if (credentialConflict) { console.log(`${PC}There are credential conflict(s).`,CW); } } // END Check for credintial conflicts. /**/ /**/ // Check for instructor conflicts. let instructorConflict = false; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Check for instructor conflicts.`,CS); } if ( instructors1.length && instructors2.length ) { if ( DEBUG_Conflicts ) { console.log(`${PC}instructors1 = ${JSON.stringify(instructors1)}`,CD); } if ( DEBUG_Conflicts ) { console.log(`${PC}instructors2 = ${JSON.stringify(instructors2)}`,CI); } instructorConflict = false; instructor_dance: for ( r1=0; r1<instructors1.length; r1++ ) { // Loop thru 1st instructors. instructor1 = instructors1[r1]; for ( r2=0; r2<instructors2.length; r2++ ) { // Loop thru 2nd instructors. instructor2 = instructors2[r2]; if ( DEBUG_Conflicts ) { console.log(`${PC}instructor1 = ${instructor1}, instructors2 = ${instructor2}`,CL); } if ( instructor1 === instructor2 ) { // Is there an instructor conflict? // There is a potential conflict. Need to test meeting dates. if ( ( SCMnow[scId][m1].sDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].sDate <= SCMnow[overlap.scId][m2].eDate ) || ( SCMnow[scId][m1].eDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].eDate <= SCMnow[overlap.scId][m2].eDate ) ) { instructorConflict = true; } else { if ( DEBUG_Conflicts ) { console.log(`${PC}Dates do not overlap ${ScheduleClass[scId].Course} = ${SCMnow[scId][m1].sDate}-${SCMnow[scId][m1].eDate}, ${ScheduleClass[overlap.scId].Course} = ${SCMnow[overlap.scId][m2].sDate}-${SCMnow[overlap.scId][m2].eDate}.`,CL); } } if ( instructorConflict ) { DayConflicts++; ClassConflicts++; CourseConflicts++; AnyConflicts++; if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} has a instructor conflict with ${ScheduleClass[overlap.scId].Course} for ${InstructorLookup[instructor1].Name}.`,CW); } try { if ( eCalendarClassDiv.className.indexOf('class_Instructor_Conflict') === -1 ) { eCalendarClassDiv.className += ' class_Instructor_Conflict'; } } catch(err) { console.log(`${PC}Element ${calendar_class_div_id} does not exist.`,CE); } break instructor_dance; } } // Is there an instructor conflict? } // Loop thru 2nd instructors. } // Loop thru 1st instructors. } else { if ( DEBUG_Conflicts ) { console.log(`${PC}instructors1.length = ${instructors1.length}, instructors2.length = ${instructors2.length}`,CL); } } if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Check for instructor conflicts.`,SE,CS); console.groupEnd(); if (instructorConflict) { console.log(`${PC}There are instructor conflict(s).`,CW); } } /**/ /**/ // Check for room conflicts. let roomConflict = false; if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Check for room conflicts.`,CS); } if ( rooms1.length && rooms2.length ) { if ( DEBUG_Conflicts ) { console.log(`${PC}rooms1 = ${JSON.stringify(rooms1)}`,CD); } if ( DEBUG_Conflicts ) { console.log(`${PC}rooms2 = ${JSON.stringify(rooms2)}`,CI); } roomConflict = false; //room_dance: for ( r1=0; r1<rooms1.length; r1++ ) { // Loop thru 1st rooms. room1 = rooms1[r1]; for ( r2=0; r2<rooms2.length; r2++ ) { // Loop thru 2nd rooms. room2 = rooms2[r2]; if ( DEBUG_Conflicts ) { console.log(`${PC}room1 = ${room1}, rooms2 = ${room2}`,CL); } if ( room1 === room2 ) { // Is there an room conflict? // There is a potential conflict. Need to test meeting dates. if ( ( SCMnow[scId][m1].sDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].sDate <= SCMnow[overlap.scId][m2].eDate ) || ( SCMnow[scId][m1].eDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].eDate <= SCMnow[overlap.scId][m2].eDate ) ) { roomConflict = true; } else { if ( DEBUG_Conflicts ) { console.log(`${PC}Dates do not overlap ${ScheduleClass[scId].Course} = ${SCMnow[scId][m1].sDate}-${SCMnow[scId][m1].eDate}, ${ScheduleClass[overlap.scId].Course} = ${SCMnow[overlap.scId][m2].sDate}-${SCMnow[overlap.scId][m2].eDate}.`,CL); } } if ( roomConflict ) { DayConflicts++; ClassConflicts++; CourseConflicts++; AnyConflicts++; if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} has a room conflict with ${ScheduleClass[overlap.scId].Course} for ${room1}.`,CW); } try { if ( eCalendarClassDiv.className.indexOf('class_Room_Conflict') === -1 ) { eCalendarClassDiv.className += ' class_Room_Conflict'; } } catch(err) { console.log(`${PC}Element ${calendar_class_div_id} does not exist.`,CE); } //break room_dance; } } // Is there an room conflict? } // Loop thru 2nd rooms. } // Loop thru 1st rooms. } else { if ( DEBUG_Conflicts ) { console.log(`${PC}rooms1.length = ${rooms1.length}, rooms2.length = ${rooms2.length}`,CL); } } if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Check for room conflicts.`,SE,CS); console.groupEnd(); if (roomConflict) { console.log(`${PC}There are room conflict(s).`,CW); } } /**/ } else { // Is this the overlaping meeting? //if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} class meeting[${m2}] scmId ${SCMnow[overlap.scId][m2].scmId} does not match overlap.scmId ${overlap.scmId}.`,CF); } } // Is this the overlaping meeting? } // Loop thru overlap meetings. if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}${ScheduleClass[overlap.scId].Course}`,SE,CL); console.groupEnd(); if (CourseConflicts) { console.log(`${PC}There are ${CourseConflicts} conflict(s) with ${ScheduleClass[overlap.scId].Course}.`,CW); } } } // Loop thru overlaps. } else { // Does the first class meeting meet today? //if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} class meeting ${m1} does not meet on ${day}.`,CF); } } // Does the first class meeting meet today? } // Loop thru first class meetings. if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}${ScheduleClass[scId].Course}`,SE,CD); console.groupEnd(); if (ClassConflicts) { console.log(`${PC}There are ${ClassConflicts} class conflict(s).`,CW); } } } else { if ( DEBUG_Conflicts ) { console.log(PC+`${ScheduleClass[EVENTS_OVERLAPPING[eoId].scId].Course}, scmId = ${EVENTS_OVERLAPPING[eoId].scmId}, has no overlaps.`,CT); } } }} // Loop thru 1st EVENTS_OVERLAPPING. if ( DEBUG_Conflicts ) { console.groupEnd(); console.log(`${PE}Check ${day} for conflicts.`,SE,ST); if (DayConflicts) { console.log(`${PC}${day} has ${DayConflicts} conflicts.`,CW); } } } // Loop thru ScheduleViewDays days. // END Highlight conflicts. if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Highlight conflicts.`,SE,CD); console.groupEnd(); } /**/ if ( DEBUG_MultipleNone || DEBUG_Conflicts ) { console.log(`${PC}END ${PC}DisplaySchedule_Highlight_Conflicts`,SE,ST); console.groupEnd(); if (AnyConflicts) { console.log(`${PC}There are ${AnyConflicts} conflicts.`,CW); } } } // END DisplaySchedule_Highlight_Conflicts. // DisplaySchedule_Highlight_Credentials() // Highlight the different credential courses and credential/year courses. var cColors = ['FF2800', 'FF003F', 'FF6347', 'FB4F14', 'FFA500', 'E48400', 'E4D00A', 'FBEC5D', 'FFFF00', '7FFF00', '00FF00', '4CBB17', 'B2FFFF', '7DF9FF', '00FFFF', 'DF73FF', 'D19FE8', 'F4BBFF', 'FE4EDA', 'FF00FF', 'FF1493']; function DisplaySchedule_Highlight_Credentials() { var DEBUG = DEBUG_ON; let DEBUG_Conflicts = false; if ( DEBUG ) { console.group(`${PC}DisplaySchedule_Highlight_Credentials[]`,CG); }//Collapsed let credentialYearsDone = []; for ( var scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses. let courseId = ScheduleClass[scId].courseId; let credentials = Course[courseId].credentials; // eg: [ {Id:1, Yr:1}, {Id:2, Yr:1} ] for (let ci = 0; ci < credentials.length; ci++) { // Loop thru Course credentials. let courseCredentialYear = credentials[ci].Id.toString() + ':' + credentials[ci].Yr.toString(); if (credentialYearsDone.indexOf(courseCredentialYear) == -1 ) { // Have we not checked this courseCredentialYear? credentialYearsDone.push(courseCredentialYear); // Remember we did this one. for ( var scId2 in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId2)){ // Loop thru ScheduleClasses again looking for conflict. if (scId != scId2) { // Is this not the same class? let courseId2 = ScheduleClass[scId].courseId; let credentials2 = Course[courseId].credentials; let credentialConflict = false; for (let ci = 0; ci < credentials2.length; ci++) { // Loop thru credentials2. let courseCredentialYear2 = credentials[ci].Id.toString() + ':' + credentials[ci].Yr.toString(); if (courseCredentialYear == courseCredentialYear2) { // Are the two credentials the same? // Check for day/time conflict. } // Are the two credentials the same? } // Loop thru credentials2. } // Is this not the same class? }} // Loop thru ScheduleClasses again looking for conflict. } // Have we not checked this courseCredentialYear? } // Loop thru Course credentials. }} // Loop thru ScheduleClass. if ( DEBUG ) { console.groupEnd(); } } // END DisplaySchedule_Highlight_Credentials. // DisplayScheduleShowHide() // Show or hide the scheduleHead, scheduleTimes, and scheduleCells and calculate left and width of cells. // U & S day cells are hidden for 'Work week' view. All cells are shown for 'Full week' view. // All cells in a row are hidden if before begin or after end times. // All cells in a row are hidden if the time is not evenly divisible by the ScheduleTimeIncrement. function DisplayScheduleShowHide() { var DEBUG_DisplayScheduleShowHide_Cell = false; var DEBUG_DisplayScheduleShowHide_Time = false; var DEBUG_DisplayScheduleShowHide_Wide = false; if ( DEBUG_DisplayScheduleShowHide_Cell || DEBUG_DisplayScheduleShowHide_Time || DEBUG_DisplayScheduleShowHide_Wide ) { console.warn('DisplayScheduleShowHide[]'); } var scheduleCells; var scheduleTimes; var scheduleCellindex; //var csClassName; // unused 2022/04/06 jfm //var calendarCells; // unused 2022/04/06 jfm //var dayIndex; // unused 2022/04/06 jfm //var calendarCell; // unused 2022/04/06 jfm //var setWidth; // unused 2022/04/06 jfm //var setWidthdivWidthDivisor; // unused 2022/04/06 jfm var ScheduleCellDay; var ScheduleCellId; var scheduleHeadindex; var ScheduleTimeBegin_mTime = parseInt(ScheduleTimeBegin) * 60; var ScheduleTimeEnd_mTime = parseInt(ScheduleTimeEnd) * 60; var scheduleTimeindex; if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleTimeBegin_mTime='+ScheduleTimeBegin_mTime); } if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleTimeEnd_mTime='+ScheduleTimeEnd_mTime); } // BEGIN Show all scheduleHeads on the right day. scheduleHeads = document.getElementsByClassName('scheduleHead'); // Get scheduleHeads. if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleHeads.length='+scheduleHeads.length); } for ( scheduleHeadindex=0; scheduleHeadindex<scheduleHeads.length; scheduleHeadindex++ ) { // Loop thru scheduleHeads. if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleHeads['+scheduleHeadindex+'].id='+scheduleHeads[scheduleHeadindex].id); } ScheduleCellId = scheduleHeads[scheduleHeadindex].id; ScheduleCellDay = ScheduleCellId.substring(0,1); if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCellDay='+ScheduleCellDay); } if ( ScheduleCellDay ) { // Is this a scheduleHead day (not the time). if ( ScheduleViewDays.indexOf(ScheduleCellDay) !== -1 ) { // Should this day be viewed? // Yes, check for scheduleHead only. scheduleHeads[scheduleHeadindex].className = 'scheduleHead'; if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Show this scheduleHead '+ScheduleCellId); } } else { // Should this day be viewed? // No, Hide this scheduleHead. scheduleHeads[scheduleHeadindex].className = 'scheduleHead hiddenz'; if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Hide this scheduleHead '+ScheduleCellId); } } // Should this day be viewed? //scheduleHeads[scheduleHeadindex].style.width = '50px'; } } // Loop thru scheduleHeads. // END Show all scheduleHeads on the right day. // BEGIN Show all scheduleTimes between schedule times. scheduleTimes = document.getElementsByClassName('scheduleTime'); // Get scheduleTimes. if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('scheduleTimes.length='+scheduleTimes.length); } for ( scheduleTimeindex=0; scheduleTimeindex<scheduleTimes.length; scheduleTimeindex++ ) { // Loop thru scheduleTimes. if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('scheduleTimes['+scheduleTimeindex+'].id='+scheduleTimes[scheduleTimeindex].id); } var ScheduleTimeId = scheduleTimes[scheduleTimeindex].id; var ScheduleTime_mTime = parseInt(ScheduleTimeId.substring(1)); if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('ScheduleTime_mTime='+ScheduleTime_mTime); } //ScheduleViewDays var ScheduleTime_mTimeIncrement = parseInt( ScheduleTime_mTime / parseInt(ScheduleTimeIncrement) ) * parseInt(ScheduleTimeIncrement); if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('ScheduleTime_mTimeIncrement='+ScheduleTime_mTimeIncrement); } //ScheduleViewDays // Yes, Show this scheduleTime. if ( ScheduleTime_mTime === ScheduleTime_mTimeIncrement && ScheduleTime_mTime >= ScheduleTimeBegin_mTime && ScheduleTime_mTime <= ScheduleTimeEnd_mTime ) { // Should this time be viewed? // Yes, Show this scheduleTime. scheduleTimes[scheduleTimeindex].className = 'scheduleTime'; if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('Show this scheduleTime '+ScheduleTimeId); } } else { // No, Hide this scheduleTime. if ( !isNaN(ScheduleTime_mTime) ) { scheduleTimes[scheduleTimeindex].className = 'scheduleTime hiddeny'; if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('Hide this scheduleTime '+ScheduleTimeId); } } } } // Loop thru scheduleTimes. // END Show all scheduleTimes between schedule times. // BEGIN Show all scheduleCells on the right day and between schedule times. scheduleCells = document.getElementsByClassName('scheduleCell'); // Get scheduleCells. if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleCells.length='+scheduleCells.length); } for ( scheduleCellindex=0; scheduleCellindex<scheduleCells.length; scheduleCellindex++ ) { // Loop thru scheduleCells. if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleCells['+scheduleCellindex+'].id='+scheduleCells[scheduleCellindex].id); } ScheduleCellId = scheduleCells[scheduleCellindex].id; ScheduleCellDay = ScheduleCellId.substring(0,1); if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCellDay='+ScheduleCellDay); } if ( ScheduleCellDay ) { var ScheduleCell_mTime = parseInt(ScheduleCellId.substring(1)); if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCell_mTime='+ScheduleCell_mTime); }//ScheduleViewDays var ScheduleCell_mTimeIncrement = parseInt( ScheduleCell_mTime / parseInt(ScheduleTimeIncrement) ) * parseInt(ScheduleTimeIncrement); if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCell_mTimeIncrement='+ScheduleCell_mTimeIncrement); } //ScheduleViewDays if ( ScheduleViewDays.indexOf(ScheduleCellDay) !== -1 ) { // Should this day be viewed? // Yes, check for scheduleCell only. if ( ScheduleCell_mTime === ScheduleCell_mTimeIncrement && ScheduleCell_mTime >= ScheduleTimeBegin_mTime && ScheduleCell_mTime <= ScheduleTimeEnd_mTime ) { // Should this time be viewed? // Yes, Show this scheduleCell. scheduleCells[scheduleCellindex].className = 'scheduleCell'; if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Show this scheduleCell '+ScheduleCellId); } } else { // No, Hide this scheduleCell. scheduleCells[scheduleCellindex].className = 'scheduleCell hiddeny'; if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Hide this scheduleCell '+ScheduleCellId); } } } else { // Should this day be viewed? // No, Hide this scheduleCell. scheduleCells[scheduleCellindex].className = 'scheduleCell hiddenx'; if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Hide this scheduleCell '+ScheduleCellId); } } // Should this day be viewed? //scheduleCells[scheduleCellindex].style.width = '50px'; } } // Loop thru scheduleCells. // END Show all scheduleCells on the right day and between schedule times. // Calculate left and width for day. let schedulecontainerBounds = ElementBounds('schedulecontainer','schedule.js 846'); if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log('schedulecontainerBounds left='+schedulecontainerBounds.left+' top='+schedulecontainerBounds.top+' right='+schedulecontainerBounds.right+' bottom='+schedulecontainerBounds.bottom+' width='+schedulecontainerBounds.width+' height='+schedulecontainerBounds.height); } var ScheduleMinuteStart = ScheduleTimeBegin * 60; if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log('ScheduleViewDays='+ScheduleViewDays+' ScheduleMinuteStart='+ScheduleMinuteStart); } let cBounds; let tdBounds; for ( var d1=0; d1<ScheduleViewDays.length; d1++ ) { // Loop thru ScheduleViewDays. var day = ScheduleViewDays[d1]; cBounds = ElementBounds('schedulecontainer'); // Get location of the schedule. tdBounds = ElementBounds(day+ScheduleMinuteStart,'schedule.js 1151'); // Get location of top schedule cell for this day. //console.log('tdBounds='+JSON.stringify(tdBounds)); if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log(day+' cBounds left='+cBounds.left+' top='+cBounds.top+' right='+cBounds.right+' bottom='+cBounds.bottom+' width='+cBounds.width+' height='+cBounds.height); } if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log(day+' tdBounds left='+tdBounds.left+' top='+tdBounds.top+' right='+tdBounds.right+' bottom='+tdBounds.bottom+' width='+tdBounds.width+' height='+tdBounds.height); } ScheduleTop = tdBounds.top - cBounds.top; ScheduleDayTimePositions[day] = { left:tdBounds.left - cBounds.left, width:tdBounds.width }; } // Loop thru ScheduleViewDays. if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log('ScheduleTop='+ScheduleTop+' ScheduleDayTimePositions='+JSON.stringify(ScheduleDayTimePositions)); } var calendar_arranged = document.getElementsByClassName('calendar_arranged'); for ( let i=0; i<calendar_arranged.length; i++) { let this_calendar_meeting = calendar_arranged[i]; this_calendar_meeting.style.width = tdBounds.width + 'px'; } } // END DisplayScheduleShowHide. // Events_Add( day ) // Add events for this day to EVENTS_TO_DISPLAY. function Events_Add( day ) { var DEBUG = false; //if ( day === 'T' || day === 'H' ) { DEBUG = true; } if ( DEBUG ) { console.groupCollapsed(`${PC}Events_Add[day=${day}]`,CG); }// let begin, ccmTime, d1, divId, end, m1, minutesOffset = ScheduleTimeBegin * 60, modifiedEvents = 0;//, //sameClass // unused 2022/04/06 jfm // Load ClassMeetings into EVENTS_TO_DISPLAY for positioning schedule classes. let scId1; let length = EVENTS_ORDERED.length; if ( DEBUG ) { console.log(`${PC}length=${length} EVENTS_ORDERED=${JSON.stringify(EVENTS_ORDERED)}`,CL); } for ( var i=0; i<length; i++ ) { // Loop thru ordered ScheduleClasses. scId1 = EVENTS_ORDERED[i]; if ( DEBUG ) { console.log(`${PC}scId1=${scId1}`,CI); } if ( DEBUG ) { console.log('ScheduleClass['+scId1+'].courseId='+ScheduleClass[scId1].courseId+' Section='+ScheduleClass[scId1].Section+' SCMnow['+scId1+']='+SCMnow[scId1]); } let cmLength = SCMnow[scId1].length; //console.log(`${PC}cmLength=${cmLength}`,CI); for ( m1=0; m1<cmLength; m1++ ) { // Loop thru class meetings. if ( DEBUG ) { console.log("\t"+' SCMnow['+scId1+']['+m1+']='+JSON.stringify(SCMnow[scId1][m1])); } begin = ConvertTimeToMinutes(SCMnow[scId1][m1].bTime); if ( !isNaN(begin) ) { ccmTime = begin; } else { ccmTime = 0; } SCMnow[scId1][m1].tdMinute = parseInt( begin / ScheduleTimeIncrement ) * ScheduleTimeIncrement; begin -= minutesOffset; end = ConvertTimeToMinutes(SCMnow[scId1][m1].eTime) - minutesOffset; if ( DEBUG ) { console.log('begin='+begin+' end='+end+' ccmTime='+ccmTime); } for ( d1=0; d1<SCMnow[scId1][m1].days.length; d1++) { // Loop thru meeting days. modifiedEvents = 1; //ccmTime = ConvertTimeToMinutes(SCMnow[scId1][m1].bTime); divId = 'calendar_class_'+scId1+'_'+SCMnow[scId1][m1].days[d1]+ccmTime; let classMeetingDay = SCMnow[scId1][m1].days[d1]; if ( day === classMeetingDay ) { // Does the day = the classMeetingDay? EVENTS_TO_DISPLAY.push({ scId : scId1, scmId : SCMnow[scId1][m1].scmId, divId : divId, day : day, sDate : SCMnow[scId1][m1].sDate, eDate : SCMnow[scId1][m1].eDate, begin : begin, end : end, position : EVENTS_TO_DISPLAY.length }); } // Does the day = the classMeetingDay? } // Loop thru meeting days. } // Loop thru class meetings. } // Loop thru ordered ScheduleClasses. //} // Loop thru classes. //} // Loop thru classes. if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); } //we don't want to refresh the DOM if nothing changed if ( modifiedEvents ) { if ( DEBUG ) { console.groupEnd(); } return true; } // Return value tells us if the view was refreshed if ( DEBUG ) { console.groupEnd(); } return false; } // END Events_Add. // Events_Overlapping(day) // Check all events for overlap and add to EVENTS_OVERLAPPING. function Events_Overlapping(day) { var DEBUG = DEBUG_OFF; //if ( day ==='M') { DEBUG = DEBUG_ON; } if ( DEBUG ) { console.group(`${PC}Events_Overlapping[day=${day}]`,CG); }//Collapsed var currentBdate, currentBegin, currentDay, currentDivId, currentEdate, currentEnd, objectKey, overlappingEvent, overlappingKey; var l=EVENTS_TO_DISPLAY.length; for ( var i=0; i<l; i++ ) { // Loop thru EVENTS_TO_DISPLAY. currentDivId = EVENTS_TO_DISPLAY[i].divId; currentDay = EVENTS_TO_DISPLAY[i].day; currentBdate = EVENTS_TO_DISPLAY[i].bDate; currentEdate = EVENTS_TO_DISPLAY[i].eDate; currentBegin = EVENTS_TO_DISPLAY[i].begin; currentEnd = EVENTS_TO_DISPLAY[i].end; objectKey = EVENTS_TO_DISPLAY[i].scmId;//currentBegin+'*'+currentEnd+'*'+EVENTS_TO_DISPLAY[i].position; //console.log(EVENTS_TO_DISPLAY[i]); EVENTS_OVERLAPPING[objectKey] = { divId: currentDivId, items: {}, length: 0, overlaps: [], scId: EVENTS_TO_DISPLAY[i].scId, scmId: EVENTS_TO_DISPLAY[i].scmId }; if ( DEBUG ) { console.info(PC+TB+'Checking scmId:'+EVENTS_TO_DISPLAY[i].scmId+' day:'+currentDay+', begin:'+currentBegin+', end:'+currentEnd+' Course:'+ScheduleClass[EVENTS_TO_DISPLAY[i].scId].Course,CI); } if ( DEBUG ) { console.log("\t"+"\t"+'EVENTS_TO_DISPLAY['+i+']='+JSON.stringify(EVENTS_TO_DISPLAY[i])); } for ( var j=0; j<l; j+=1 ) { // Loop thru EVENTS_TO_DISPLAY. if ( j !== i ) { // Is this a different event? overlappingEvent = EVENTS_TO_DISPLAY[j]; if ( DEBUG ) { console.log("\t"+"\t"+'Against scId:'+overlappingEvent.scId+' day:'+overlappingEvent.day+', begin:'+overlappingEvent.begin+', end:'+overlappingEvent.end); } /** / if ( DEBUG ) { console.log("\t\t"+'overlappingEvent.day === currentDay == '+(overlappingEvent.day === currentDay)); console.log("\t\t"+'( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ) == '+(( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ))); console.log("\t\t"+'( overlappingEvent.end >= currentBegin && overlappingEvent.end <= currentEnd ) == '+(( overlappingEvent.end >= currentBegin && overlappingEvent.end <= currentEnd ))); console.log("\t\t"+'( currentBegin >= overlappingEvent.begin && currentBegin <= overlappingEvent.end ) == '+(( currentBegin >= overlappingEvent.begin && currentBegin <= overlappingEvent.end ))); console.log("\t\t"+'( currentEnd >= overlappingEvent.begin && currentEnd <= overlappingEvent.end ) == '+(( currentEnd >= overlappingEvent.begin && currentEnd <= overlappingEvent.end ))); } /**/ if ( ( overlappingEvent.day === currentDay ) && // day is same. ( ( ( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ) || // other's begin is between current begin and end. ( overlappingEvent.end >= currentBegin && overlappingEvent.end <= currentEnd ) // other's end is between current begin and end. ) || ( ( currentBegin >= overlappingEvent.begin && currentBegin <= overlappingEvent.end ) || // current begin is between other's begin and end. ( currentEnd >= overlappingEvent.begin && currentEnd <= overlappingEvent.end ) // current end is between other's begin and end. ) ) ) { // wraps other's begin and end. overlappingKey = overlappingEvent.scmId;//overlappingEvent.begin+'*'+overlappingEvent.end+'*'+overlappingEvent.position; EVENTS_OVERLAPPING[objectKey].items[overlappingKey] = 1; EVENTS_OVERLAPPING[objectKey].length += 1; EVENTS_OVERLAPPING[objectKey].overlaps.push({ day: overlappingEvent.day, scId: overlappingEvent.scId, scmId: overlappingEvent.scmId }); if ( DEBUG ) { console.warn("\t"+"\t"+'Overlap scId:'+overlappingEvent.scId+', scmId:'+overlappingEvent.scmId+' Course:'+ScheduleClass[overlappingEvent.scId].Course); console.log("\t"+"\t"+"\t"+'EVENTS_OVERLAPPING['+objectKey+']='+JSON.stringify(EVENTS_OVERLAPPING[objectKey])); } } } // Is this a different event? } // Loop thru EVENTS_TO_DISPLAY. /** / ( ( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ) || // begin is between other's begin and end. ( overlappingEvent.end >= currentBegin && overlappingEvent.end <= currentEnd ) || // end is between other's begin and end. ( overlappingEvent.begin <= currentBegin && overlappingEvent.end >= currentBegin ) || // wraps other's begin and end. ( overlappingEvent.begin === currentBegin || overlappingEvent.end === currentEnd ) ) ) { // begin or end is the same /**/ //if (!overlappingEvent){ //EVENTS_OVERLAPPING[objectKey] = null; //} } // Loop thru EVENTS_TO_DISPLAY. if ( DEBUG ) { console.log("\t"+"\t"+day+' EVENTS_OVERLAPPING='+JSON.stringify(EVENTS_OVERLAPPING)); } if ( DEBUG ) { console.groupEnd(); } } // END Events_Overlapping. // Events_Prepare( day ) // Adds additional properties to EVENTS_TO_DISPLAY, so that they can be positioned properly on the schedule. // Events with calculated position are added to EVENTS_READY for Events_Prepare_GetLeft(). function Events_Prepare( day ) { var DEBUG = false; let DEBUG_ORIGINAL = DEBUG; //if ( day === DAY_TO_DEBUG ) { DEBUG = DEBUG_ON; } let DEBUG_GROUPS = false; if (DEBUG_GROUPS) { DEBUG = DEBUG_ON; } if ( DEBUG || DAY_TO_DEBUG ) { console.groupCollapsed(`${PC}Events_Prepare[day=${day}]`,CG); }//. var //currentDay, // unused 2022/04/06 jfm currentEvent, eventKey, i, j, k, l, //heightMultiplier = ScheduleIncrementHeight / ScheduleTimeIncrement, //left, // unused 2022/04/06 jfm //overlappingEvents, // unused 2022/04/06 jfm scmId, scmId2, scmId3, width; EVENTS_READY = {}; Events_Sort(EVENTS_TO_DISPLAY); let divWidthDivisor = {}; // BEGIN Calculate and set calendar_class div width. // BEGIN Get event groups. let overlapGroups = []; let overlapGroupsIndex = -1; for ( scmId in EVENTS_OVERLAPPING ){if(EVENTS_OVERLAPPING.hasOwnProperty(scmId)){ // Loop thru EVENTS_OVERLAPPING. let currentEVENTS_OVERLAPPING = EVENTS_OVERLAPPING[scmId]; // Check if class scmId is in overlapGroups. let overlapGroupsLength = overlapGroups.length; if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS overlapGroupsLength=${overlapGroupsLength}`,CS); } let inGroup = false; for ( j=0; j<overlapGroupsLength; j++) { // Loop thru overlapGroups. let thisGroup = overlapGroups[j]; if ( DEBUG_GROUPS && day === DAY_TO_DEBUG) { console.log(`${PC}DEBUG_GROUPS thisGroup=${JSON.stringify(thisGroup)}`,CL); } for ( k=0; k<thisGroup.length; k++ ) { if ( thisGroup[k].indexOf(scmId) !== -1 ) { inGroup = true; } } } // Loop thru overlapGroups. if ( DEBUG_GROUPS && day === DAY_TO_DEBUG) { if (inGroup) { console.log(`${PC}DEBUG_GROUPS scmId=${scmId} inGroup=${inGroup}`,CT); } else { console.log(`${PC}DEBUG_GROUPS scmId=${scmId} inGroup=${inGroup}`,CF); } } if ( !inGroup ) { // Is this class scmId NOT in a group? // Create new group. overlapGroupsIndex++; overlapGroups[overlapGroupsIndex] = []; overlapGroups[overlapGroupsIndex].push(scmId); if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Create new group overlapGroups[${overlapGroupsIndex}]=${overlapGroups[overlapGroupsIndex]}`,CD); } // Loop thru class items and see if they are in a group. let theseItems = currentEVENTS_OVERLAPPING.items; if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS theseItems=[${JSON.stringify(theseItems)}`,CA); } for ( scmId2 in theseItems){if(theseItems.hasOwnProperty(scmId2)){ // Loop thru theseItems if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Testing ${scmId2} for ${scmId}`,CI); } if ( scmId !== scmId2 ) { let isInGroup = false; overlapGroupsLength = overlapGroups.length; if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS overlapGroupsLength= ${overlapGroupsLength}`,CI); } for ( j=0; j<overlapGroupsLength; j++) { // Loop thru overlapGroups. let thisOverlapGroup = overlapGroups[j]; if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Is ${scmId2} in thisOverlapGroup=${thisOverlapGroup} ${( thisOverlapGroup.indexOf(scmId2)!== -1 )}`,CI); } if ( thisOverlapGroup.indexOf(scmId2)!== -1 ) { isInGroup = true; //if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS isInGroup=${isInGroup}`,CT); } } } // Loop thru overlapGroups. if ( DEBUG_GROUPS && day === DAY_TO_DEBUG) { if (isInGroup) { console.log(`${PC}DEBUG_GROUPS scmId2=${scmId2} isInGroup=${isInGroup}`,CT); } else { console.log(`${PC}DEBUG_GROUPS scmId2=${scmId2} isInGroup=${isInGroup}`,CF); } } if ( isInGroup ) { // scmId2 was in a group so scmId group should be removed and scmId added to scmId2 group. if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Remove group [${overlapGroupsIndex}]}`,CD); } overlapGroups.pop(); overlapGroupsIndex--; overlapGroups[overlapGroupsIndex].push(scmId); // Changed 2023-03-28 jfm overlapGroups[overlapGroupsIndex].push(scmId2); if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Add ${scmId} overlapGroups[${overlapGroupsIndex}]=${overlapGroups[overlapGroupsIndex]}`,CD); } } else { overlapGroups[overlapGroupsIndex].push(scmId2); if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Add ${scmId2} overlapGroups[${overlapGroupsIndex}]=${overlapGroups[overlapGroupsIndex]}`,CD); } } } else { if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Skip ${scmId2} == ${scmId}`,CW); } } }} // Loop thru theseItems } // Is this class scmId NOT in a group? }} // Loop thru EVENTS_OVERLAPPING. if ( day === DAY_TO_DEBUG) { console.log(`${PC}${day} overlapGroups=${JSON.stringify(overlapGroups)}`,CI); } // END Get event groups. // BEGIN Count non overlaps. for ( i=0; i<overlapGroups.length; i++) { // Loop thru groups. let thisGroup = overlapGroups[i]; if ( day === DAY_TO_DEBUG ) { console.log(`${PC}thisGroup=${thisGroup}`,CI); } let nonOverlapping = []; for ( j=0; j<thisGroup.length; j++) { // Loop thru group classes. scmId = thisGroup[j]; if ( day === DAY_TO_DEBUG ) { console.groupCollapsed(`${PC}Checking scmId=${scmId}`,CG); }// for ( k=0; k<thisGroup.length; k++) { // Loop thru group classes again. scmId2 = thisGroup[k]; if ( scmId !== scmId2 ) { // Is this a different scmId? // Check for overlap. if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Test scmId=${scmId} vs scmId2=${scmId2}`,CD); } let inItems = false; let scmId2Items = EVENTS_OVERLAPPING[scmId2].items; if ( day === DAY_TO_DEBUG ) { console.log(`${PC}scmId2=${scmId2}.items= ${JSON.stringify(scmId2Items)}`,CI); } for ( scmId3 in scmId2Items ){if(scmId2Items.hasOwnProperty(scmId3)){ // Loop thru items. if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Check scmId=${scmId} vs scmId3=${scmId3}`,CD); } if ( scmId === scmId3 ) { if ( day === DAY_TO_DEBUG ) { console.log(`${PC}${scmId} === ${scmId3}`,CD); } inItems = true; } }} // Loop thru items. if ( day === DAY_TO_DEBUG ) { console.log(`${PC}inItems=${inItems}`,CI); } if ( !inItems ) { if ( nonOverlapping.indexOf(scmId2) === -1){ nonOverlapping.push(scmId2); } } } else { if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Skip ${scmId} vs ${scmId2}`,CW); } } // Is this a different scmId? } // Loop thru group classes again. if ( day === DAY_TO_DEBUG ) { console.groupEnd(); } } // Loop thru group classes. if ( day === DAY_TO_DEBUG ) { console.log(`${PC}divWidthDivisor=${JSON.stringify(divWidthDivisor)}`,CC); } // Save div width divisors for each scmId. let widthDivisor = thisGroup.length - parseInt(nonOverlapping.length / 2); if ( day === DAY_TO_DEBUG ) { console.log(`${PC}${day} thisGroup=${thisGroup} nonOverlapping=${JSON.stringify(nonOverlapping)} widthDivisor=${widthDivisor}`,CI); } for ( k=0; k<thisGroup.length; k++) { // Loop thru group classes again. divWidthDivisor[thisGroup[k]] = widthDivisor; } // Loop thru group classes again. } // Loop thru groups. // END Count non overlaps. // END Calculate and set calendar_class div width. if ( DEBUG ) { console.log(`${PC}${day} divWidthDivisor=${JSON.stringify(divWidthDivisor)}`,CI); } // Store EVENTS_TO_DISPLAY values. if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); } for ( i=0, l=EVENTS_TO_DISPLAY.length; i<l; i+=1 ) { // Loop thru EVENTS_TO_DISPLAY. if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY['+i+']='+JSON.stringify(EVENTS_TO_DISPLAY[i])); } currentEvent = EVENTS_TO_DISPLAY[i]; if ( DEBUG ) { console.log(`${PC}${day} currentEvent=${JSON.stringify(currentEvent)}`,CG); } eventKey = currentEvent.scmId; width = ScheduleDayTimePositions[day].width / (divWidthDivisor[eventKey]); if ( day === DAY_TO_DEBUG ) { console.log(`${PC}${day} eventKey=${eventKey} divisor=${divWidthDivisor[eventKey]} width=${width}`,CC); } let left = Events_Prepare_GetLeft(EVENTS_OVERLAPPING[eventKey], eventKey, day, width); // Store values in EVENTS_TO_DISPLAY[i]. currentEvent.top = currentEvent.begin;// * heightMultiplier; currentEvent.width = width; currentEvent.left = left; currentEvent.height = ( currentEvent.end - currentEvent.begin );// * heightMultiplier; //currentEvent.contentWidth = currentEvent.width - 4; if ( DEBUG ) { console.log('currentEvent='+JSON.stringify(currentEvent)); } EVENTS_READY[eventKey] = { left: left, width : width }; if ( DEBUG ) { console.log('EVENTS_READY['+eventKey+']='+JSON.stringify(EVENTS_READY[eventKey])); } } // Loop thru EVENTS_TO_DISPLAY. if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); } if ( DEBUG ) { console.log('EVENTS_READY='+JSON.stringify(EVENTS_READY)); } if ( DEBUG ) { console.groupEnd(); } } // END Events_Prepare. // Events_Prepare_GetLeft( overlapObject, eventKey, day ) // Calculate left overlapping events. // This function performs a few operations. // It accepts an event object with overlapping events of event object to be rendered (let's call it E). // First of all it checks if E has any overlapping events. // If not - then we know that it will be positioned at x=0. // If there are overlapping events we check if they overlap with each other as it's x position can be influenced (e2): // // ******** // * e1 * ******* // * * * * ******** // * * * E * * e3 * // ******** * * ******** // ******** ******* // * e2 * // ******** // E overlaps 3 others: e1, e2, and e3. // But e3 does not overlap e2. // Finally we find the left position of E using the positions of events that were already positioned. function Events_Prepare_GetLeft( overlapObject, eventKey, day, width ) { var DEBUG = DEBUG_OFF; if ( DEBUG ) { console.group(`${PC}Events_Prepare_GetLeft[overlapObject.divId=${overlapObject.divId} eventKey=${eventKey} day=${day}]`,CG); }//Collapsed if ( DEBUG ) { console.log(`${PC}overlapObject=${JSON.stringify(overlapObject)}`,CL); } var noncollidingEvents = {}, noncollidingEventsPairs = 0, noncollidingEventIds = [], left = 0, overlappingEventsCount = Events_Prepare_MaxOverlap(overlapObject, eventKey),//overlapObject.length, overlappingEventsAmount = overlapObject.length, overlappingIEvents, overlapReadyIEvent, startingLefts = {}, overlappingEventsAmountIds = []; if ( overlapObject ) { // Is there an overlap? if ( DEBUG ) { console.log('overlappingEventsAmount='+overlappingEventsAmount); } if ( DEBUG ) { console.log('overlapObject.items='+JSON.stringify(overlapObject.items)); } let MaxOverlaps = 0; var i, m; noncollidingEvents = {}; //MaxOverlaps = overlappingEventsCount; for( i in overlapObject.items ) {if (overlapObject.items.hasOwnProperty(i)){ // Loop thru overlap items. overlapReadyIEvent = EVENTS_READY[i]; if ( DEBUG ) { console.log(`${PC}${i} EVENTS_READY[${i}]=${JSON.stringify(EVENTS_READY[i])}`,CC); } overlappingIEvents = EVENTS_OVERLAPPING[i].items; for ( m in overlapObject.items ) {if (overlapObject.items.hasOwnProperty(m)){ // Loop thru overlap items. if ( DEBUG ) { console.log('i='+i+' m='+m+' noncollidingEvents[i]='+noncollidingEvents[i]+' noncollidingEvents[m]='+noncollidingEvents[m]+' overlappingIEvents[m]='+overlappingIEvents[m]+' eventKey='+eventKey); } if ( overlapObject.items.hasOwnProperty(m) && m !== i ) { if ( DEBUG ) { console.log(`${PC}Check for collision`,CL); } if ( noncollidingEvents[m] !== i && noncollidingEvents[i] !== m && !overlappingIEvents[m] && m !== eventKey && i !== eventKey ) { // Do these events NOT collide? if ( DEBUG ) { console.info(`${PC}${i} and ${m} do not collide.`,CC); } noncollidingEvents[i] = m; noncollidingEvents[m] = i; // if in array to not add to pair if ( noncollidingEventIds.indexOf(i) === -1 && noncollidingEventIds.indexOf(m) === -1 ) { noncollidingEventsPairs += 1; } if ( noncollidingEventIds.indexOf(m) === -1 ) { noncollidingEventIds.push(m); } // store i m in array } else { // Do these events NOT collide? // No, they collide. if ( DEBUG ) { console.log(`${PC}Collide.`,CF); } if ( overlappingEventsAmountIds.indexOf(i) === -1 ) { overlappingEventsAmount++; if ( DEBUG ) { console.log(`${PC}overlappingEventsAmount=${overlappingEventsAmount}`,CD); } overlappingEventsAmountIds.push(i); } } // Do these events NOT collide? } else { if ( DEBUG ) { console.log(`${PC}Same.`,CT); } if ( overlappingEventsAmountIds.indexOf(i) === -1 ) { overlappingEventsAmount++; if ( DEBUG ) { console.log(`${PC}overlappingEventsAmount=${overlappingEventsAmount}`,CD); } overlappingEventsAmountIds.push(i); } } }} // Loop thru overlap items. if ( MaxOverlaps < overlappingEventsAmount ) { MaxOverlaps = overlappingEventsAmount; } if ( overlapReadyIEvent ) { if ( DEBUG ) { console.log('overlapReadyIEvent '+i+' left='+overlapReadyIEvent.left+' width='+overlapReadyIEvent.width); } startingLefts[overlapReadyIEvent.left] = 1; } }} // Loop thru overlap items. if ( DEBUG ) { console.log(`${PC}noncollidingEventsPairs=${noncollidingEventsPairs} noncollidingEventIds=${noncollidingEventIds} overlappingEventsAmount=${overlappingEventsAmount}`,CL); } overlappingEventsAmount -= noncollidingEventsPairs; if ( DEBUG ) { console.log(`${PC}ScheduleDayTimePositions[day].width=${ScheduleDayTimePositions[day].width} overlappingEventsAmount=${overlappingEventsAmount} overlappingEventsCount=${overlappingEventsCount}`,CL); } if ( DEBUG ) { console.log('startingLefts='+JSON.stringify(startingLefts)+' width='+width); } if ( DEBUG ) { console.log(`${PC}ScheduleDayTimePositions[day].width=${ScheduleDayTimePositions[day].width} MaxOverlaps=${MaxOverlaps}`,CL); } for (var k in startingLefts){if (startingLefts.hasOwnProperty(k)){ if (startingLefts[left]) { left += width; } }} } // Is there an overlap? if ( DEBUG ) { console.log(`${PC}left=${left}`,CI); } if ( DEBUG ) { console.groupEnd(); } return left; } // END Events_Prepare_GetLeft. // Events_Prepare_MaxOverlap(overlapObject, eventKey) // Calculate max overlap length for positioning schedule classes. function Events_Prepare_MaxOverlap(overlapObject, eventKey) { var DEBUG = DEBUG_OFF; //if ( DEBUG_scmIds.indexOf(overlapObject.scmId) !== -1 ) { DEBUG = DEBUG_ON; } //console.log(`${PC}( DEBUG_scmIds.indexOf(${overlapObject.scmId}) !== -1 )=${( DEBUG_scmIds.indexOf(overlapObject.scmId) !== -1 )}`,CI); if ( DEBUG ) { console.group(`${PC}Events_Prepare_MaxOverlap[overlapObject=${JSON.stringify(overlapObject)} eventKey=${eventKey}]`,CG); }//Collapsed var MaxLength = overlapObject.length; if ( DEBUG ) { console.log("\t"+ScheduleClass[ClassMeeting_ScheduleClass[eventKey]].Course+'.length='+MaxLength); } //console.log(eventKey+' MaxLength='+MaxLength); for ( var index in overlapObject.items ) {if(overlapObject.items.hasOwnProperty(index)) { var thisLength = EVENTS_OVERLAPPING[index].length; if ( DEBUG ) { console.log("\t"+ScheduleClass[ClassMeeting_ScheduleClass[index]].Course+' '+EVENTS_OVERLAPPING[index].scmId+'.length='+thisLength); } MaxLength = Math.max(MaxLength,thisLength); }} //MaxLength = Math.min(MaxLength,overlapObject.length); //if ( MaxLength > overlapObject.length ) { MaxLength -= 1; } if ( DEBUG ) { console.log("\t"+'MaxLength='+MaxLength); } if ( DEBUG ) { console.groupEnd(); } return MaxLength; } // END Events_Prepare_MaxOverlap. // Events_Sort( EVENT ) // Sorts array of event objects by their begin and position parameters. function Events_Sort( EVENT ) { EVENT.sort(function(a, b) { if ( a.begin > b.begin ) { return 1; } else if ( a.begin < b.begin ) { return -1; } else { if ( a.position > b.position ) { return 1; } else if ( a.position < b.position ) { return -1; } return 0; } }); } // END Events_Sort. // AddClassMeeting() // Add a new meeting to the Schedule Class dialog. function AddClassMeeting(scheduleclassId) { var DEBUG = true; if ( DEBUG ) { console.warn('AddClassMeeting[scheduleclassId='+scheduleclassId+']'); } if ( DEBUG ) { console.log('scheduleclassId='+scheduleclassId); } var eMeetingFieldset = document.getElementById('fldMeetings'); // Create the new class meeting id. var ClassMeetingAddId = 'add'+ ClassMeetingIndex; ClassMeetingIndex++; // Save the new class meeting id. var scheduleclassmeetingIds = document.getElementById('hid_scheduleclassmeetingIds').value; if ( scheduleclassmeetingIds !== '' ) { document.getElementById('hid_scheduleclassmeetingIds').value = scheduleclassmeetingIds + ',' + ClassMeetingAddId; } else { document.getElementById('hid_scheduleclassmeetingIds').value = ClassMeetingAddId; } var _ClassMeetingAddId = '_'+ClassMeetingAddId; // Prepend the _ for use below. // Create the class meeting div. var div = document.createElement('div'); div.id = 'id_classmeeting'+_ClassMeetingAddId; div.className = 'divClassMeeting'; div.innerHTML = ''; div.style.display = 'none'; // Append new meeting in Schedule Class dialog. eMeetingFieldset.appendChild(div); // Get the meeting form via AJAX. URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassForm.php?task=AddMeeting'; URI += '&scheduleclassId='+scheduleclassId; URI += '&scmId='+ClassMeetingAddId; let preloadText = 'Getting class meeting'; UpdateLoadingText = preloadText; let jsReturnCode = "AddClassMeeting_Done("+div.id+")"; ScheduleClassOpenCount = 0; UpdateInclude(URI, div.id, preloadText, jsReturnCode); } // END AddClassMeeting. // AddClassMeeting_Done(divId) // Wait until the Meeting loads and call ScheduleClassDialog_SetWidth(). function AddClassMeeting_Done(divId) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}AddClassMeeting_Done[divId=${divId}]`,CG); }//Collapsed if ( typeof divId === 'object' ) { // Is divId an object? divId = divId.id; // Change it to the object's id. } // Is divId an object? if ( DEBUG ) { console.warn('AddClassMeeting_Done[divId='+divId+']'); } if ( DEBUG ) { console.log("UpdateDOMelement.innerHTML.indexOf('Load Meeting OK')="+UpdateDOMelement.innerHTML.indexOf('Load Meeting OK')); } if ( UpdateDOMelement.innerHTML.indexOf('Load Meeting OK') !== -1 ) { // Did the dialog contents load OK? // Yes. console.log(`${divId}.style.display = 'block'`); document.getElementById(divId).style.display = 'block'; ScheduleClassDialog_SetWidth('AddClassMeeting_Done 1196'); var divIdParts = divId.split('_'); var class1meetingStartDateId = 'inp_class1meetingStartDate_'+divIdParts[2]; if ( document.getElementById(class1meetingStartDateId) ) { document.getElementById(class1meetingStartDateId).focus(); } Validate_ScheduleClass(); } else { // Did the dialog contents load OK? // No, try again. if ( ScheduleClassOpenCount < 5 ) { ScheduleClassOpenCount++; if ( DEBUG ) { console.log('ScheduleClassOpenCount='+ScheduleClassOpenCount); } //UpdateInclude(URI, divId); // The preloadText is stored in the global UpdateLoadingText, and jsReturnCode is in the global UpdateReturnCode. setTimeout(function(){AddClassMeeting_Done(divId);},ScheduleClassOpenCount*100); } else { //alert('AddClassMeeting_Done: Never got return from URI='+URI+' divId='+divId); document.getElementById(divId).remove(); ClassMeetingIndex--; let e_errorDiv = document.getElementById('errorDiv'); e_errorDiv.innerHTML = `ERROR: There was a problem communicating with the server. Unable to get new class meeting information within 1 second. Please try again. If this error continues, please notify the site Administrator.`; ttLoad(e_errorDiv, '', '', 'error', true); } } // Did the dialog contents load OK? if ( DEBUG ) { console.log(`${PC}END ${PC}function AddClassMeeting_Done`,SE,ST); console.groupEnd(); } } // END AddClassMeeting_Done. // HighlightLikeMe() // Highlight all sibling class meetings with something to make them noticeable. function HighlightLikeMe(evt) { let DEBUG = false; if ( evt.target !== this ) { return; } let e = evt.target; //let e1 = evt.toElement || evt.relatedTarget; if ( DEBUG ) { console.group(`${PC}HighlightLikeMe[e.id=${e.id}]`,CG); }//Collapsed //console.clear(); background: linear-gradient(to bottom, var(--default-background) 25%, #ff0 100%) let idParts = e.id.split('_'); let scId = idParts[2]; if ( DEBUG ) { console.log(`${PC}scId=${scId}`,CI); } let i; let j; if ( typeof HighlightLikeMe.idsToHighlight == 'undefined' ) { HighlightLikeMe.idsToHighlight = []; } HighlightLikeMe.idsToHighlight = [e.id]; for ( i=0; i<SCMnow[scId].length; i++ ) { // Loop thru ClassMeetings. let classMeeting = SCMnow[scId][i]; let mTime = ConvertTimeToMinutes(classMeeting.bTime); if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)} if ( !isNaN(mTime) ) { // Is the mTime valid? if ( classMeeting.days.length > 0 ) { // Does this classMeeting have days? // Yes, use the days to build the ids. for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days. let day = classMeeting.days[j]; let newId = `calendar_class_${scId}_${day}${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); } HighlightLikeMe.idsToHighlight.push(newId); } // Loop thru the days. } // Does this classMeeting have days? } // Is the mTime valid? } // Loop thru ClassMeetings. if ( DEBUG ) { console.log(`${PC}idsToHighlight=${HighlightLikeMe.idsToHighlight}`,CI); } // Highlight the class meetings. for ( i=0; i<HighlightLikeMe.idsToHighlight.length; i++ ) { let eToHighlight = document.getElementById(HighlightLikeMe.idsToHighlight[i]); eToHighlight.style.boxShadow = '0 0 10px 8px blue'; eToHighlight.style.zIndex = 20; eToHighlight.style.marginRight = '15px'; eToHighlight.style.outline = 'blue solid 4px'; } if ( DEBUG ) { console.groupEnd(); } } // END HighlightLikeMe. // RemoveChildren(e) // Remove all child elements from e. function RemoveChildren(e) { let c = e.childNodes; let l = c.length - 1; for( let i = l; i >= 0; i-- ) { e.removeChild(c[i]); } } // END RemoveChildren // ScheduleChange() // Display the schedule change form. function ScheduleChange(importClasses='') { var DEBUG_ScheduleChange = true; if ( DEBUG_ScheduleChange ) { console.warn('ScheduleViewSettings[importClasses='+importClasses+']'); } var eId = 'div_ScheduleFunctionsContainer'; var e = document.getElementById(eId); var eDisplay = e.style.display; // Get schedulecontainer display. if ( DEBUG_ScheduleChange ) { console.log('eDisplay='+eDisplay); } if ( DEBUG_ScheduleChange && eDisplay === 'block' ) { console.log("e.innerHTML.indexOf('Change or create schedule')="+e.innerHTML.indexOf('Change or create schedule')); } if ( importClasses === '' && eDisplay === 'block' && e.innerHTML.indexOf('Change or create schedule') !== -1 ) { ScheduleTaskShow('ScheduleChange 882'); return false; } else { ScheduleTaskHide(); } switch ( importClasses ) { // switch importClasses. case '': URI = ROOT_http +'/Schedule/ScheduleChange/ScheduleChange.php'; let preloadText = '<br><br><span class="bold info">Getting schedule form. Please wait ...</span><br><br><br>'; UpdateInclude(URI, eId, preloadText); //setTimeout(DisplaySchedule,50); window.scrollTo(0, 0); break; case 'Import classes': break; case 'Cancel': document.getElementById(eId).style.display = 'none'; ScheduleTaskShow('ScheduleChange 903'); break; } // switch importClasses. return false; } // END ScheduleChange // ScheduleChange_ChangeScheduleButtonCheck(e) // Enable/disable Change schedule button. function ScheduleChange_ChangeScheduleButtonCheck(e) { var scheduleIdSelected = e.value; console.log('scheduleIdSelected='+scheduleIdSelected); if ( scheduleIdSelected ) { document.getElementById('btn_Change_schedule').disabled = false; } else { document.getElementById('btn_Change_schedule').disabled = true; } } // END ScheduleChange_ChangeScheduleButtonCheck. // ScheduleClass_MoveSingleMeetingDiv(by) // Move class meeting div to the drop day/time, update db and redraw. function ScheduleClass_MoveSingleMeetingDiv(by) { var DEBUG = true; if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClass_MoveSingleMeetingDiv[] by=${by}`,CG); } if ( DEBUG ) { console.log(PC+`dragElement = ${NL}"id":"${dragElement.id}" ${D_formatJSONstring(dragElement)}`,CL); } let scId = dragElement.scId; let scmId = dragElement.scmId; let divId = dragElement.id; let diDay = dragElement.droppedIn_day; let diMtime = parseInt(dragElement.droppedIn_mTime); let scmIndex = parseInt(dragElement.scmIndex); let scmNewIndex = parseInt(dragElement.scmNewIndex); if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); } // Check for Error: let moveError = document.getElementById('dialogDiv').innerHTML.indexOf('Error:'); if ( DEBUG ) { console.log('moveError='+moveError); } if ( moveError === -1 ) { // Is there no error? // Save original SCMnow. Now done in site_js.php. //SCMold[scId] = CopyObject(SCMnow[scId]); // Copy the SCMnow to a new meeting. SCMnow[scId][scmNewIndex] = CopyObject(SCMnow[scId][scmIndex]); // Modify the scmId. SCMnow[scId][scmNewIndex].scmId = `_${scmId}_${NewMeeting_scmId_Count}`; NewMeeting_scmId_Count++; // Remove the days from the current meeting. SCMnow[scId][scmIndex].days = []; // BEGIN Move meeting to new time for all days. // Get day and beginning mTime from id. let DivIdParts = divId.split('_'); let From_day = DivIdParts[3].substr(0,1); let From_mTime = DivIdParts[3].substr(1); let Difference_day = GetWeekdayNumber(diDay) - GetWeekdayNumber(From_day); // Get the day difference. let Difference_mTime = diMtime - From_mTime; // Get the mTime difference. let diTimeBegin = ConvertMinutesToTime(diMtime); let lengthMin = CalcMinuteDiff(SCMnow[scId][scmNewIndex].bTime,SCMnow[scId][scmNewIndex].eTime); let mTimeEnd = parseInt(diMtime) + parseInt(lengthMin); let diTimeEnd = ConvertMinutesToTime(mTimeEnd); if ( DEBUG ) { console.log('diTimeBegin='+diTimeBegin+' lengthMin='+lengthMin+' mTimeEnd='+mTimeEnd+' diTimeEnd='+diTimeEnd); } // Change the schedule class meeting bTime, eTime, days, and div id. var NewDays = ''; // Save the day and time differences. //let Difference_day = GetWeekdayNumber(dragElement.droppedIn_day) - GetWeekdayNumber(dragElement.original_day); // Get the day difference. //let Difference_mTime = dragElement.droppedIn_mTime - dragElement.original_mTime; // Get the mTime difference. if ( DEBUG ) { console.log('diDay='+diDay+' From_day='+From_day+' Difference_day='+Difference_day); } if ( DEBUG ) { console.log('diMtime='+diMtime+' From_mTime='+From_mTime+' Difference_mTime='+Difference_mTime); } SCMnow[scId][scmNewIndex].dayDiff = Difference_day; SCMnow[scId][scmNewIndex].mbTimeDiff = Difference_mTime; // Change the bTime and eTime. SCMnow[scId][scmNewIndex].bTime = diTimeBegin+':00'; SCMnow[scId][scmNewIndex].eTime = diTimeEnd+':00'; // Change the days, bTime and eTime innerHTML, divId, and days innerHTML. var DayNumber = 0; var DayscmNewIndex; for ( DayscmNewIndex in SCMnow[scId][scmNewIndex].days ){if(SCMnow[scId][scmNewIndex].days.hasOwnProperty(DayscmNewIndex)){ // Loop thru the days. DayNumber++; if ( DEBUG ) { console.log('SCMnow['+scId+']['+scmNewIndex+'].days['+DayscmNewIndex+']='+SCMnow[scId][scmNewIndex].days[DayscmNewIndex]); } var divId_Old = 'calendar_class_'+scId+'_'+SCMnow[scId][scmNewIndex].days[DayscmNewIndex]+From_mTime; // Same the old divId. var NewDayNumber = parseInt(GetWeekdayNumber(SCMnow[scId][scmNewIndex].days[DayscmNewIndex]))+Difference_day; // Calc the new day number. if ( DEBUG ) { console.log('NewDayNumber='+NewDayNumber); } var NewDayD = GetWeekdayD(NewDayNumber); // Calc the weekdayD. if ( DEBUG ) { console.log('NewDayD='+NewDayD); } NewDays += NewDayD; // Add new day to content for days innerHTML. SCMnow[scId][scmNewIndex].days[DayscmNewIndex] = NewDayD; var divId_New = 'calendar_class_'+scId+'_'+NewDayD+diMtime; // Calc the new divId. //SCMnow[scId][scmNewIndex].moveNewId = divId_New; if ( DEBUG ) { console.log('divId_Old='+divId_Old+' divId_New='+divId_New); } document.getElementById('bTime_'+scmId+'_'+DayNumber).innerHTML = ConvertTimeTo12hr(diTimeBegin); // Change the bTime innerHTML. document.getElementById('eTime_'+scmId+'_'+DayNumber).innerHTML = ConvertTimeTo12hr(diTimeEnd); // Change the eTime innerHTML. document.getElementById(divId_Old).id = divId_New; // Change the divId. }} // Loop thru the days. DayNumber = 0; for ( DayscmNewIndex in SCMnow[scId][scmNewIndex].days ){if(SCMnow[scId][scmNewIndex].days.hasOwnProperty(DayscmNewIndex)){ // Loop thru the days. DayNumber++; document.getElementById('days_'+scmId+'_'+DayNumber).innerHTML = NewDays; // Change the days innerHTML. }} // Loop thru the days. if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); } DisplaySchedule('ScheduleClass_MoveSingleMeetingDiv~1916'); // Re-display the schedule. } // Is there no eror? if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); } if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClass_MoveSingleMeetingDiv`,SE,ST); console.groupEnd(); } } // END ScheduleClass_MoveSingleMeetingDiv. // ScheduleChange_CreateScheduleButtonCheck(e) // Enable/disable Create schedule button. function ScheduleChange_CreateScheduleButtonCheck() { var sessionIdSelected = document.getElementById('sel_sessionId').value; var departmentIdSelected = document.getElementById('sel_departmentId').value; var scheduleNameEntered = document.getElementById('inp_scheduleName').value; console.log('sessionIdSelected='+sessionIdSelected+' departmentIdSelected='+departmentIdSelected+' scheduleNameEntered='+scheduleNameEntered); if ( sessionIdSelected && departmentIdSelected && scheduleNameEntered ) { document.getElementById('btn_Create_new_schedule').disabled = false; } else { document.getElementById('btn_Create_new_schedule').disabled = true; } } // END ScheduleChange_CreateScheduleButtonCheck. // ScheduleClass_RemoveClassMeetingVerify(scmId, thisTask) // Verify removal of class meeting. function ScheduleClass_RemoveClassMeetingVerify(scmId, thisTask) { var DEBUG_ScheduleClass_RemoveClassMeetingVerify = true; if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('BEGIN ScheduleClass_RemoveClassMeetingVerify[scmId='+scmId+' thisTask='+thisTask+']'); } if ( typeof thisTask === 'undefined' ) { if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('Display div_RemoveClassMeetingVerify_'+scmId); } document.getElementById('div_RemoveClassMeetingVerify_'+scmId).style.display = 'block'; } else if ( thisTask === 'yes' ) { // Yes clicked, remove class meeting. // Hide the div. document.getElementById('div_RemoveClassMeetingVerify_'+scmId).style.display = 'none'; // Remove this class meeting from the DOM. var divId = 'id_classmeeting_'+scmId; if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('divId='+divId); } var div = document.getElementById(divId); div.parentNode.removeChild(div); ScheduleClassDialog_SetWidth('ScheduleClass_RemoveClassMeetingVerify 1309'); // Remove it from scheduleclassmeetingIds. var scheduleclassmeetingIds = document.getElementById('hid_scheduleclassmeetingIds').value; if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('scheduleclassmeetingIds='+scheduleclassmeetingIds); } scheduleclassmeetingIds = scheduleclassmeetingIds.split(','); var scheduleclassmeetingIndex = scheduleclassmeetingIds.indexOf(scmId); if( scheduleclassmeetingIndex !== -1 ) { scheduleclassmeetingIds.splice(scheduleclassmeetingIndex, 1); // Remove the scmId. } scheduleclassmeetingIds = scheduleclassmeetingIds.toString(); if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('scheduleclassmeetingIds='+scheduleclassmeetingIds); } document.getElementById('hid_scheduleclassmeetingIds').value = scheduleclassmeetingIds; if ( typeof ClassMeeting_ScheduleClass[scmId] !== 'undefined' ) { let scId = ClassMeeting_ScheduleClass[scmId]; // Remove the calendar_class div from the DOM. let tdDay; let calendar_classId; let meetingIndex; //let i; // unused 2022/04/06 jfm for ( meetingIndex=0; meetingIndex<SCMnow[scId].length; meetingIndex++ ) { // Loop thru class meetings. var tdMin = ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime); if ( SCMnow[scId][meetingIndex].scmId === scmId ) { // Is this the meeting we want to remove? for ( var d=0; d<SCMnow[scId][meetingIndex].days.length; d++ ) { // Loop thru days. tdDay = SCMnow[scId][meetingIndex].days[d]; calendar_classId = 'calendar_class_'+scId+'_'+tdDay+tdMin; if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('calendar_classId='+calendar_classId); } var e_calendar_class = document.getElementById(calendar_classId); e_calendar_class.parentNode.removeChild(e_calendar_class); // Remove this calendar_class div from the DOM. } // Loop thru days. } // Is this the meeting we want to remove? } // Loop thru class meetings. // Remove the SCMnow javascript object. if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('ClassMeeting_ScheduleClass['+scmId+']='+ClassMeeting_ScheduleClass[scmId]+' scId='+scId); console.log('SCMnow[scId]='+JSON.stringify(SCMnow[scId])); } for ( meetingIndex=0; meetingIndex<SCMnow[scId].length; meetingIndex++ ) { if ( SCMnow[scId][meetingIndex].scmId === scmId ) { SCMnow[scId].splice(meetingIndex,1); } } if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('SCMnow[scId]='+JSON.stringify(SCMnow[scId])); } // Remove this class meeting from the database. // BEGIN Make AJAX call. // Build the URL for the AJAX call if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('BEGIN Make AJAX call.'); } URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassUpdate.php?'; URI += 'task=RemoveClassMeeting'; URI += '&scId='+scId; URI += '&scmId='+scmId; let preloadText = 'Removing class meeting'; let jsReturnCode = false; UpdateInclude(URI, null, preloadText, jsReturnCode); // END Make AJAX call. if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('END Make AJAX call.'); } } else { console.log('ClassMeeting_ScheduleClass['+scmId+'] is undefined so there is no javascript object or data to remove.'); } } else if ( thisTask === 'no' ) { // No clicked, just hide the div. document.getElementById('div_RemoveClassMeetingVerify_'+scmId).style.display = 'none'; } Validate_ScheduleClass(); ClassMeeting_SetHeight('ScheduleClass_RemoveClassMeetingVerify'); } // END ScheduleClass_RemoveClassMeetingVerify. // ScheduleClassDialog_SetWidth(by) // Set the width of the Schedule Class dialogDiv. function ScheduleClassDialog_SetWidth(by) { var DEBUG = false; if ( DEBUG ) { console.groupCollapsed(PC+'ScheduleClassDialog_SetWidth[] by='+by,CG); } var divClassMeetings = document.getElementsByClassName('divClassMeeting'); // Get the divClassMeetings. if ( divClassMeetings.length >= 1 ) { // Does the class have meetings? // Yes, Set the Schedule Class Dialog width. if ( DEBUG ) { console.log(PC+'Set the Schedule Class Dialog width',CI); } var MeetingColumns = 1; // Set to 1 or 2 below. A max of 2 columns is allowed. var ClassMeetingBoxWidth = 0; if ( divClassMeetings.length !== 0 ) { // Are there ClassMeetings? // Yes, set the number of columns and get the max divClassMeeting width; MeetingColumns = divClassMeetings.length; if ( MeetingColumns > 2 ) { MeetingColumns = 2; } // Max of 2 columns. // Need maximum width of the divClassMeetings. for ( var i=0; i<divClassMeetings.length; i++ ) { var ClassMeetingsBounds = ElementBounds(divClassMeetings[0],'schedule.js 1334'); if ( DEBUG ) { console.log(PC+'ClassMeetings['+i+']Bounds='+JSON.stringify(ClassMeetingsBounds),CL); } var ThisClassMeetingBoxWidth = ClassMeetingsBounds.margin.left + ClassMeetingsBounds.margin.right + ClassMeetingsBounds.width; if ( DEBUG ) { console.log(PC+'ThisClassMeetingBoxWidth='+ThisClassMeetingBoxWidth,CL); } if ( ThisClassMeetingBoxWidth > ClassMeetingBoxWidth ) { ClassMeetingBoxWidth = ThisClassMeetingBoxWidth; if ( DEBUG ) { console.log(PC+'ClassMeetingBoxWidth changed to '+ClassMeetingBoxWidth,CS); } } } } // Are there ClassMeetings? if ( DEBUG ) { console.log(PC+'divClassMeetings.length='+divClassMeetings.length+' MeetingColumns='+MeetingColumns+' ClassMeetingBoxWidth='+ClassMeetingBoxWidth,CL); } // Get the bounds and offsetWidth of the fldMeetings fieldset element. var eMeetingFieldset = document.getElementById('fldMeetings'); var MeetingFieldsetBounds = ElementBounds(eMeetingFieldset,'schedule.js 1344'); if ( DEBUG ) { console.log(PC+'MeetingFieldsetBounds='+JSON.stringify(MeetingFieldsetBounds),CL); } var MeetingFieldsetPartWidth = 50;//MeetingFieldsetBounds.padding.left + MeetingFieldsetBounds.padding.right + MeetingFieldsetBounds.border.left + MeetingFieldsetBounds.border.right + 50; var NewMeetingFieldsetWidth = MeetingFieldsetPartWidth + ( ClassMeetingBoxWidth * MeetingColumns ) + 3; // Added 3 to make it work. Find out why! if ( DEBUG ) { console.log(PC+'fldMeetings width = '+NewMeetingFieldsetWidth+' MeetingFieldsetPartWidth='+MeetingFieldsetPartWidth,CS); } eMeetingFieldset.style.width = NewMeetingFieldsetWidth + 'px'; ClassMeeting_SetHeight('ScheduleClassDialog_SetWidth'); // Fix frmSchedule_form width. var eScheduleForm = document.getElementById('frmSchedule_form'); var ScheduleFormBounds = ElementBounds(eScheduleForm,'schedule.js 1392'); if ( DEBUG ) { console.log(PC+'ScheduleFormBounds='+JSON.stringify(ScheduleFormBounds),CL); } var NewScheduleFormWidth = NewMeetingFieldsetWidth;// + ScheduleFormBounds.padding.left + ScheduleFormBounds.padding.right + ScheduleFormBounds.border.left + ScheduleFormBounds.border.right; if ( DEBUG ) { console.log(PC+'frmSchedule_form width = '+NewScheduleFormWidth,CS); } eScheduleForm.style.width = NewScheduleFormWidth + 'px'; /** / } else { // Does the class have meetings? // No, Check if this is a move class dialog (MCD). if ( document.getElementById('fldMoveClassMeetings') ) { // Is this a MCD? // Yes, Set the Move Class Dialog width. if ( DEBUG ) { console.log(PC+'Set the Move Class Dialog width',CI); } let eMoveClassMeetingsFieldset = document.getElementById('fldMoveClassMeetings'); // Get the fldMoveClassMeetings fieldset element. var MoveClassMeetingsFieldsetBounds = ElementBounds(eMoveClassMeetingsFieldset,'schedule.js 1419'); // Get the fldMoveClassMeetings bounds. if ( DEBUG ) { console.log(PC+'MoveClassMeetingsFieldsetBounds='+JSON.stringify(MoveClassMeetingsFieldsetBounds),CL); } var NewMoveClassMeetingFieldsetWidth = MoveClassMeetingsFieldsetBounds.padding.left + MoveClassMeetingsFieldsetBounds.padding.right + MoveClassMeetingsFieldsetBounds.border.left + MoveClassMeetingsFieldsetBounds.border.right; // Calc new width. if ( DEBUG ) { console.log(PC+'NewMoveClassMeetingFieldsetWidth='+NewMoveClassMeetingFieldsetWidth,CS); } eMoveClassMeetingsFieldset.style.width = NewMoveClassMeetingFieldsetWidth + 'px'; } else { // Is this a MCD? // No, do nothing } // Is this a MCD? /**/ //ClassMeeting_SetHeight('ScheduleClassDialog_SetWidth'); } // Does the class have meetings? if ( DEBUG ) { console.groupEnd(); } } // END ScheduleClassDialog_SetWidth. // ScheduleClassDialogDrag(e) // Handles the drag event from the Schedule Class dialog. function ScheduleClassDialogDrag(e) { var DEBUG_ScheduleClassDialogDrag = true; if ( DEBUG_ScheduleClassDialogDrag ) { console.warn('ScheduleClassDialogDrag[e.id='+e.id+']'); } var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; var e_dialogContainer = document.getElementById('dialogContainer'); document.removeEventListener('scroll', ScrollDialogDiv); function dragMouseDown(e) { e = e || window.event; // Get the mouse cursor position at startup: pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { var DEBUG = false; e = e || window.event; if ( DEBUG ) { console.warn('elementDrag[e.id='+e.id+']'); } // Calculate the new cursor position pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; // Remove any text selection. ClearTextSelection(); // Set the element's new position e_dialogContainer.style.top = (e_dialogContainer.offsetTop - pos2) + "px"; e_dialogContainer.style.left = (e_dialogContainer.offsetLeft - pos1) + "px"; } function closeDragElement() { // TODO: Save location to database document.onmouseup = null; document.onmousemove = ttPosition; // Restore onmousemove handler to ttPosition[]. document.addEventListener('scroll', ScrollDialogDiv); KeepElementInViewport(e_dialogContainer); } dragMouseDown(e); } // END ScheduleClassDialogDrag // ScheduleClassDragCheck(evt) // Determine if this is a click or a drag of a schedule class. function ScheduleClassDragCheck(evt) { //var DEBUG_ScheduleClassDragCheck = true; // unused 2022/04/06 jfm evt = (evt) ? evt : window.event; //console.log('evt='+JSON.stringify(evt)); //element.removeEventListener('mousedown',ScheduleClassDragCheck); //console.warn('ScheduleClassDragCheck[] evt.target.id='+evt.target.id+' mousedownFlag='+mousedownFlag+' button='+evt.button); if ( evt.button !== 0 ) { return; } ClearTextSelection(); mousedownFlag = 'clickwait'; var d = new Date(); mousedownTimer = d.getTime(); //console.log('mousedownTimer='+mousedownTimer); evt.currentTarget.addEventListener('mousemove', ScheduleClassDragCheckWait); } // END ScheduleClassDragCheck. // ScheduleClassDragCheckWait(evt) // Wait 50 ms to ensure this is a drag vs a click. function ScheduleClassDragCheckWait(evt) { evt = (evt) ? evt : window.event; //console.warn('ScheduleClassDragCheckWait[] evt.currentTarget.id='+evt.currentTarget.id+' mousedownFlag='+mousedownFlag); ClearTextSelection(); var d = new Date(); var now = d.getTime(); var diff = now - mousedownTimer; console.log('mousemove mousedownTimer='+mousedownTimer+' now='+now+' diff='+diff); if ( diff > 50 ) { evt.currentTarget.removeEventListener('mousemove', ScheduleClassDragCheckWait); mousedownFlag = 'mousemove'; ScheduleClassDragBegin(evt); } else { console.log('WAITING'); } } // END ScheduleClassDragCheckWait. // ScheduleClassDragBegin(evt) // Begin the schedule class drag. function ScheduleClassDragBegin(evt) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClassDragBegin[evt.target.id=${evt.target.id}] evt.type=${evt.type}`,CG); } evt = (evt) ? evt : window.event; //console.warn('ScheduleClassDragBegin[] evt.currentTarget.id='+evt.currentTarget.id+' mousedownFlag='+mousedownFlag); dragElement = evt.currentTarget; ClearTextSelection(); ttHide(); document.body.addEventListener('mouseup',ScheduleClassDrop); document.body.addEventListener('mousemove',ScheduleClassDragMove); document.body.addEventListener('keydown',ScheduleClassDragMoveAbortCheck); evt.preventDefault(); var mX = mouseX(evt); mXprevious = mX; var mY = mouseY(evt); mYprevious = mY; if ( DEBUG ) { console.log('mX='+mX+' mY='+mY); } dragElement.style.zIndex = 500; // Move the class meeting up the z. dragElementTL = ElementBounds(dragElement.id,'schedule.js 1449'); //dragElementTL.offsetLeft = (evt.offsetX || evt.clientX - $(dragElement).offset().left); //dragElementTL.offsetTop = (evt.offsetY || evt.clientY - $(dragElement).offset().top); dragElementTL.offsetLeft = (evt.offsetX || evt.clientX - dragElementTL.left); dragElementTL.offsetTop = (evt.offsetY || evt.clientY - dragElementTL.top); dragElementOriginalTL = JSON.parse(JSON.stringify(dragElementTL)); if ( DEBUG ) { console.log('dragElementTL left='+dragElementTL.left+' top='+dragElementTL.top+' right='+dragElementTL.right+' bottom='+dragElementTL.bottom+' offsetLeft='+dragElementTL.offsetLeft+' offsetTop='+dragElementTL.offsetTop); } schedulecontainerTL = ElementBounds('schedulecontainer','schedule.js 1455'); if ( DEBUG ) { console.log('schedulecontainerTL left='+schedulecontainerTL.left+' top='+schedulecontainerTL.top+' right='+schedulecontainerTL.right+' bottom='+schedulecontainerTL.bottom); } scrollTL = ScrollLeftTop(); if ( DEBUG ) { console.log('scrollTL left='+scrollTL.left+' top='+scrollTL.top); } viewportTL = {}; viewportTL.width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); viewportTL.height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); if ( DEBUG ) { console.log('viewportTL width='+viewportTL.width+' height='+viewportTL.height); } if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClassDragBegin`,SE,ST); console.groupEnd(); } } // END ScheduleClassDragBegin. // ScheduleClassDragMove(evt) // Follow the mouse with the schedule class being dragged. function ScheduleClassDragMove(evt) { //return 'dragdrop'; var DEBUG_ScheduleClassDragMove = false; evt = (evt) ? evt : window.event; ClearTextSelection(); if ( DEBUG_ScheduleClassDragMove ) { console.warn('ScheduleClassDragMove[] evt.target.id='+evt.target.id); } ttHide(); // Find current mouse position. var mX = mouseX(evt); var mY = mouseY(evt); if ( DEBUG_ScheduleClassDragMove ) { console.log('mX='+mX+' mY='+mY+' dragElementTL offsetLeft='+dragElementTL.offsetLeft+' offsetTop='+dragElementTL.offsetTop); } // Calculate position to move class meeting to in order to follow the mouse. let schedulecontainerBounds = ElementBounds('schedulecontainer'); var posX = mX - dragElementTL.offsetLeft - schedulecontainerBounds.left; var posY = mY - dragElementTL.offsetTop - schedulecontainerBounds.top; if ( DEBUG_ScheduleClassDragMove ) { console.log('posX='+posX+' posY='+posY); } // Move the class meeting to follow the mouse. dragElement.style.left = posX + 'px'; dragElement.style.top = posY + 'px'; // Remember offsetLeft and offsetTop. var offsetLeft = dragElementTL.offsetLeft; var offsetTop = dragElementTL.offsetTop; dragElementTL = ElementBounds(dragElement.id,'schedule.js 1490'); // Put back offsetLeft and offsetTop; dragElementTL.offsetLeft = offsetLeft; dragElementTL.offsetTop = offsetTop; if ( DEBUG_ScheduleClassDragMove ) { console.log('dragElementTL left='+dragElementTL.left+' top='+dragElementTL.top+' right='+dragElementTL.right+' bottom='+dragElementTL.bottom+' offsetLeft='+dragElementTL.offsetLeft+' offsetTop='+dragElementTL.offsetTop); } // Check if scroll up needed. while ( dragElementTL.top > schedulecontainerTL.top && scrollTL.top > 0 && posY < ( scrollTL.top + 1 ) ) { if ( DEBUG_ScheduleClassDragMove ) { console.info('Scroll up'); } window.scrollBy(0, -1); scrollTL = ScrollLeftTop(); console.log('scrollTL left='+scrollTL.left+' top='+scrollTL.top); } // Check if scroll down needed. /** / console.log('dragElementTL.top='+dragElementTL.top+' schedulecontainerTL.bottom='+schedulecontainerTL.bottom+' ScheduleIncrementHeight='+ScheduleIncrementHeight); console.log('scrollTL.top='+scrollTL.top+' dragElementTL.bottom='+dragElementTL.bottom); console.log('scrollTL.top='+scrollTL.top+' viewportTL.height='+viewportTL.height); /**/ while ( dragElementTL.top < ( schedulecontainerTL.bottom - ScheduleIncrementHeight ) && scrollTL.top < viewportTL.height && dragElementTL.bottom > ( scrollTL.top + viewportTL.height - 1 ) ) { if ( DEBUG_ScheduleClassDragMove ) { console.info('Scroll down'); } window.scrollBy(0, 1); scrollTL = ScrollLeftTop(); console.log('scrollTL left='+scrollTL.left+' top='+scrollTL.top); } } // END ScheduleClassDragMove. // ScheduleClassDragMoveAbortCheck(evt) // Check for ESC key to abort sheedule class drag. function ScheduleClassDragMoveAbortCheck(evt) { evt = (evt) ? evt : window.event; var theKey; if (evt) { theKey = evt.which; } else { theKey = window.event.keyCode; } console.log('theKey='+theKey); if ( theKey === 27 ) { console.info(dragElement.id+' not dropped in schedule td. dragElementOriginalTL left='+dragElementOriginalTL.left+' top='+dragElementOriginalTL.top); ScheduleClassDragAbort('ScheduleClassDragMoveAbortCheck 2259'); evt.preventDefault(); } } // END ScheduleClassDragMoveAbortCheck. // ScheduleClassDragAbort(by) // Abort sheedule class drag. function ScheduleClassDragAbort(by) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClassDragAbort[] by=${by}`,CG); } // Return dragElement to original position. dragElement.style.zIndex = 1; // Move the class meeting back down the z. let schedulecontainerBounds = ElementBounds('schedulecontainer'); dragElement.style.left = dragElementOriginalTL.left - schedulecontainerBounds.left + 'px'; dragElement.style.top = dragElementOriginalTL.top - schedulecontainerBounds.top + 'px'; // Remove drag event listeners. document.body.removeEventListener('mouseup',ScheduleClassDrop); document.body.removeEventListener('mousemove',ScheduleClassDragMove); document.body.removeEventListener('keydown',ScheduleClassDragMoveAbortCheck); if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClassDragAbort`,SE,ST); console.groupEnd(); } } // END ScheduleClassDragAbort. // ScheduleClassDrop(evt) // ScheduleClassDrop_Change_calendar_class_id(droppedIn_day, droppedIn_mTime) // Change the calendar_class div id, this needs to be changed AFTER the updateInclude() call. function ScheduleClassDrop_Change_calendar_class_id(droppedIn_day, droppedIn_mTime) { var DEBUG_Change_calendar_class_id = false; if ( DEBUG_Change_calendar_class_id ) { console.log('BEGIN ScheduleClassDrop_Change_calendar_class_id[droppedIn_day='+droppedIn_day+', droppedIn_mTime='+droppedIn_mTime+'] dragElement.id='+dragElement.id); } // BEGIN Change the calendar_class div id. if ( DEBUG_Change_calendar_class_id ) { console.log('BEGIN Change the calendar_class div.id.'); } var e_calendar_class = document.getElementById(dragElement.id); // Get the calendar_class div element. if ( DEBUG_Change_calendar_class_id ) { console.log("\t"+'ORIGINAL e_calendar_class.id='+e_calendar_class.id); } var newTimeID = dragElement.id.substr(0, dragElement.id.lastIndexOf("_")) + "_" + droppedIn_day + droppedIn_mTime; e_calendar_class.id = newTimeID; // Change the id. if ( DEBUG_Change_calendar_class_id ) { console.log("\t"+'REPLACED e_calendar_class.id='+e_calendar_class.id); } // END Change the calendar_class div id. if ( DEBUG_Change_calendar_class_id ) { console.log('END Change the calendar_class div.id.'); } // Redraw the calendar DisplaySchedule('ScheduleClassDrop 1944'); } // END ScheduleClassDrop_Change_calendar_class_id. // ScheduleClassDrop(evt) // Handle schedule class drop. function ScheduleClassDrop(evt) { var DEBUG = DEBUG_ON; evt = (evt) ? evt : window.event; if ( DEBUG ) { console.groupCollapsed(PC+'ScheduleClassDrop[] evt.currentTarget.id='+evt.currentTarget.id+' dragElement.id='+dragElement.id,CG); } evt.preventDefault(); dragElement.style.zIndex = 1; // Move the class meeting back down the z. dragElement.mX = mouseX(evt); dragElement.mY = mouseY(evt); //return 'dragdrop'; // Uncomment to stop ScheduleClassDrop(). var DEBUG_AllowAJAXrequest = true; // Allow the AJAX request to update the database. //DEBUG_AllowAJAXrequest = false; // Uncomment to prevent the AJAX request to update the database. if ( DEBUG ) { console.groupCollapsed(PB+'Find out where the class meeting was dropped.',SB,ST); } // Get mouse position. //var mX = mouseX(evt); // unused 2022/04/06 jfm //var mY = mouseY(evt); // unused 2022/04/06 jfm let dragElementTLNow = ElementBounds(dragElement.id,'schedule.js 1675'); // Calculate upper left corner position of class meeting. var dayIndexMin; // Min day index in the schedule view. var dayIndexMax; // Max day index in the schedule view. if ( ScheduleDayView === 'Work week' ) { dayIndexMin = 1; dayIndexMax = 5; } else { dayIndexMin = 0; dayIndexMax = 6; } var droppedInCalendarDayTime = false; // Set true if class meeting was dropped in a scheduleCell. var droppedIn_day = ''; // The day the class meeting was moved to. var droppedIn_mTime = ''; // The mTime the class meeting was moved to. var meetingIndex = 0; // Used to loop thru schedule class meetings. var mScheduleTimeBegin = ScheduleTimeBegin * 60; // The beginning time in the schedule view. var mScheduleTimeEnd = ScheduleTimeEnd * 60; // The ending time in the schedule view. // Get the days of the week. var daysOfWeek = []; var daysOfWeekIndex = 0; for ( var weekdayId in Weekdays ){if(Weekdays.hasOwnProperty(weekdayId)){ daysOfWeek[daysOfWeekIndex] = Weekdays[weekdayId].weekdayD; daysOfWeekIndex++; }} var scId; var scmId = 0; var scmIndex = false; var original_day; var original_mTime; var dayIndex; var droppedIn_eTime; daysOfWeekLoop: for ( var d=dayIndexMin; d<=dayIndexMax; d++ ) { // Loop thru the days in the schedule view. droppedIn_day = daysOfWeek[d]; for ( droppedIn_mTime=mScheduleTimeBegin; droppedIn_mTime<=mScheduleTimeEnd; droppedIn_mTime+=ScheduleTimeIncrement ) { // Loop thru the times in the schedule view. var tdId = droppedIn_day + droppedIn_mTime; //var eTD = document.getElementById(tdId); // The td we are testing. // unused 2022/04/06 jfm let tdBounds = ElementBounds(tdId,'schedule.js 1712'); if ( DEBUG ) { console.log(PC+`tdBounds = ${D_formatJSONstring(tdBounds)}`,CI); } if ( dragElementTLNow.left >= tdBounds.left && dragElementTLNow.left <= tdBounds.right && dragElementTLNow.top >= tdBounds.top && dragElementTLNow.top <= tdBounds.bottom ) { // Did the class meeting get dropped on the schedule? let schedulecontainerBounds = ElementBounds('schedulecontainer'); droppedInCalendarDayTime = true; if ( DEBUG ) { console.log('Dropped in '+tdId); } // Snap class meeting to top left of schedule td. dragElement.style.left = tdBounds.left - schedulecontainerBounds.left + 1 + 'px'; dragElement.style.top = tdBounds.top - schedulecontainerBounds.top + 8 + 'px'; //var newBounds = ElementBounds(dragElement.id,'schedule.js 1603'); //if ( DEBUG ) { console.log('newBounds left='+newBounds.left+' top='+newBounds.top); } break daysOfWeekLoop; // Found where it was dropped so we can stop looping. } // Did the class meeting get dropped on the schedule? } // Loop thru the times in the schedule view. } // Loop thru the days in the schedule view. if ( DEBUG ) { console.log('droppedInCalendarDayTime='+droppedInCalendarDayTime+' droppedIn_day='+droppedIn_day+' droppedIn_mTime='+droppedIn_mTime); } // END Find where the class meeting was dropped. if ( DEBUG ) { console.groupEnd(); console.log(PE+'Find out where the class meeting was dropped.',SE,ST); } if ( droppedInCalendarDayTime ) { // Was the class meeting dropped in a valid scheduleCell? if ( DEBUG ) { console.log(PC+`The class meeting was dropped in a valid scheduleCell.`,CT); } if ( DEBUG ) { console.groupCollapsed(`${PB}Find the scId, scmId, and scmIndex.`,SB,ST); } // Find old day of class meeting. var idParts = dragElement.id.split('_'); scId = parseInt(idParts[2]); original_day = idParts[3].substr(0,1); original_mTime = parseInt(idParts[3].substr(1)); if ( DEBUG ) { console.log('scId='+scId+' original_day='+original_day+' original_mTime='+original_mTime); } if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); } var meetingDay; var bTime; var mTime; if ( DEBUG ) { console.log('Count of meetings = SCMnow[scId].length='+SCMnow[scId].length); } if ( DEBUG ) { console.log('Search meetings for the original day meeting was on = original_day='+original_day); } if ( DEBUG ) { console.log('BEGIN Loop thru meetings.'); } loopMeeting: for ( meetingIndex=0; meetingIndex<SCMnow[scId].length; meetingIndex++ ) { // Loop thru meetings. if ( DEBUG ) { console.log('Meeting days = SCMnow['+scId+']['+meetingIndex+'].days='+SCMnow[scId][meetingIndex].days); } // Change bTime to mTime bTime = SCMnow[scId][meetingIndex].bTime; var timeInMinutes = ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime); if ( DEBUG ) { console.log(PC+'timeInMinutes='+timeInMinutes+' ScheduleTimeIncrement='+ScheduleTimeIncrement,CI); } mTime = parseInt(ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime)); // No longer set to calendar time boundry. if ( DEBUG ) { console.log(PC+'meetingIndex='+meetingIndex+' bTime='+bTime+' mTime='+mTime+' original_mTime='+original_mTime,CI); } if ( mTime === original_mTime ) { // Is this mTime the same as the original_mTime? // Yes, check if the day is also the same. for ( dayIndex=0; dayIndex<SCMnow[scId][meetingIndex].days.length; dayIndex++ ) { // Loop thru meeting days. meetingDay = SCMnow[scId][meetingIndex].days[dayIndex]; if ( meetingDay === original_day ) { // Is this meetingDay the same as the original_day? // Yes, we found the original day and mTime. scmIndex = meetingIndex; scmId = SCMnow[scId][scmIndex].scmId; break loopMeeting; } // Is this meetingDay the same as the original_day? } // Loop thru meeting days. } // Is this mTime the same as the original_mTime? } // Loop thru meetings. if ( DEBUG ) { console.log('scmIndex='+scmIndex+' meetingDay='+meetingDay); } if ( DEBUG ) { console.log('END Loop thru meetings.'); } console.log('scId='+scId+' scmId='+scmId+' scmIndex='+scmIndex+' meetingDay='+meetingDay+' dayIndex='+dayIndex); if ( DEBUG ) { console.groupEnd(); console.log(`${PE}Find the scId, scmId, and scmIndex.`,SE,ST); } if ( DEBUG ) { console.log(PC+`scId = ${scId}, scmId = ${scmId}, scmIndex = ${scmIndex}`,CI); } if ( scmIndex !== false ) { if ( DEBUG ) { console.groupCollapsed(PB+'Find the day diff.',SB,ST); } if ( DEBUG ) { console.log(PC+`Moved SCMnow[${scId}][${dayIndex}] meeting day from ${meetingDay} to ${droppedIn_day}`,CL); } if ( DEBUG ) { console.log(PC+`Moved SCMnow[${scId}][${dayIndex}] meeting mTime from ${mTime} to ${droppedIn_mTime}`,CL); } // Find the day and time diff. var mIndexFrom = daysOfWeek.indexOf(meetingDay); var mIndexTo = daysOfWeek.indexOf(droppedIn_day); var dayDiff = mIndexTo - mIndexFrom; var newDayIndex; if ( DEBUG ) { console.log('mIndexFrom='+mIndexFrom+' mIndexTo='+mIndexTo+' dayDiff='+dayDiff); } var daysOK = true; for ( dayIndex=0; dayIndex<SCMnow[scId][scmIndex].days.length; dayIndex++ ) { meetingDay = SCMnow[scId][scmIndex].days[dayIndex]; var thisDayIndex = daysOfWeek.indexOf(SCMnow[scId][scmIndex].days[dayIndex]); if ( DEBUG ) { console.log('meetingDay='+meetingDay+' thisDayIndex='+thisDayIndex); } newDayIndex = thisDayIndex + dayDiff; if ( newDayIndex < dayIndexMin || newDayIndex > dayIndexMax ) { if ( DEBUG ) { console.log('newDayIndex '+newDayIndex+' out of range '+dayIndexMin+'-'+dayIndexMax); } daysOK = false; break; } } var timeDiff = droppedIn_mTime - mTime; droppedIn_eTime = ConvertTimeToMinutes(SCMnow[scId][scmIndex].eTime) + timeDiff; if ( DEBUG ) { console.log('daysOK='+daysOK+' newDayIndex='+newDayIndex+' day of week='+daysOfWeek[newDayIndex]+' timeDiff='+timeDiff+' droppedIn_mTime='+droppedIn_mTime+' droppedIn_eTime='+droppedIn_eTime); } if ( DEBUG ) { console.groupEnd(); console.log(PE+'Find the day diff.',SE,ST); } // Store needed values in dragElement dragElement.droppedIn_day = droppedIn_day; // diDay dragElement.droppedIn_mTime = droppedIn_mTime; // diMtime dragElement.scId = scId; dragElement.scmId = scmId; dragElement.scmIndex = scmIndex; dragElement.scmNewIndex = SCMnow[scId].length; dragElement.original_day = original_day; // From_day dragElement.original_mTime = original_mTime; // From_mTime var preloadText; var jsReturnCode; if ( SCMnow[scId][scmIndex].days.length === 1 ) { // Is there only one day? // There is only one day, simply update the SCMnow[scId][scmIndex]. if ( DEBUG ) { console.log(PC+`There is only one day for this meeting.`,CI); } if ( DEBUG ) { console.groupCollapsed(PB+'Update the SCMnow JSON object.',SB,ST); } SCMnow[scId][scmIndex].bTime = ConvertMinutesToTime(droppedIn_mTime)+':00'; // Set new bTime. SCMnow[scId][scmIndex].eTime = ConvertMinutesToTime(droppedIn_eTime)+':00'; // Set new eTime. // Find the day it was moved from in the days array and replace it. for ( dayIndex = 0; dayIndex < SCMnow[scId][scmIndex].days.length; dayIndex++ ) { // If this is the day the class was moved from, replace it. if ( SCMnow[scId][scmIndex].days[dayIndex] === original_day) { SCMnow[scId][scmIndex].days[dayIndex] = droppedIn_day; } } if ( DEBUG ) { console.log('REPLACED SCMnow['+scId+']='+JSON.stringify(SCMnow[scId])); } if ( DEBUG_AllowAJAXrequest ) { // Should we perform the AJAX call? // BEGIN Make AJAX call. // Build the URL for the AJAX call if ( DEBUG ) { console.log('BEGIN Make AJAX call.'); } URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassUpdate.php?'; URI += 'task=MoveClassMeeting'; URI += '&scId='+scId; URI += '&scmId='+scmId; URI += '&bTime='+SCMnow[scId][scmIndex].bTime; URI += '&eTime='+SCMnow[scId][scmIndex].eTime; var days = ''; for ( var di=0; di<SCMnow[scId][scmIndex].days.length; di++) { days += SCMnow[scId][scmIndex].days[di]; } URI += '&days='+days; var eId = dragElement.id; preloadText = 'Updating class'; jsReturnCode = "ScheduleClassDrop_Change_calendar_class_id('"+droppedIn_day+"', '"+droppedIn_mTime+"');"; UpdateInclude(URI, eId, preloadText, jsReturnCode); // END Make AJAX call. if ( DEBUG ) { console.log('END Make AJAX call.'); } } else { // Should we perform the AJAX call? // No. if ( DEBUG ) { console.log('AJAX call skipped for now because DEBUG_AllowAJAXrequest is false.'); } // Put the class meeting back. console.info(dragElement.id+' not dropped in schedule td. dragElementOriginalTL left='+dragElementOriginalTL.left+' top='+dragElementOriginalTL.top); dragElement.style.left = dragElementOriginalTL.left + 'px'; dragElement.style.top = dragElementOriginalTL.top + 'px'; } // Should we perform the AJAX call? if ( DEBUG ) { console.groupEnd(); console.log(PE+'Update the SCMnow JSON object.',SE,ST); } } else { // Is there only one day? // There are multiple days, Make an AJAX call and open a Move Class Dialog. if ( DEBUG ) { console.log(PC+`There are ${SCMnow[scId][scmIndex].days.length} days for this meeting.`,CI); } if ( DEBUG ) { console.groupCollapsed(PB+'Make an AJAX call to open a Move Class Dialog.',SB,ST); } console.log('ScheduleCurrent.scheduleId='+ScheduleCurrent.scheduleId+', ScheduleCurrent.departmentId='+ScheduleCurrent.departmentId+', scId='+scId); ScheduleClassDragAbort('ScheduleClassDrop 2500'); console.log(PC+'Stop click for '+dragElement.id,CI); evt.preventDefault(); EventListeners_Remove(); // Get the Move Class Dialog via AJAX. URI = ROOT_http + '/Schedule/MoveClass/MoveClassDialog.php'; URI += '?scheduleclassId='+scId; URI += '&divId='+dragElement.id; URI += '&droppedIn_day='+droppedIn_day; URI += '&droppedIn_mTime='+droppedIn_mTime; URI += '&scheduleclassmeetingId='+scmId; preloadText = 'Getting class meetings for move'; UpdateLoadingText = preloadText; jsReturnCode = "ScheduleClass_MoveSingleMeetingDiv('ScheduleClassDrop~2531');"; jsReturnCode += ` OpenDialog(${ScheduleCurrent.departmentId}, ${scId});`; jsReturnCode += ` PositionMoveClassDialog();`; console.log('jsReturnCode='+jsReturnCode); ScheduleClassOpenCount = 0; UpdateInclude(URI, 'dialogDiv', preloadText, jsReturnCode); if ( DEBUG ) { console.groupEnd(); console.log(PE+'Make an AJAX call to open a Move Class Dialog.',SE,ST); } } // Is there only one day? } } else { // Was the class meeting dropped in a valid scheduleCell? if ( DEBUG ) { console.log(PC+'The class meeting was NOT dropped in a valid scheduleCell.',CF); } evt.preventDefault(); ScheduleClassDragAbort('ScheduleClassDrop 2542'); } // Was the class meeting dropped in a valid scheduleCell? evt.preventDefault(); document.body.removeEventListener('mouseup',ScheduleClassDrop); document.body.removeEventListener('mousemove',ScheduleClassDragMove); document.body.removeEventListener('keydown',ScheduleClassDragMoveAbortCheck); //evt.preventDefault(); if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClassDrop`,SE,ST); console.groupEnd(); } } // END ScheduleClassDrop. // OpenDialog(scheduleclassId, CallCount) // Open the dialogDiv with the scheduleclass info loaded. function OpenDialog(scheduleclassId=0, CallCount=0) { var DEBUG = true; var DEBUG_CourseNumber = true; let courseNumber = 'NOLOOKUP'; if (DEBUG_CourseNumber) { for ( var scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ if (scheduleclassId == scId) { courseNumber = ScheduleClass[scId].Course; } }} } if ( DEBUG ) { console.group(PC+`OpenDialog[scheduleclassId = ${scheduleclassId}, ${courseNumber}, CallCount = ${CallCount}]`,CG);//Collapsed } else { console.log(PC+`OpenDialog[scheduleclassId = ${scheduleclassId}, ${courseNumber}, CallCount = ${CallCount}]`,CH); } if ( DEBUG && dragElement && dragElement.id ) { console.log(PC+`dragElement = ${NL}"id":"${dragElement.id}" ${D_formatJSONstring(dragElement)}`,CL); } var e_dialogDiv = document.getElementById('dialogDiv'); dialogDivContents = e_dialogDiv.innerHTML; if ( dialogDivContents.indexOf('Load OK') !== -1 ) { // Did the dialog contents load OK? // Yes. if ( DEBUG ) { console.log(`${PC}Load OK`,CT); } document.addEventListener('keydown',KeydownDialog); e_dialogDiv.style.display = 'block'; ScheduleClassDialog_SetWidth('OpenDialog 2548'); // Set dialog width. // BEGIN Position the dialog. var e_dialogContainer = document.getElementById('dialogContainer'); //.addEventListener('keydown',KeydownDialog); var docScroll = document.documentElement; var docLeft = (window.pageXOffset || docScroll.scrollLeft) - (docScroll.clientLeft || 0); var docTop = (window.pageYOffset || docScroll.scrollTop) - (docScroll.clientTop || 0); if ( DEBUG ) { console.log(PC+'docLeft='+docLeft+' docTop='+docTop,CL); } if ( DEBUG ) { console.log(PC+'dialogContainerLeft='+dialogContainerLeft+' dialogContainerTop='+dialogContainerTop,CL); } if ( dialogContainerLeft < docLeft ) { dialogContainerLeft = docLeft; e_dialogContainer.style.left = dialogContainerLeft+'px'; if ( DEBUG ) { console.log(PC+'dialogContainer left changed to docLeft='+dialogContainerLeft,CS); } } if ( dialogContainerLeft < 0 ) { dialogContainerLeft = 0; e_dialogContainer.style.left = dialogContainerLeft+'px'; if ( DEBUG ) { console.log(PC+'dialogContainer left changed to 0',CS); } } if ( dialogContainerTop < docTop ) { dialogContainerTop = docTop; e_dialogContainer.style.top = dialogContainerTop+'px'; if ( DEBUG ) { console.log(PC+'dialogContainer top changed to docTop='+dialogContainerTop,CS); } } // Make sure dialog is rendered in the viewport if ( dialogContainerTop > docTop ) { // Get the distance of the sidenav from the top // By getting this, it insures the dialogDiv will never render above the top of the sidenav // Without this the dialog could render on the top navbar var e_sidenav = document.getElementById("navSidenav"); var sidenavDistanceFromTop = parseInt(e_sidenav.style.top); // Check to see if dialog will be rendered above the sidenav if ( dialogContainerTop >= sidenavDistanceFromTop ) { dialogContainerTop = sidenavDistanceFromTop; e_dialogContainer.style.top = dialogContainerTop+'px'; if ( DEBUG ) { console.log(PC+'dialogContainer top changed to sidenavDistanceFromTop='+dialogContainerTop,CS); } } else { dialogContainerTop = docTop; e_dialogContainer.style.top = dialogContainerTop+'px'; if ( DEBUG ) { console.log(PC+'dialogContainer top changed to docTop='+dialogContainerTop,CS); } } } else { if ( DEBUG ) { console.log('dialogContainerTop ['+dialogContainerTop+'] <= docTop ['+docTop+']'); } } if ( dialogContainerTop < 0 ) { dialogContainerTop = 0; e_dialogContainer.style.top = dialogContainerTop+'px'; if ( DEBUG ) { console.log(PC+'dialogContainer top set to 0',CS); } } //e_dialogDiv.style.display = 'block'; // END Position the dialog. // Get legend button and add drag event listener var e_legends = e_dialogContainer.getElementsByTagName("legend"); e_legends[0].onmousedown = ScheduleClassDialogDrag; } else { // Did the dialog contents load OK? // No. Try the UpdateInclude again. if ( DEBUG ) { console.log(`${PC}Load Failed`,CF); } if ( DEBUG ) { if (!CallCount) { console.log(PC+'Make first AJAX call.',CC); } else { console.log(PC+'Dialog in not OK after '+CallCount+' tries.',CE); } } if ( CallCount < 10 ) { CallCount++; URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassForm.php?task=EditCLass'; if ( typeof scheduleclassId === 'undefined' ) { scheduleclassId = 0; } URI += '&scheduleclassId='+scheduleclassId; let eId = 'dialogDiv'; let preloadText = 'Getting class'; UpdateInclude(URI, eId, preloadText); let callTimer = CallCount*200; if ( DEBUG ) { console.log(`${PC}callTimer=${callTimer}`,CI); } setTimeout(function(){ OpenDialog(scheduleclassId, CallCount); },callTimer); } else { //alert('OpenDialog: Never got return from URI='+URI); console.log(`${PC}OpenDialog: Never got return from URI=${URI}`,CF); let e_errorDiv = document.getElementById('errorDiv'); e_errorDiv.innerHTML = `ERROR: There was a problem communicating with the server. Unable to get the class information within 1 second. Please try again. If this error continues, please notify the site Administrator.`; ttLoad(e_errorDiv, '', '', 'error', true); } } // Did the dialog contents load OK? if ( DEBUG ) { console.groupEnd(); console.log(PC+'END '+PC+'OpenDialog',SE,ST); } } // END OpenDialog. // OpenTextbox(evt, title, text, buttons, returnFunction) // Open the textboxDiv. // evt = event that called this function. // title = title of the textbox. // text = text for the textbox. Can contain html. // buttons = button text in an array. // e.g. ['Yes','No'] // Clicking Yes will return 0 and clicking No will return 1 // (the array index of the button that was clicked). // returnFunction = name of a callback function. // targetLocation = name of field to position TextBox (optional). function OpenTextbox(evt, title, text, buttons, returnFunction, targetLocation=false) { var DEBUG = true; if ( DEBUG ) { console.group(PC+`OpenTextbox[title=${title} id=${evt.target.id}]`,CG); }//Collapsed if ( DEBUG ) { console.log(PC+`title=${title}, text=${text}, buttons=${buttons}`,CI); } if ( DEBUG && dragElement && dragElement.id ) { console.log(PC+`dragElement = ${NL}"id":"${dragElement.id}" ${D_formatJSONstring(dragElement)}`,CL); } var e_textboxDiv = document.getElementById('textboxDiv'); let textboxDivContents = `<fieldset><legend>${title}</legend>\n${text}\n<br><br>\n`; for ( let b=0; b<buttons.length; b++ ) { textboxDivContents += `<input type="button" class="textboxButton" value="${buttons[b]}" onClick="${returnFunction}(${b});">`; } textboxDivContents += `\n</fieldset>`; e_textboxDiv.innerHTML = textboxDivContents; e_textboxDiv.style.display = 'table-cell'; // BEGIN Position the textbox. var e_textboxContainer = document.getElementById('textboxContainer'); let textboxBounds = ElementBounds('textboxDiv'); let textboxWidthOffset = textboxBounds.width/2; let targetBounds; if (!targetLocation) { targetBounds = ElementBounds(evt.target.id); } else { targetBounds = ElementBounds(targetLocation); } if ( DEBUG ) { console.log(`${PC}targetBounds=${JSON.stringify(targetBounds)}`,CL); } // textboxContainerLeft = targetBounds.left + targetBounds.width/2 - textboxWidthOffset; textboxContainerLeft = targetBounds.left + targetBounds.width + 50; e_textboxContainer.style.left = textboxContainerLeft+'px'; textboxContainerTop = targetBounds.bottom; e_textboxContainer.style.top = textboxContainerTop+'px'; //.addEventListener('keydown',KeydownTextbox); var docScroll = document.documentElement; var docLeft = (window.pageXOffset || docScroll.scrollLeft) - (docScroll.clientLeft || 0); var docTop = (window.pageYOffset || docScroll.scrollTop) - (docScroll.clientTop || 0); if ( DEBUG ) { console.log(PC+'docLeft='+docLeft+' docTop='+docTop,CL); } if ( DEBUG ) { console.log(PC+'textboxContainerLeft='+textboxContainerLeft+' textboxContainerTop='+textboxContainerTop,CL); } if ( textboxContainerLeft < docLeft ) { textboxContainerLeft = docLeft; e_textboxContainer.style.left = textboxContainerLeft+'px'; if ( DEBUG ) { console.log(PC+'textboxContainer left changed to docLeft='+textboxContainerLeft,CS); } } if ( textboxContainerLeft < 0 ) { textboxContainerLeft = 0; e_textboxContainer.style.left = textboxContainerLeft+'px'; if ( DEBUG ) { console.log(PC+'textboxContainer left changed to 0',CS); } } if ( textboxContainerTop < docTop ) { textboxContainerTop = docTop; e_textboxContainer.style.top = textboxContainerTop+'px'; if ( DEBUG ) { console.log(PC+'textboxContainer top changed to docTop='+textboxContainerTop,CS); } } // Make sure textbox is rendered in the viewport if ( textboxContainerTop > docTop ) { // Get the distance of the sidenav from the top // By getting this, it insures the textboxDiv will never render above the top of the sidenav // Without this the textbox could render on the top navbar var e_sidenav = document.getElementById("navSidenav"); var sidenavDistanceFromTop = parseInt(e_sidenav.style.top); // Check to see if textbox will be rendered above the sidenav if ( textboxContainerTop >= sidenavDistanceFromTop ) { textboxContainerTop = sidenavDistanceFromTop; e_textboxContainer.style.top = textboxContainerTop+'px'; if ( DEBUG ) { console.log(PC+'textboxContainer top changed to sidenavDistanceFromTop='+textboxContainerTop,CS); } } else { textboxContainerTop = docTop; e_textboxContainer.style.top = textboxContainerTop+'px'; if ( DEBUG ) { console.log(PC+'textboxContainer top changed to docTop='+textboxContainerTop,CS); } } } else { if ( DEBUG ) { console.log('textboxContainerTop ['+textboxContainerTop+'] <= docTop ['+docTop+']'); } } if ( textboxContainerTop < 0 ) { textboxContainerTop = 0; e_textboxContainer.style.top = textboxContainerTop+'px'; if ( DEBUG ) { console.log(PC+'textboxContainer top set to 0',CS); } } if ( DEBUG ) { console.groupEnd(); } } // END OpenTextbox. // ScheduleClass_OpenAddDialog() // Add a class to the schedule. function ScheduleClass_OpenAddDialog() { var DEBUGAdd = true; if ( DEBUGAdd ) { console.warn('ScheduleClass_OpenAddDialog[]'); } OpenDialog(); document.addEventListener('scroll', ScrollDialogDiv); return false; } // END ScheduleClass_OpenAddDialog. // ScheduleClass_OpenEditDialog(evt) // Edit the class. function ScheduleClass_OpenEditDialog(evt) { var DEBUG = false; evt = (evt) ? evt : window.event; if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClass_OpenEditDialog[] evt.currentTarget.id = ${evt.currentTarget.id}, mousedownFlag = ${mousedownFlag}`,CG); } ClearTextSelection(); evt.currentTarget.removeEventListener('mousemove', ScheduleClassDragCheckWait); if ( mousedownFlag === 'mousemove' || evt.button !== 0 ) { mousedownFlag = ''; if ( DEBUG ) { console.log(PC+`mousedownFlag = ${mousedownFlag}`,CI); } } else { mousedownFlag = 'click'; if ( DEBUG ) { console.log(PC+`mousedownFlag = ${mousedownFlag}`,CI); } // Get scheduleclassId. var calendar_class_parts = this.id.split('_'); currentOpenScheduleClassId = parseInt(calendar_class_parts[2]); // Clear the dialogDiv div. var e_dialogDiv = document.getElementById('dialogDiv'); e_dialogDiv.innerHTML = ''; if ( DEBUG ) { console.log('ScheduleCurrent.scheduleId='+ScheduleCurrent.scheduleId+', ScheduleCurrent.departmentId='+ScheduleCurrent.departmentId+', currentOpenScheduleClassId='+currentOpenScheduleClassId+'];'); } ScheduleClassOpenCount = 0; // Reset the ScheduleClassOpenCount counter. OpenDialog(currentOpenScheduleClassId); document.addEventListener('scroll', ScrollDialogDiv); } if ( DEBUG ) { console.log(PC+`mousedownFlag = ${mousedownFlag}`,CL); } if ( DEBUG ) { console.groupEnd(); console.log(PC+'END '+PC+'ScheduleClass_OpenEditDialog',SE,ST); } return false; } // END ScheduleClass_OpenEditDialog. // ScrollDialogDiv() // Reposition the Schedule Class dialog on page scroll. function ScrollDialogDiv() { var DEBUG = false; if ( DEBUG ) { console.group(PC+'ScrollDialogDiv[]',CG); } if ( DEBUG ) { console.log(PC+'ScrollDialogDiv[] does nothing for now.',CF); } if ( DEBUG ) { console.groupEnd(); } } // END ScrollDialogDiv. // ScheduleImportClasses(thisTask) // Handle class import from another schedule. function ScheduleImportClasses(thisTask) { var DEBUG_ScheduleImportClasses = true; if ( typeof thisTask === 'undefined' ) { thisTask = ''; } if ( DEBUG_ScheduleImportClasses ) { console.warn('ScheduleViewSettings[thisTask='+thisTask+']'); } var eId = 'div_ScheduleFunctionsContainer'; var e = document.getElementById(eId); var eDisplay = e.style.display; // Get schedulecontainer height. if ( DEBUG_ScheduleImportClasses ) { console.log('eDisplay='+eDisplay); } if ( DEBUG_ScheduleImportClasses && eDisplay === 'block' ) { console.log("e.innerHTML.indexOf('Import classes into')="+e.innerHTML.indexOf('Import classes into')); } if ( thisTask === '' && eDisplay === 'block' && e.innerHTML.indexOf('Import classes into') !== -1 ) { ScheduleTaskShow('ScheduleImportClasses 1528'); return false; } else { ScheduleTaskHide(); } switch ( thisTask ) { // switch thisTask. case '': URI = ROOT_http +'/Schedule/ScheduleImportClasses/ScheduleImportClasses.php'; var preloadText = '<br><br><span class="bold info">Getting import form. Please wait ...</span><br><br><br>'; UpdateInclude(URI, eId, preloadText); //setTimeout(DisplaySchedule,50); window.scrollTo(0, 0); break; case 'Import classes': if ( DEBUG_ScheduleImportClasses ) { } break; case 'Cancel': document.getElementById(eId).style.display = 'none'; ScheduleTaskShow('ScheduleImportClasses 1552'); break; } // switch thisTask. return false; } // END ScheduleImportClasses. // ScheduleImportClasses_ScheduleButtonCheck(e) // Enable/disable Change schedule button. function ScheduleImportClasses_ScheduleButtonCheck(e) { var scheduleIdSelected = e.value; console.log('scheduleIdSelected='+scheduleIdSelected); if ( scheduleIdSelected ) { document.getElementById('btn_Import_schedule_classes').disabled = false; } else { document.getElementById('btn_Import_schedule_classes').disabled = true; } } // END ScheduleImportClasses_ScheduleButtonCheck. // ScheduleImportClasses_ParseButtonCheck(e) // Enable/disable Change schedule button. function ScheduleImportClasses_ParseButtonCheck(e) { var scheduleIdSelected = e.value; console.log('scheduleIdSelected='+scheduleIdSelected); if ( scheduleIdSelected ) { document.getElementById('btn_Import_parsed_classes').disabled = false; } else { document.getElementById('btn_Import_parsed_classes').disabled = true; } } // END ScheduleImportClasses_ParseButtonCheck. // ScheduleTaskHide() // Hide the schedule and display the div_ScheduleFunctionsContainer. function ScheduleTaskHide() { if ( document.getElementById('schedulecontainer') ) { var ContainerHeight = Math.max(document.getElementById('schedulecontainer').offsetHeight,document.getElementById('div_ScheduleFunctionsContainer').offsetHeight); // Get schedulecontainer height. //console.log('ContainerHeight='+ContainerHeight); document.getElementById('schedulecontainer').style.display = 'none'; // Hide the main schedulecontainer. document.getElementById('div_CalendarKey').style.display = 'none'; // Hide the calendar key. var scheduleClasses = document.getElementsByClassName('calendar_class'); for ( var i=0; i<scheduleClasses.length; i++ ) { scheduleClasses[i].style.display = 'none'; // Hide each schedule class. } document.getElementById('div_ScheduleFunctionsContainer').style.height = ContainerHeight+'px'; // Set div_ScheduleFunctionsContainer height the same as the main schedulecontainer. document.getElementById('div_ScheduleFunctionsContainer').style.display = 'block'; // Show the div_ScheduleFunctionsContainer. } return false; } // END ScheduleTaskHide. // ScheduleTaskShow(callDisplaySchedule) // Show the schedule and hide the div_ScheduleFunctionsContainer. function ScheduleTaskShow(by,callDisplaySchedule) { console.warn('ScheduleTaskShow[by='+by+', callDisplaySchedule='+callDisplaySchedule+']'); if ( document.getElementById('schedulecontainer') ) { //document.getElementById('schedulecontainer').style.display = 'block'; // Show the main schedulecontainer. document.getElementById('div_CalendarKey').style.display = 'block'; // Show the calendar key. var scheduleClasses = document.getElementsByClassName('calendar_class'); for ( var i=0; i<scheduleClasses.length; i++ ) { scheduleClasses[i].style.display = 'block'; // Show each schedule class. } document.getElementById('div_ScheduleFunctionsContainer').style.display = 'none'; // Hide the div_ScheduleFunctionsContainer. } //if ( typeof callDisplaySchedule === 'undefined' || !callDisplaySchedule ) { DisplaySchedule('1613 '+by); } // Re-display the schedule. DisplaySchedule('ScheduleTaskShow 1622 '+by); return false; } // END ScheduleTaskShow. // ScheduleViewSettings(makeChange) // Set schedule settings: calendar_dayview, calendar_timebegin, calendar_timeend, calendar_timeincrement, and calendar_incrementheight. function ScheduleViewSettings(makeChange) { var DEBUG = false; if ( typeof makeChange === 'undefined' ) { makeChange = ''; } if ( DEBUG ) { console.group(`${PC}ScheduleViewSettings[makeChange=${makeChange}]`,CG); }//Collapsed var eId = 'div_ScheduleFunctionsContainer'; var e = document.getElementById(eId); var eDisplay = e.style.display; // Get schedulecontainer height. if ( DEBUG ) { console.log('eDisplay='+eDisplay); } if ( DEBUG && eDisplay === 'block' ) { console.log("e.innerHTML.indexOf('Schedule view settings')="+e.innerHTML.indexOf('Schedule view settings')); } if ( makeChange === '' && eDisplay === 'block' && e.innerHTML.indexOf('Schedule view settings') !== -1 ) { ScheduleTaskShow('schedule2.js ScheduleViewSettings 149'); return false; } else { ScheduleTaskHide(); } switch ( makeChange ) { // switch makeChange. case '': URI = ROOT_http +'/Schedule/ScheduleViewSettings/ScheduleViewSettings.php'; var preloadText = '<br><br><span class="bold info">Getting schedule settings. Please wait ...</span><br><br><br>'; UpdateInclude(URI, eId, preloadText); //setTimeout(DisplaySchedule,50); window.scrollTo(0, 0); break; case 'Update schedule settings via javascript': // Get settings. ScheduleDayView = getRadioValue('calendar_dayview'); // calendar_dayview is work/full week. console.log('ScheduleDayView='+ScheduleDayView); e = document.getElementById('inp_calendar_timebegin'); ScheduleTimeBegin = parseInt(e.options[e.selectedIndex].value); console.log('ScheduleTimeBegin='+ScheduleTimeBegin); e = document.getElementById('inp_calendar_timeend'); ScheduleTimeEnd = parseInt(e.options[e.selectedIndex].value); console.log('ScheduleTimeEnd='+ScheduleTimeEnd); e = document.getElementById('inp_calendar_timeincrement'); ScheduleTimeIncrement = parseInt(e.options[e.selectedIndex].value); console.log('ScheduleTimeIncrement='+ScheduleTimeIncrement); e = document.getElementById('inp_calendar_incrementheight'); ScheduleIncrementHeight = parseInt(e.options[e.selectedIndex].value); console.log('ScheduleIncrementHeight='+ScheduleIncrementHeight); // Need to ensure settings are valid. // Calc ScheduleHeightMultiplier. ScheduleHeightMultiplier = parseInt(ScheduleIncrementHeight) / parseInt(ScheduleTimeIncrement); console.log('ScheduleHeightMultiplier='+ScheduleHeightMultiplier); // Calc ScheduleViewDays. switch ( ScheduleDayView ) { case 'Full week': ScheduleViewDays = ScheduleDaysFullWeek; // Should get the string from Weekdays. break; case 'Work week': ScheduleViewDays = ScheduleDaysWorkWeek; // Should get the string from Weekdays. break; } console.log('ScheduleViewDays='+ScheduleViewDays); // Save settings in the database. URI = ROOT_http + '/Schedule/ScheduleViewSettings/ScheduleViewSettings.php?Update=true'; URI += '&calendar_dayview='+ScheduleDayView.replace(' ','%20'); URI += '&calendar_timebegin='+ScheduleTimeBegin; URI += '&calendar_timeend='+ScheduleTimeEnd; URI += '&calendar_timeincrement='+ScheduleTimeIncrement; URI += '&calendar_incrementheight='+ScheduleIncrementHeight; eId = 'div_ScheduleFunctionsContainer'; preloadText = 'Saving schedule view settings ...'; UpdateInclude(URI, eId, preloadText); ScheduleTaskShow('schedule2.js ScheduleViewSettings 203',false); break; case 'Cancel': document.getElementById(eId).style.display = 'none'; ScheduleTaskShow('schedule2.js ScheduleViewSettings Cancel 207'); break; } // switch makeChange. if ( DEBUG ) { console.groupEnd(); } return false; // getRadioValue(radioName) // Returns the value of the radio button that is checked. // Returns empty string if no buttons selected or radio control does not exist. function getRadioValue(radioName) { var DEBUG_getRadioValue = false; if ( DEBUG_getRadioValue ) { console.warn('getRadioValue['+radioName+']'); } if ( !radioName ) { if ( DEBUG_getRadioValue ) { console.log('radioName is empty.'); } return ""; } var radioObj = document.getElementsByName(radioName); if ( !radioObj ) { if ( DEBUG_getRadioValue ) { console.log('radio with name ['+radioName+'] not found.'); } } var radioLength = radioObj.length; if ( radioLength === undefined ) { // Only one radio button. if ( radioObj.checked ) { if ( DEBUG_getRadioValue ) { console.log('Single radio value=.'+radioObj.value); } return radioObj.value; } else { if ( DEBUG_getRadioValue ) { console.log('Single radio not selected.'); } return ""; } } else { for(var i = 0; i < radioLength; i++) { // Loop thru radio buttons. if (radioObj[i].checked) { if ( DEBUG_getRadioValue ) { console.log('Multiple radio value=.'+radioObj[i].value); } return radioObj[i].value; } // Loop thru radio buttons. } } if ( DEBUG_getRadioValue ) { console.log('Multiple radio none selected.'); } return ""; } // END getRadioValue. } // END ScheduleViewSettings. // SetClassEndTime(e) // Set the class end time based on the # credits, # meeting days, and 'As lab'. function SetClassEndTime(e) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.groupCollapsed(`${PC}SetClassEndTime[e.id=${e.id}]`,CG); }//Collapsed //document.getElementById('errorDiv').style.display = 'none'; //divHide('errorDiv'); // Get scmId. var eIdParts = e.id.split('_'); let scmId = eIdParts[2]; var EndTime; var chkAutoEndId = 'chk_AutoEnd_'+scmId; if ( DEBUG ) { console.log('chkAutoEndId='+chkAutoEndId); } if ( document.getElementById(chkAutoEndId).checked ) { document.getElementById('spn_asLab_'+scmId).style.display = 'inline'; // Get course credits. let courseId = document.getElementById('id_courseId').value; if ( courseId ) { // Is the courseId set? var CourseCredits = Course[courseId].Cr; if ( DEBUG ) { console.log(Course[courseId].Title+' CourseCredits='+CourseCredits); } // Get meeting days. var days = 0; var radioId; for ( var weekdayId in Weekdays ){if(Weekdays.hasOwnProperty(weekdayId)){ radioId = 'chk_Weekday_'+scmId+'_'+weekdayId; console.log('radioId='+radioId+' document.getElementById(radioId).checked='+document.getElementById(radioId).checked); if ( document.getElementById(radioId).checked ) { days++; } }} if ( DEBUG ) { console.log('days='+days); } if ( days > 0 ) { // Get beginning time. var BeginTime = document.getElementById('id_scheduleclassmeetingBeginTime_'+scmId).value; if ( BeginTime ) { var flags = ''; if ( BeginTime.indexOf('m') !== -1 ) { flags = 'a'; } else { if ( BeginTime.indexOf('M') !== -1 ) { flags = 'P'; } } var BeginMin = ConvertTimeToMinutes(BeginTime); if ( DEBUG ) { console.log('BeginTime='+BeginTime+' BeginMin='+BeginMin+' flags='+flags); } var meetingMinutes; if ( !document.getElementById('chk_AsLab_'+scmId).checked ) { meetingMinutes = parseInt( 50 * parseInt(CourseCredits) / days ); } else { meetingMinutes = parseInt( 110 * parseInt(CourseCredits) / days ); } var EndMin = BeginMin + meetingMinutes; if ( DEBUG ) { console.log('meetingMinutes='+meetingMinutes+' EndMin='+EndMin); } EndTime = ConvertMinutesToTime(EndMin,flags+'h'); if ( DEBUG ) { console.log('EndTime='+EndTime); } } else { EndTime = ''; if ( DEBUG ) { console.log('No begin time, EndTime='+EndTime); } } } else { EndTime = ''; if ( DEBUG ) { console.log('No days, EndTime='+EndTime); } } let e_scheduleclassmeetingEndTime = document.getElementById('id_scheduleclassmeetingEndTime_'+scmId); e_scheduleclassmeetingEndTime.value = EndTime; let e_scheduleclassmeetingBeginTime = document.getElementById('id_scheduleclassmeetingBeginTime_'+scmId); // Clear errors. divHide('errorDiv'); if ( DEBUG ) { console.log(`${PC}e_scheduleclassmeetingBeginTime.className=${e_scheduleclassmeetingBeginTime.className} e_scheduleclassmeetingEndTime.className=${e_scheduleclassmeetingEndTime.className}`,CA); } if ( e_scheduleclassmeetingBeginTime.className.indexOf('error') !== -1 ) { if ( DEBUG ) { console.log(`${PC}Removing error from scheduleclassmeetingBeginTime.`,CD); } e_scheduleclassmeetingBeginTime.className = e_scheduleclassmeetingBeginTime.className.replace(' error',''); // Remove error. } if ( e_scheduleclassmeetingEndTime.className.indexOf('error') !== -1 ) { if ( DEBUG ) { console.log(`${PC}Removing error from scheduleclassmeetingEndTime.`,CD); } e_scheduleclassmeetingEndTime.className = e_scheduleclassmeetingEndTime.className.replace(' error',''); // Remove error. } } // Is the courseId set? } else { document.getElementById('spn_asLab_'+scmId).style.display = 'none'; } Validate_ScheduleClass(); if ( DEBUG ) { console.groupEnd(); } } // END SetClassEndTime. // SetupBuildingSelectOptions(e) // Set the options for the building select. function SetupBuildingSelectOptions(e) { var DEBUG_SetupBuildingSelectOptions = false; if ( DEBUG_SetupBuildingSelectOptions ) { console.log('BEGIN SetupBuildingSelectOptions[e.Id='+e.id+']'); } // Get the campusId. campusId = parseInt(e.value); if ( DEBUG_SetupBuildingSelectOptions ) { console.log('campusId='+campusId); } var eId = e.id.split('_'); var scmId = eId[1]; var campusIndex = parseInt(eId[2]); // Get the room order. if ( DEBUG_SetupBuildingSelectOptions ) { console.log('scmId='+scmId+' campusIndex='+campusIndex); } // Clear the building select. var eBuildingId = 'selBuilding_'+scmId+'_'+campusIndex; if ( DEBUG_SetupBuildingSelectOptions ) { console.log('eBuildingId='+eBuildingId); } var eBuilding = document.getElementById(eBuildingId); // Get building select. eBuilding.options.length = 0; // Clear the room select. var eRoomId = 'selRoom_'+scmId+'_'+campusIndex; if ( DEBUG_SetupBuildingSelectOptions ) { console.log('eRoomId='+eRoomId); } var eRoom = document.getElementById(eRoomId); // Get room select. eRoom.options.length = 0; var opt = document.createElement('option'); opt.value = ''; opt.innerHTML = ''; eBuilding.appendChild(opt); /**/ if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding.length='+CollegeBuilding.length+' campusId='+campusId); } for ( var i=0; i<CollegeBuilding.length; i++ ) { //if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding['+i+'].campusId='+CollegeBuilding[i].campusId); } if ( CollegeBuilding[i].campusId === campusId ) { if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding['+i+'].buildingId='+CollegeBuilding[i].buildingId); } if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding['+i+'].Code='+CollegeBuilding[i].Code); } opt = document.createElement('option'); opt.value = CollegeBuilding[i].buildingId; //if ( buildingId === CollegeBuilding[i].buildingId ) { opt.selected = true; } opt.innerHTML = CollegeBuilding[i].Code; eBuilding.appendChild(opt); } } // Clear and hide the room select. eRoom = document.getElementById('selRoom_'+scmId+'_'+campusIndex); // Get room select. eRoom.options.length = 0; /**/ if ( !isNaN(campusId) ) { //document.getElementById('labBuilding_'+scmId+'_'+campusIndex).style.display = 'inline-block'; document.getElementById('labBuilding_'+scmId+'_'+campusIndex).classList.remove("hidden"); } else { var eBuildingLabelId = 'labBuilding_'+scmId+'_'+campusIndex; if ( DEBUG_SetupBuildingSelectOptions ) { console.log('Hide '+eBuildingLabelId); } var eBuildingLabel = document.getElementById(eBuildingLabelId); eBuildingLabel.classList.add("hidden"); RoomLine_RoomSelect_Hide(scmId, campusIndex); // Hide the room select (label). } SetupNextCampusSelectOptions(scmId, campusIndex); } // END SetupBuildingSelectOptions. // SetupInstructorOptions(e) // Set the options for the next instructor select. // Any already selected instructores are not added to the select. function SetupInstructorOptions(e) { var DEBUG_setInstructor = false; var c, thisSelectId, thisSelect; let SelectedInstructorId; if ( DEBUG_setInstructor ) { console.log('BEGIN SetupInstructorOptions[e.id='+e.id+']'); } var eIdParts = e.id.split('_'); var scmId = eIdParts[1]; //var campusIndex = parseInt(eIdParts[2]); //var instructorIndex = parseInt(eIdParts[3]); //var instructorIndex = parseInt(eIdParts[2]); // unused 2022/04/06 jfm if ( DEBUG_setInstructor ) { console.log('ScheduleInstructor.length='+ScheduleInstructor.length); } let instructorIdsSelected = []; // Array of instructorIds that have been selected to this point. for ( c=0; c<ScheduleInstructor.length; c++ ) { // Loop thru instructor indexes. thisSelectId = 'selInstructor_'+scmId+'_'+c; if ( DEBUG_setInstructor ) { console.log('thisSelectId='+thisSelectId); } thisSelect = document.getElementById(thisSelectId); SelectedInstructorId = parseInt(thisSelect.options[thisSelect.selectedIndex].value); if ( DEBUG_setInstructor ) { console.log('SelectedInstructorId='+SelectedInstructorId); } if ( !isNaN(SelectedInstructorId) ) { instructorIdsSelected.push(SelectedInstructorId); } // Add the instructorId to the array. } // Loop thru instructor indexes. if ( DEBUG_setInstructor ) { console.log('instructorIdsSelected='+instructorIdsSelected); } for ( c=0; c<ScheduleInstructor.length; c++ ) { // Loop thru instructor indexes. thisSelectId = 'selInstructor_'+scmId+'_'+c; if ( DEBUG_setInstructor ) { console.log('thisSelectId='+thisSelectId); } thisSelect = document.getElementById(thisSelectId); console.log('thisSelect.selectedIndex='+thisSelect.selectedIndex); SelectedInstructorId = parseInt(thisSelect.options[thisSelect.selectedIndex].value); let SelectedIndex; if ( !isNaN(SelectedInstructorId) ) { SelectedIndex = thisSelect.selectedIndex; } else { SelectedInstructorId = 0; SelectedIndex = 0; } if ( DEBUG_setInstructor ) { console.log('SelectedInstructorId='+SelectedInstructorId+' SelectedIndex='+SelectedIndex); } thisSelect.options.length = 0; var opt = document.createElement('option'); opt.value = ''; opt.innerHTML = ''; thisSelect.appendChild(opt); /**/ for ( var i=0; i<ScheduleInstructor.length; i++ ) { if ( ScheduleInstructor[i].instructorId === SelectedInstructorId || instructorIdsSelected.indexOf(ScheduleInstructor[i].instructorId) === -1 ) { if ( DEBUG_setInstructor ) { console.log('Adding selInstructor_'+c+' option for '+ScheduleInstructor[i].Name+'.'); } opt = document.createElement('option'); opt.value = ScheduleInstructor[i].instructorId; opt.innerHTML = ScheduleInstructor[i].Name; thisSelect.appendChild(opt); } } if ( SelectedInstructorId ) { //thisSelect.selectedIndex = SelectedInstructorId; thisSelect.value = SelectedInstructorId; } } // Loop thru instructor indexes. } // END SetupInstructorOptions. // SetupNextCampusSelectOptions(scmId, campusIndex) // scmId = the scheduleclassmeetingId // campusIndex = the current campusIndex. // Set the options for the next campus select (campusIndex+1). // Any already selected campuses are not added to the next campus select. function SetupNextCampusSelectOptions(scmId, campusIndex) { var DEBUG = false; if ( DEBUG ) { console.group(`${PC}SetupNextCampusSelectOptions[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed if ( DEBUG ) { console.log(`${PC}END ${PC}SetupNextCampusSelectOptions`,SE,ST); console.groupEnd(); } if ( DEBUG ) { console.log('CollegeCampus.length='+CollegeCampus.length); } // Get already selected (used) campuses. let campusIdsSelected = []; // Array of campusIds that have been selected to this point. for ( var c = 0; c <= campusIndex; c++ ) { // Loop thru campuses. var thisSelectId = 'selCampus_'+scmId+'_'+c; if ( DEBUG ) { console.log('thisSelectId='+thisSelectId); } var thisSelect = document.getElementById(thisSelectId);//CollegeCampus[c].campusId); let selectedCampusId = parseInt(thisSelect.options[thisSelect.selectedIndex].value); if ( DEBUG ) { console.log('selectedCampusId='+selectedCampusId); } if ( !isNaN(selectedCampusId) ) { campusIdsSelected.push(selectedCampusId); } // Add the campusId to the array. } // Loop thru campuses. if ( campusIndex >= 0 ) { RoomLine_AddButton_Hide(scmId, campusIndex, 'SetupNextCampusSelectOptions:3236'); // Hide the current + (Add another room) button. //RoomLine_RemoveButton_Hide(scmId, campusIndex); } if ( DEBUG ) { console.log('campusIdsSelected='+campusIdsSelected); } let campusIndex_Next = campusIndex + 1; if ( DEBUG ) { console.log('typeof CollegeCampus['+campusIndex_Next+']='+(typeof CollegeCampus[campusIndex_Next])); } if ( typeof CollegeCampus[campusIndex_Next] !== 'undefined' ) { // Is there another campus after the current one. // Yes, Setup campus select options. let nextCampusSelect = document.getElementById('selCampus_'+scmId+'_'+campusIndex_Next); nextCampusSelect.options.length = 0; let opt = document.createElement('option'); opt.value = ''; opt.innerHTML = ''; nextCampusSelect.appendChild(opt); for ( var i=0; i<CollegeCampus.length; i++ ) { if ( campusIdsSelected.indexOf(CollegeCampus[i].campusId) === -1 ) { if ( DEBUG ) { console.log('Adding option for '+CollegeCampus[i].Name+'.'); } opt = document.createElement('option'); opt.value = CollegeCampus[i].campusId; opt.innerHTML = CollegeCampus[i].Name; nextCampusSelect.appendChild(opt); } } RoomLine_BuildingSelect_Hide(scmId, campusIndex_Next); RoomLine_RoomSelect_Hide(scmId, campusIndex_Next); // Hide the room select (label). } // Is there another Campus after the current one. if ( DEBUG ) { console.log(`${PC}END ${PC}SetupNextCampusSelectOptions`,SE,ST); console.groupEnd(); } } // END SetupNextCampusSelectOptions. // RoomLine_BuildingSelect_Hide(scmId, campusIndex) // Hide the Rm select (via label) and clear the options. function RoomLine_BuildingSelect_Hide(scmId, campusIndex) { // Hide the building select. let labBuildingId = `labBuilding_${scmId}_${campusIndex}`; let eBuildingLabel = document.getElementById(labBuildingId); if ( !eBuildingLabel.classList.contains('hidden') ) { eBuildingLabel.classList.add("hidden"); } // Clear the building select options. let eBuildingId = `selBuilding_${scmId}_${campusIndex}`; let eBuilding = document.getElementById(eBuildingId); eBuilding.options.length = 0; } // END RoomLine_BuildingSelect_Hide. // RoomLine_RoomSelect_Hide(scmId, campusIndex) // Hide the Rm select (via label) and clear the options. function RoomLine_RoomSelect_Hide(scmId, campusIndex) { // Hide the room select. let labRoomId = `labRoom_${scmId}_${campusIndex}`; let eRoomLabel = document.getElementById(labRoomId); if ( !eRoomLabel.classList.contains('hidden') ) { eRoomLabel.classList.add("hidden"); } // Clear the room select options. let eRoomId = `selRoom_${scmId}_${campusIndex}`; let eRoom = document.getElementById(eRoomId); eRoom.options.length = 0; } // END RoomLine_RoomSelect_Hide. // RoomLine_RoomSelect_Show(scmId, campusIndex) // Show the Rm select (via label). function RoomLine_RoomSelect_Show(scmId, campusIndex) { let labRoomId = `labRoom_${scmId}_${campusIndex}`; let eRoomLabel = document.getElementById(labRoomId); eRoomLabel.classList.remove("hidden"); // Show the RM select line. } // END RoomLine_RoomSelect_Show. // SetupRoomSelectOptions() // Set the options for the room select. function SetupRoomSelectOptions(e) { var DEBUG = false; if ( DEBUG ) { console.group(`${PC}SetupRoomSelectOptions[e.id=${e.id}]`,CG); }//Collapsed // Get the buildingId. buildingId = parseInt(e.value); if ( DEBUG ) { console.log('buildingId='+buildingId); } // Get the room order. var eIdParts = e.id.split('_'); var scmId = eIdParts[1]; var campusIndex = parseInt(eIdParts[2]); // Get the campusIndex. if ( DEBUG ) { console.log('scmId='+scmId+' campusIndex='+campusIndex); } let eRoom = document.getElementById('selRoom_'+scmId+'_'+campusIndex); // Get room select. eRoom.options.length = 0; // Remove current options. // Add the blank option. var opt = document.createElement('option'); opt.value = ''; opt.innerHTML = ''; eRoom.appendChild(opt); // Add other room options. for ( let i=0; i<CollegeRoom.length; i++ ) { if ( CollegeRoom[i].buildingId === buildingId ) { opt = document.createElement('option'); opt.value = CollegeRoom[i].roomId; //if ( roomId === CollegeRoom[i].roomId ) { opt.selected = true; } opt.innerHTML = CollegeRoom[i].Number; eRoom.appendChild(opt); } } RoomLine_RoomSelect_Show(scmId, campusIndex); // Show the room select (label). /** / let eRoomLabelId = 'labRoom_'+scmId+'_'+campusIndex; let eRoomLabel = document.getElementById(eRoomLabelId); if ( !isNaN(buildingId) ) { if ( DEBUG ) { console.log('Show '+eRoomLabelId); } eRoomLabel.classList.remove("hidden"); } else { if ( DEBUG ) { console.log('Hide '+eRoomLabelId); } eRoomLabel.classList.add("hidden"); } /**/ // Hide + and - buttons. RoomLine_AddButton_Hide(scmId, campusIndex, 'SetupRoomSelectOptions:3346'); //RoomLine_RemoveButton_Hide(scmId, campusIndex); if ( DEBUG ) { console.log(`${PC}END ${PC}SetupRoomSelectOptions`,SE,ST); console.groupEnd(); } } // END SetupRoomSelectOptions. // ShowInstructorButton(e) // Show + add instructor button. function ShowInstructorButton(e) { //console.warn('ShowInstructorButton[instructorId='+instructorId+']'); var eIdParts = e.id.split('_'); var scmId = eIdParts[1]; //var campusIndex = parseInt(eIdParts[2]); var instructorIndex = parseInt(eIdParts[2]); console.log('scmId='+scmId+' instructorIndex='+instructorIndex); if ( document.getElementById('btnShowInstructor_'+scmId+'_'+instructorIndex) ) { document.getElementById('btnShowInstructor_'+scmId+'_'+instructorIndex).style.display = 'inline'; } } // END ShowInstructorButton. // ShowInstructorNext(e) // Show next select element for instructor. function ShowInstructorNext(e) { console.log('BEGIN ShowInstructorNext[e.id='+e.id+']'); var eIdParts = e.id.split('_'); var scmId = eIdParts[1]; //var campusIndex = parseInt(eIdParts[2]); //var instructorIndex = parseInt(eIdParts[3]); var instructorIndex = parseInt(eIdParts[2]); var instructorIndexNext = instructorIndex + 1; console.log('scmId='+scmId+' instructorIndex='+instructorIndex+' instructorIndexNext='+instructorIndexNext); var btnShowInstructorId = 'btnShowInstructor_'+scmId+'_'+instructorIndex; console.log('btnShowInstructorId='+btnShowInstructorId); document.getElementById(btnShowInstructorId).style.display = 'none'; // Hide the current + button. var divInstructorId = 'divInstructor_'+scmId+'_'+instructorIndexNext; console.log('divInstructorId='+divInstructorId); document.getElementById(divInstructorId).className = ''; // Remove hidden class. } // END ShowInstructorNext. // Room_RoomLine_Hide(scmId, campusIndex) // Hide the RoomLine (via div id). // If all RoomLines are now hidden, check the Off campus checkbox. function Room_RoomLine_Hide(scmId, campusIndex) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}Room_RoomLine_Hide[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed let allRoomLinesAreHidden = true; for ( let loopIndex = 0; loopIndex < CollegeCampus.length; loopIndex++) { // Loop thru RoomLines in reverse. // Check if this RoomLine is shown. let divRoomId = 'divRoom_'+scmId+'_' + loopIndex; if ( DEBUG ) { console.log ('divRoomId='+divRoomId); } let eDivRoom = document.getElementById(divRoomId); if ( !eDivRoom.classList.contains('hidden') ) { // Is this RoomLine shown? if ( DEBUG ) { console.log(`${PC}${divRoomId} is shown`,CT); } if ( loopIndex === campusIndex) { if ( !eDivRoom.classList.contains('hidden') ) { eDivRoom.classList.add("hidden"); if ( DEBUG ) { console.log(`${PC}${divRoomId} is now hidden`,CF); } } } else { allRoomLinesAreHidden = false; } } else { // Is this RoomLine shown? if ( DEBUG ) { console.log(`${PC}${divRoomId} is hidden`,CF); } } // Is this RoomLine shown? } // Loop thru RoomLines in reverse. if ( DEBUG ) { console.log(`${PC}allRoomLinesAreHidden=${allRoomLinesAreHidden}`,CI); } if ( allRoomLinesAreHidden ) { // Check the Off campus checkbox. let chkClassIsOffCampusId = `chkClassIsOffCampus_${scmId}`; let eClassIsOffCampus = document.getElementById(chkClassIsOffCampusId); eClassIsOffCampus.checked = true; ClassmeetingOffCampus(eClassIsOffCampus) } if ( DEBUG ) { console.log(`${PC}END ${PC}Room_RoomLine_Hide`,SE,ST); console.groupEnd(); } } // END Room_RoomLine_Hide. chkClassIsOffCampus _add0 // Room_RoomLine_Show(scmId, campusIndex) // Show the room line (via div id) and hide the previous + (add another room) button. function Room_RoomLine_Show(scmId, campusIndex) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.warn('Room_RoomLine_Show[scmId='+scmId+' campusIndex='+campusIndex+']'); } // Show the classroom line. var divRoomId = 'divRoom_'+scmId+'_'+campusIndex; if ( DEBUG ) { console.log ('divRoomId='+divRoomId); } let eDivRoom = document.getElementById(divRoomId); eDivRoom.classList.remove("hidden"); // Show the classroom line. let campusIndex_Previous = campusIndex - 1; if ( DEBUG ) { console.log(`${PC}campusIndex_Previous=${campusIndex_Previous}`,CD); } if ( campusIndex_Previous >= 0 ) { RoomLine_AddButton_Hide(scmId, campusIndex_Previous, 'Room_RoomLine_Show:3432') // Hide the previous + (Add another room) button. } SetupNextCampusSelectOptions(scmId, campusIndex_Previous); // Uncheck the Off campus checkbox. let chkClassIsOffCampusId = `chkClassIsOffCampus_${scmId}`; let eClassIsOffCampus = document.getElementById(chkClassIsOffCampusId); if ( eClassIsOffCampus.checked ) { eClassIsOffCampus.checked = false; ClassmeetingOffCampus(eClassIsOffCampus); } else { //Room_RoomLine_Show(scmId, 0); // Show campusIndex 0 RoomLine. } } // END Room_RoomLine_Show. // RoomLine_RemoveAddButtons_ShowHide(scmId, campusIndex) // Show or hide the - (Remove room) and + (add another room) buttons. function RoomLine_RemoveAddButtons_ShowHide(scmId, campusIndex) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}RoomLine_RemoveAddButtons_ShowHide[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed let selRoomId = `selRoom_${scmId}_${campusIndex}`; let eRoomSelect = document.getElementById(selRoomId); if ( DEBUG ) { console.log(`${PC}${selRoomId}.value=${eRoomSelect.value}`,CI); } if ( eRoomSelect.value !== '' ) { RoomLine_RemoveButton_Show(scmId, campusIndex); RoomLine_AddButton_Show(scmId); } else { //RoomLine_RemoveButton_Hide(scmId, campusIndex); RoomLine_AddButton_Hide(scmId, campusIndex, 'RoomLine_RemoveAddButtons_ShowHide:3459'); } if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_RemoveAddButtons_ShowHide`,SE,ST); console.groupEnd(); } } // END RoomLine_RemoveAddButtons_ShowHide. // RoomLine_AddButton_Hide(scmId, campusIndex) // Hide + (Add another room) button. function RoomLine_AddButton_Hide(scmId, campusIndex, by='') { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}RoomLine_AddButton_Hide[scmId=${scmId} campusIndex=${campusIndex}] by=${by}`,CG); }//Collapsed // Hide the + button. let ShowRoomLine_btnId = `ShowRoomLineBtn_${scmId}_${campusIndex}`; let eShowButton = document.getElementById(ShowRoomLine_btnId); if ( eShowButton && !eShowButton.classList.contains('hidden') ) { eShowButton.classList.add("hidden"); } if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_AddButton_Hide`,SE,ST); console.groupEnd(); } } // END RoomLine_AddButton_Hide. // RoomLine_AddButton_Show(scmId) // Show + (add another room) button if the last shown RoomLine has a room selected. function RoomLine_AddButton_Show(scmId) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}RoomLine_AddButton_Show[scmId=${scmId}]`,CG); }//Collapsed for ( let campusIndex = CollegeCampus.length - 1; campusIndex >= 0; campusIndex-- ) { // Loop thru RoomLines in reverse. // Check if this RoomLine is shown. let divRoomId = 'divRoom_'+scmId+'_'+campusIndex; if ( DEBUG ) { console.log ('divRoomId='+divRoomId); } let eDivRoom = document.getElementById(divRoomId); if ( !eDivRoom.classList.contains('hidden') ) { // Is this RoomLine shown? // Check room value. let selRoomId = `selRoom_${scmId}_${campusIndex}`; let eRoomSelect = document.getElementById(selRoomId); if ( DEBUG ) { console.log(`${PC}campusIndex=${campusIndex} eRoomSelect.value=${eRoomSelect.value}`,CI); } if ( eRoomSelect.value !== '' ) { // Is there a room value? let ShowRoomLine_btnId = `ShowRoomLineBtn_${scmId}_${campusIndex}`; if ( DEBUG ) { console.log('ShowRoomLine_btnId='+ShowRoomLine_btnId); } let eRoomBtn = document.getElementById(ShowRoomLine_btnId); if ( eRoomBtn ) { eRoomBtn.classList.remove("hidden"); } break; } // Is there a room value? } // Is this RoomLine shown? } // Loop thru RoomLines in reverse. if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_AddButton_Show`,SE,ST); console.groupEnd(); } } // END RoomLine_AddButton_Show. // RoomLine_RemoveButton_Hide(scmId, campusIndex) // Hide - (Remove room) button. function RoomLine_RemoveButton_Hide(scmId, campusIndex) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}RoomLine_RemoveButton_Hide[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed /** / // Hide the - button. let btnRemoveId = `btnRemoveRoom_${scmId}_${campusIndex}`; let eRemoveButton = document.getElementById(btnRemoveId); if ( !eRemoveButton.classList.contains('hidden') ) { eRemoveButton.classList.add("hidden"); } /**/ if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_RemoveButton_Hide`,SE,ST); console.groupEnd(); } } // END RoomLine_RemoveButton_Hide. // RoomLine_RemoveButton_Show(scmId, campusIndex) // Show the - (Remove room) button. function RoomLine_RemoveButton_Show(scmId, campusIndex) { let btnRemoveRoomId = 'btnRemoveRoom_'+scmId+'_'+campusIndex; let eRemoveRoomBtn = document.getElementById(btnRemoveRoomId); eRemoveRoomBtn.classList.remove("hidden"); } // END RoomLine_RemoveButton_Show. // SidenavToggle(e) // Show / hide side nav sub menu. function SidenavToggle(e) { ttHide(); var DEBUG = false; if ( DEBUG ) { console.group(PC+'SidenavToggle[e.id='+e.id+']',CG); } var eIdParts = e.id.split('_'); var sidenavName = eIdParts[1]; // Get sidenav menu name. var subs = document.getElementsByClassName(sidenavName+' sub'); if ( DEBUG ) { console.log(PC+'eIdParts='+eIdParts,CL); } if ( DEBUG ) { console.log(PC+'sidenavName='+sidenavName+' subs.length='+subs.length,CI); } // Get the span in the link. var spans = e.getElementsByTagName('span'); //if ( DEBUG ) { console.log(PC+'spans.length='+spans.length,CL); } var menu_innerHTML = spans[0].innerHTML; if ( DEBUG ) { console.log(PC+sidenavName+' a#'+e.id+' span.innerHTML='+menu_innerHTML,CI); } if ( menu_innerHTML === '▼' ) //if ( ShowSub ) { // Open sub-menu. if ( DEBUG ) { console.log(PC+'Open '+sidenavName+' sub-menu',CD); } document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Close '+sidenavName.toLowerCase()+' sub menu.');}; spans[0].innerHTML = '▲'; //document.getElementById('spn_'+sidenavName).innerHTML = '▲'; ttShow('Close '+sidenavName+' task menu.'); } else { // Close sub-menu. if ( DEBUG ) { console.log(PC+'Close '+sidenavName+' sub-menu',CD); } document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Open '+sidenavName.toLowerCase()+' sub menu.');}; spans[0].innerHTML = '▼'; //document.getElementById('spn_'+sidenavName).innerHTML = '▼'; ttShow('Open '+sidenavName+' task menu.'); } // Show/Hide sub-menu items. //var ShowSub = false; // unused 2022/04/06 jfm for ( var i=0; i<subs.length; i++ ) { //if ( DEBUG ) { console.log(PC+TB+'id='+subs[i].id+' style.display='+subs[i].style.display,CL); } switch (menu_innerHTML) { case '▲': if ( DEBUG ) { console.log(PC+TB+'Hide '+subs[i].id,CL); } subs[i].style.display = 'none'; break; case '▼': if ( DEBUG ) { console.log(PC+TB+'Show '+subs[i].id,CL); } subs[i].style.display = 'inline-block'; break; } /** / if ( subs[i].style.display === 'inline-block' ) { subs[i].style.display = 'none'; } else { ShowSub = true; subs[i].style.display = 'inline-block'; } /**/ } /** / if ( menu_innerHTML === '▼' ) //if ( ShowSub ) { // Open sub-menu. if ( DEBUG ) { console.log(PC+'Open '+sidenavName+' sub-menu',CD); } document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Close '+sidenavName.toLowerCase()+' sub menu.');}; spans[0].innerHTML = '▲'; //document.getElementById('spn_'+sidenavName).innerHTML = '▲'; ttShow('Close '+sidenavName+' task menu.'); } else { // Close sub-menu. if ( DEBUG ) { console.log(PC+'Close '+sidenavName+' sub-menu',CD); } document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Open '+sidenavName.toLowerCase()+' sub menu.');}; spans[0].innerHTML = '▼'; //document.getElementById('spn_'+sidenavName).innerHTML = '▼'; ttShow('Open '+sidenavName+' task menu.'); } /**/ if ( DEBUG ) { console.groupEnd(); } return false; } // END SidenavToggle. function SaveAutoscrollPosition() { // by Garrett Wiley. document.cookie = "sp=" + document.getElementById("schedulecontainer").getBoundingClientRect().top; } // END SaveAutoscrollPosition by Garrett Wiley. function AutoscrollPage(todelete) { // by Garrett Wiley. var cook = document.cookie.split(" "); var scrollPos = 0; var scheduleVar = document.getElementById("schedulecontainer"); //if(bcrt == 0)bcrt = scheduleVar.getBoundingClientRect().top; if(bcrt === 0){bcrt = scheduleVar.getBoundingClientRect().top;} for(var i = 0; i < cook.length; i++) { if(cook[i].substr(0, 3) === "sp=") { scrollPos = bcrt - parseInt(cook[i].replace(";", "").substr(3, cook[i].length-3)); } } if(todelete === 1) { document.cookie = "sp=; expires=Thu, 01 Jan 1970 00:00:00 UTC"; } window.scrollTo(0, scrollPos); } // END AutoscrollPage by Garrett Wiley. document.addEventListener('DOMContentLoaded', function() { // addEventListener for AutoscrollPage by Garrett Wiley. See https://www.rgraph.net/canvas/docs/the-domcontentloaded-event.html AutoscrollPage(1); }, false); // ScheduleClass_RemoveClassVerify(thisTask) // Verify removal of schedule class. function ScheduleClass_RemoveClassVerify(thisTask) { var DEBUG_ScheduleClass_RemoveClassVerify = true; if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('BEGIN ScheduleClass_RemoveClassVerify[thisTask='+thisTask+']'); } if ( typeof thisTask === 'undefined' ) { if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('Display div_RemoveClassVerify'); } document.getElementById('div_RemoveClassVerify').style.display = 'block'; } else if ( thisTask ) { if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('Yes clicked.'); } if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.warn('ScheduleClass_RemoveClassVerify[scheduleId='+ScheduleCurrent.scheduleId+', departmentId='+ScheduleCurrent.departmentId+', scheduleclassId='+currentOpenScheduleClassId+'];'); } // Remove the calendar_class divs from the DOM. if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log(SCMnow[currentOpenScheduleClassId]); } for (let i = 0; i < SCMnow[currentOpenScheduleClassId].length; i++) { // Loop thru class meetings. for (let x = 0; x < SCMnow[currentOpenScheduleClassId][i].days.length; x++) { // Loop through class meeting days. var calendar_class_Id = 'calendar_class_'+currentOpenScheduleClassId+'_'+SCMnow[currentOpenScheduleClassId][i].days[x]+SCMnow[currentOpenScheduleClassId][i].tdMinute; if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log(calendar_class_Id); } document.getElementById(calendar_class_Id).remove(); } // Loop through class meeting days. } // Loop thru class meetings. // Remove the ClassMeetings from local. SCMnow[currentOpenScheduleClassId] = []; // Remove the ClassMeetings from the database. URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassUpdate.php?'; URI += 'task=RemoveClass'; URI += '&scId='+currentOpenScheduleClassId; UpdateInclude(URI, false); CloseDialog(); DisplaySchedule('ScheduleClass_RemoveClassVerify 3699'); } else { if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('No clicked.'); } document.getElementById('div_RemoveClassVerify').style.display = 'none'; } } // END ScheduleClass_RemoveClassVerify. // For use by Jonathan Plotz // ccs = Credential color set. var ccs = []; ccs[0] = { index:1, color:['Tomato', 'Electric crimson'] }; ccs[1] = { index:1, color:['Orange', 'Fulvous'] }; ccs[2] = { index:1, color:['Yellow', 'Citrine'] }; ccs[3] = { index:1, color:['Lime', 'Kelly green'] }; ccs[4] = { index:1, color:['Celeste', 'Cyan'] }; ccs[5] = { index:1, color:['Brilliant lavender', 'Heliotrope'] }; // DisplaySchedule_Highlight() // Highlights the schedule. function DisplaySchedule_Highlight() { var DEBUG = false; if ( DEBUG ) { console.warn('DisplaySchedule_Highlight[] ScheduleHighlightView='+ScheduleHighlightView+''); } // Hide all highlight type color keys. divHide('divHighlightNone'); divHide('divHighlightConflict'); divHide('divHighlightCredential'); divHide('divHighlightInstructor'); divHide('divHighlightRoom'); // Show the current color key. switch ( ScheduleHighlightView ) { case 'None': if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); } DisplaySchedule_Highlight_None(); document.getElementById('divHighlightNone').style.display = 'block'; break; case 'Conflict': if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Conflicts[]',CC); } DisplaySchedule_Highlight_Conflicts(); document.getElementById('divHighlightConflict').style.display = 'block'; break; case 'Credential': if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Credentials[]',CC); } DisplaySchedule_Highlight_Credentials(); document.getElementById('divHighlightCredential').style.display = 'block'; break; case 'Instructor': if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Instructors[]',CC); } DisplaySchedule_Highlight_Instructors(); document.getElementById('divHighlightInstructor').style.display = 'block'; break; case 'Room': if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Rooms[]',CC); } DisplaySchedule_Highlight_Rooms(); document.getElementById('divHighlightRoom').style.display = 'block'; break; } } // END DisplaySchedule_Highlight. // DisplaySchedule_Highlight_None() // Check schedule for class 1) Degree/year, 2) room, or 3) Instructor conflicts and change meeting styles to show them. function DisplaySchedule_Highlight_None() { var DEBUG = false; if ( DEBUG ) { console.groupCollapsed(`${PC}DisplaySchedule_HighlightNone[]`,CG); } /** / var eCalendarClassDiv, calendar_class_div_base, calendar_class_div_id, dayIndex, meetingIndex, scId; /**/ let CalendarClassDivs = document.querySelectorAll('div[id^="calendar_class_"]'); //let CalendarClassDivsCount = CalendarClassDivs.length; // unused 2022/04/06 jfm CalendarClassDivs.forEach(function(e, index) { let Course, Section; if ( DEBUG ) { // Get the course numbers. //console.log(`${PC}${CalendarClassDivs[index].id}`,CL); let idParts = CalendarClassDivs[index].id.split('_'); let scId = idParts[2]; //console.log(`scmId = ${scmId}`); //let scId = ClassMeeting_ScheduleClass[scmId]; //console.log(`scId = ${scId}`); Course = ScheduleClass[scId].Course; Section = ScheduleClass[scId].Section; //console.log(JSON.stringify(Course)); } if ( DEBUG ) { console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CL); } // Remove highlights. CalendarClassDivs[index].style.border = null; if ( e.className.indexOf('calendar_class') !== -1 ) { e.className = 'calendar_class'; } else if ( e.className.indexOf('calendar_arranged') !== -1 ) { e.className = 'calendar_arranged'; } else { e.className = 'calendar_hidden'; } if ( DEBUG ) { if ( e.className.indexOf('calendar_class') !== -1 ) { console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CD); } else if ( e.className.indexOf('calendar_arranged') !== -1 ) { console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CI); } else { console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CW); } } }); /** / for ( scId in ScheduleClass ) {if(ScheduleClass.hasOwnProperty(scId)) { // Loop thru classes. calendar_class_div_base = 'calendar_class_'+scId+'_'; const MeetingCount = SCMnow[scId].length; for ( meetingIndex=0; meetingIndex<MeetingCount; meetingIndex++ ) { // Loop thru 1st class meetings. // instructor and room code see below. let DaysCount = SCMnow[scId][meetingIndex].days.length; for ( dayIndex=0; dayIndex<DaysCount; dayIndex++ ) { // Loop thru days. calendar_class_div_id = calendar_class_div_base + SCMnow[scId][meetingIndex].days[dayIndex] + ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime); //console.log(PC+'calendar_class_div_id='+calendar_class_div_id,CI); eCalendarClassDiv = document.getElementById(calendar_class_div_id); // Do what you need here. // See DisplaySchedule_Highlight_Conflicts() in scheduler.js to see how to find instructors and rooms. Credential info is not available yet! eCalendarClassDiv.className="calendar_class"; eCalendarClassDiv.style.border = ''; } // Loop thru days. } // Loop thru 1st class meetings. }} // Loop thru classes. /**/ if ( DEBUG ) { console.log(`${PC}END ${PC}DisplaySchedule_HighlightNone`,SE,CG); console.groupEnd(); } } // END DisplaySchedule_Highlight_None. // DisplaySchedule_Highlight_Rooms() // Highlight the different rooms. function DisplaySchedule_Highlight_Rooms() { var DEBUG = false; if ( DEBUG ) { console.warn('DisplaySchedule_Highlight_Rooms[]'); } if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); } DisplaySchedule_Highlight_None(); } // END DisplaySchedule_Highlight_Rooms. // HasAttributeWithValue( theObject, theAttribute, theValue ) // Search in an array of objects for an attribute with the value you are searching for. // Returns an array of objects that have an attribute with a value that matches. // theObject = The array to search. // theAttribute = The attribute to search. Must be set before function call. // theValue = the attribute value you are searching for. function HasAttributeWithValue(theArray,theAttribute,theValue) { return theArray.filter(function(el) { if ( typeof el[theAttribute] !== 'object' ) { return el[theAttribute] === theValue; } else { return el[theAttribute].indexOf(theValue) !== -1 ; } }); } // END HasAttributeWithValue. // MoveCLass_Cancel() // Cancel the class move and put the calendar_class divs back to their original locations. function MoveCLass_Cancel(scId) { var DEBUG = false; if ( DEBUG ) { console.group(PC+`MoveCLass_Cancel[scId=${scId}]`,CG); } CloseDialog(); // BEGIN Restore calendar_class div ids to original. // Collect current calendar_class divs for this scId. let calendar_class_divs = document.querySelectorAll('*[id^="calendar_class_'+scId+'"]'); if ( DEBUG ) { console.log(`${PC}calendar_class_divs=${D_formatJSONstring(calendar_class_divs)}`,CL); } if ( DEBUG ) { let text = 'current ids ='; calendar_class_divs.forEach(e => { text += ` ${e.id}`; }); console.log(`${PC}${text}`,CI); } if ( DEBUG ) { console.log(`${PC}SCMnow[${scId}]=${D_formatJSONstring(SCMnow[scId])}`,CI); } if ( DEBUG ) { console.log(`${PC}SCMold[${scId}]=${D_formatJSONstring(SCMold[scId])}`,CI); } if ( DEBUG ) { console.log(PC+'ClassMeetings = '+D_formatJSONstring(SCMnow[scId]),CD); } // Restore original calendar_class div Ids. if ( DEBUG ) { console.log(PB+'Reset div Ids',SB,ST); } for ( let IndexClassMeeting in SCMnow[scId] ){if(SCMnow[scId].hasOwnProperty(IndexClassMeeting)){ // Loop thru class meetings. if ( DEBUG ) { console.log(PC+'IndexClassMeeting = '+IndexClassMeeting,CL); } //if ( DEBUG ) { console.log(PC+'Current_mTime = '+Current_mTime,CL); } if ( DEBUG ) { console.log(`${PC}SCMnow[${scId}][${IndexClassMeeting}].days.length=${SCMnow[scId][IndexClassMeeting].days.length}`,CL); } if ( SCMnow[scId][IndexClassMeeting].days.length > 0 ) { let Original_mTime = ConvertTimeToMinutes(SCMnow[scId][IndexClassMeeting].bTime) - SCMnow[scId][IndexClassMeeting].mbTimeDiff; let Current_mTime = ConvertTimeToMinutes(SCMnow[scId][IndexClassMeeting].bTime); for ( let IndexDay in SCMnow[scId][IndexClassMeeting].days ){if(SCMnow[scId][IndexClassMeeting].days.hasOwnProperty(IndexDay)){ // Loop thru the days. if ( DEBUG ) { console.log(PC+'IndexDay = '+IndexDay,CL); } let Original_Day = Weekdays[WeekdayD[SCMnow[scId][IndexClassMeeting].days[IndexDay]] - SCMnow[scId][IndexClassMeeting].dayDiff].weekdayD; let Current_Day = SCMnow[scId][IndexClassMeeting].days[IndexDay]; //if ( DEBUG ) { console.log(PC+'Current_Day = '+Current_Day,CL); } let originalId = 'calendar_class_' + scId + '_' + Original_Day + Original_mTime; let currentlId = 'calendar_class_' + scId + '_' + Current_Day + Current_mTime; //let currentlId = calendar_class_divs[IndexDay]; if ( DEBUG ) { console.log(PC+`original id = ${originalId}`,CI); } if ( DEBUG ) { console.log(PC+` current id = ${currentlId}`,CI); } document.getElementById(currentlId).id = originalId; }} } }} // Loop thru class meetings. if ( DEBUG ) { console.log(PE+'Reset div Ids',SE,ST); } if ( DEBUG ) { console.log(PC+`SCMnow[${scId}][0].bTime=${SCMnow[scId][0].bTime} SCMold[${scId}][0].bTime=${SCMold[scId][0].bTime}`,CL); } // Reset SCMnow. SCMnow[scId] = JSON.parse(JSON.stringify(SCMold[scId])); // Restore original. EventListeners_Add(); DisplaySchedule('MoveCLass_Cancel 152'); if ( DEBUG ) { console.groupEnd(); } } // END MoveCLass_Cancel. /** / instructors = SCMnow[scId][meetingIndex].instructors; if ( instructors.length ) { // Is there an instructor? instructorConflict = false; for ( instructorIndex=0; instructorIndex<instructors.length; instructorIndex++ ) { // Loop thru 1st instructors. instructor = instructors[instructorIndex]; // Now you have the instructor name. } // Loop thru 1st instructors. } // Is there an instructor? rooms = SCMnow[scId][meetingIndex].rooms; if ( rooms.length ) { // Is there an room? roomConflict = false; for ( roomIndex=0; roomIndex<rooms.length; roomIndex++ ) { // Loop thru 1st rooms. room = rooms[roomIndex]; // Now you have the room number. } // Loop thru 1st rooms. } // Is there an room? /**/ // For use by Tyson Tvinnereim //alert("schedule6.js has been successfully included in scheduleclassmeetingform!"); // Search_HighlightMeetings() // Hightlight meetings found by search. function Search_HighlightMeetings() { var DEBUG = DEBUG_OFF; if ( DEBUG ) { console.groupCollapsed(`${PC}Search_HighlightMeetings[]`,CG); }// if ( DEBUG ) { console.log(`${PC}Search_FindMeetings.idsToHighlight.length=${Search_FindMeetings.idsToHighlight.length}`,CI); } if ( Search_FindMeetings.idsToHighlight.length ) { // Are there idsToHighlight? for ( let i=0; i<Search_FindMeetings.idsToHighlight.length; i++ ) { // Loop thru idsToHighlight. let thisId = Search_FindMeetings.idsToHighlight[i]; let eToHighlight = document.getElementById(thisId); eToHighlight.style.boxShadow = '0 0 10px 8px green'; eToHighlight.style.zIndex = 20; eToHighlight.style.marginRight = '15px'; eToHighlight.style.outline = 'green solid 4px'; } // Loop thru idsToHighlight. } // Are there idsToHighlight? if ( DEBUG ) { console.groupEnd(); } } // END Search_HighlightMeetings. // Search_FindMeetings(search) // Find and highlight class meetings that match search. function Search_FindMeetings(search) { var DEBUG = false; if ( DEBUG ) { console.group(`${PC}Search_FindMeetings[search=${search}]`,CG); }//Collapsed let i, j, k; let newId; let courseFiler = []; let scId; for( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses. courseFiler.push(ScheduleClass[scId].courseId); }} // Loop thru ScheduleClasses. Search_FindMeetings.idsToHighlight = []; if ( DEBUG ) { console.log(`${PC}Searching for ${search}`,CI); } // BEGIN Search thru Courses. for ( var courseId in Course ){if(Course.hasOwnProperty(courseId)){ // Loop thru courses. //if ( DEBUG ) { console.log(`${PC} Course[${cId}]=${JSON.stringify( Course[courseId])}`,CL); } if ( courseFiler.indexOf(courseId) !== -1 ) { // Is this course in the filter? // Search the course dept number and title. let course = Course[courseId]; let courseInfo = course.Dept + course.Number + ' ' + course.Title; if ( DEBUG ) { console.log(`${PC}courseInfo=${courseInfo} ( courseInfo.indexOf(search) !== -1 )=${( courseInfo.indexOf(search) !== -1 )}`,CL); } let classMeetingPushed = false; if ( courseInfo.indexOf(search) !== -1 ) { // Is the courseInfo in the search? for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses. if ( DEBUG ) { console.log(`${PC}( ScheduleClass[scId].courseId === courseId =${( ScheduleClass[scId].courseId === courseId )}`,CL); } if ( ScheduleClass[scId].courseId === courseId ) { // Do the courseIds match? for ( i=0; i<SCMnow[scId].length; i++ ) { // Loop thru ClassMeetings. let classMeeting = SCMnow[scId][i]; let mTime = ConvertTimeToMinutes(classMeeting.bTime); if ( isNaN(mTime) ) { mTime = 0; } if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)} if ( classMeeting.days.length > 0 ) { // Does this classMeeting have days? // Yes, use the days to build the ids. for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days. let day = classMeeting.days[j]; newId = `calendar_class_${scId}_${day}${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); } Search_FindMeetings.idsToHighlight.push(newId); classMeetingPushed = true; } // Loop thru the days. } else { // Does this classMeeting have days? // No, build no-day id. newId = `calendar_class_${scId}_${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId}`,CL); } Search_FindMeetings.idsToHighlight.push(newId); classMeetingPushed = true; } // Does this classMeeting have days? } // Loop thru ClassMeetings. } // Do the courseIds match? }} // Loop thru ScheduleClasses. } // Is the courseInfo in the search? if ( !classMeetingPushed ) { //Was the class meeting NOT put in idsToHighlight? // Search rooms. let roomSearch = search.replace('Room ',''); if ( DEBUG ) { console.log(`${PC}roomSearch=[${roomSearch}]`,CD); } for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass. //if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id} ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); } if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match? for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings let classMeeting = SCMnow[scId][j]; if ( DEBUG ) { console.log(`${PC}classMeeting.rooms.length=${classMeeting.rooms.length}`,CL); } if ( classMeeting.rooms.length ) { // Are there rooms. for ( k=0; k<classMeeting.rooms.length; k++ ) { // Loop thru rooms. let room = classMeeting.rooms[k]; if ( DEBUG ) { console.log(`${PC}room=[${room}] room.indexOf(${roomSearch}) !== -1 == ${(room.indexOf(roomSearch) !== -1)}`,CI); } if ( room.indexOf(roomSearch) !== -1 ) { // Is the room in the search? if ( Search_FindMeetings.idsToHighlight.indexOf(room) == -1 ) { // Has the room not been added to idsToHighlight? let mTime = ConvertTimeToMinutes(classMeeting.bTime); if ( isNaN(mTime) ) { mTime = 0; } if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)} if ( classMeeting.days.length > 0 ) { // Does this classMeeting have days? // Yes, use the days to build the ids. for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days. let day = classMeeting.days[j]; let newId = `calendar_class_${scId}_${day}${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); } Search_FindMeetings.idsToHighlight.push(newId); classMeetingPushed = true; } // Loop thru the days. } else { // Does this classMeeting have days? // No, build no-day id. newId = `calendar_class_${scId}_${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId}`,CL); } Search_FindMeetings.idsToHighlight.push(newId); classMeetingPushed = true; } // Does this classMeeting have days? } // Has the room not been added to idsToHighlight? } // Is the room in the search? } // Loop thru rooms. } // Are there rooms. } // Loop thru ClassMeetings } // Do the courseIds match? }} // Loop thru ScheduleClass. if ( !classMeetingPushed ) { //Was the class meeting NOT put in idsToHighlight? // Search instructors. for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass. //if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id} ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); } if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match? for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings let classMeeting = SCMnow[scId][j]; if ( DEBUG ) { console.log(`${PC}classMeeting.instructors.length=${classMeeting.instructors.length}`,CL); } if ( classMeeting.instructors.length ) { // Are there instructors. for ( k=0; k<classMeeting.instructors.length; k++ ) { // Loop thru instructors. let instructorName = InstructorLookup[classMeeting.instructors[k]].Name; if ( instructorName.indexOf(search) !== -1 ) { // Did we find and instructor name? if ( Search_FindMeetings.idsToHighlight.indexOf(instructorName) == -1 ) { // Has the instructorName not been added to idsToHighlight? let mTime = ConvertTimeToMinutes(classMeeting.bTime); if ( isNaN(mTime) ) { mTime = 0; } if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)} if ( classMeeting.days.length > 0 ) { // Does this classMeeting have days? // Yes, use the days to build the ids. for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days. let day = classMeeting.days[j]; let newId = `calendar_class_${scId}_${day}${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); } Search_FindMeetings.idsToHighlight.push(newId); classMeetingPushed = true; } // Loop thru the days. } else { // Does this classMeeting have days? // No, build no-day id. newId = `calendar_class_${scId}_${mTime}`; if ( DEBUG ) { console.log(`${PC}newId=${newId}`,CL); } Search_FindMeetings.idsToHighlight.push(newId); classMeetingPushed = true; } // Does this classMeeting have days? } // Has the instructorName not been added to idsToHighlight? } // Did we find and instructor name? } // Loop thru instructors. } // Are there instructors. } // Loop thru ClassMeetings } // Do the courseIds match? }} // Loop thru ScheduleClass. } //Was the class meeting NOT put in idsToHighlight? } //Was the class meeting NOT put in idsToHighlight? if ( DEBUG ) { console.log(`${PC}.idsToHighlight =${Search_FindMeetings.idsToHighlight}`,CI); } if ( classMeetingPushed ) { //Was the class meeting NOT put in idsToHighlight? // We have the idsToHighlight here and now need to highlight the Ids. Search_HighlightMeetings(); } //Was the class meeting NOT put in idsToHighlight? } // Is this course in the filter? }}// Loop thru courses. // END Search thru Courses. if ( DEBUG ) { console.groupEnd(); } } // END Search_FindMeetings. Search_FindMeetings.idsToHighlight = []; // Search_UpdateDatalist(e) // Populate schedule search datalist from input. function Search_UpdateDatalist(evt) { evt = (evt) ? evt : window.event; var DEBUG = false; if ( DEBUG ) { console.clear(); console.group(`${PC}Search_UpdateDatalist[evt.target.id=${evt.target.id}]`,CG); }//Collapsed // Get the <datalist> and <input> elements. var dataList = document.getElementById('datalistSearchSchedule'); let i; let j; let k; var input = document.getElementById('inpSearchSchedule'); let inputValue = input.value; let scId; let searchValue = inputValue.toLowerCase(); if ( DEBUG ) { console.log(`${PC}searchValue=${searchValue}`,CS); } if ( searchValue ) { // Is there something to search for? // Yes, Search for it. //input.value = ''; // Build course filter. Include only courses that are on the schedule. //ScheduleClass[2343] = { scId:2343, Course:"CST1021", courseId:"3267", Section:"41,42" }; let courseFiler = []; for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses. courseFiler.push(ScheduleClass[scId].courseId); }} // Loop thru ScheduleClasses. if ( DEBUG ) { console.log(`${PC}courseFiler=${courseFiler}`,CI); } //input.placeholder = "Loading options..."; // Update the placeholder text. // Clear the datalist if ( DEBUG ) { console.log(`${PC}dataList.options.length=${dataList.options.length}`,CL); } dataList.innerHTML = '<option>Loading options...</option>'; let dataListOptions = []; let optionAdd = false; //let searchWords = searchValue.split(' '); let searchWords = [searchValue]; for ( i=0; i<searchWords.length; i++ ) { let search = searchWords[i]; if ( search ) { if ( DEBUG ) { console.log(`${PC}Searching for ${search}`,CI); } // BEGIN Search thru Courses. for ( var courseId in Course ){if(Course.hasOwnProperty(courseId)){ // Loop thru courses. let searchOptions = []; //if ( DEBUG ) { console.log(`${PC} Course[${cId}]=${JSON.stringify( Course[courseId])}`,CL); } if ( courseFiler.indexOf(courseId) !== -1 ) { // Is this course in the filter? // Add the course dept number and title. let course = Course[courseId]; let thisOption = course.Dept + course.Number + ' ' + course.Title; searchOptions.push(thisOption); // Add rooms. for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass. //if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id} ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); } if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match? for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings let classMeeting = SCMnow[scId][j]; if ( DEBUG ) { console.log(`${PC}classMeeting.rooms.length=${classMeeting.rooms.length}`,CL); } if ( classMeeting.rooms.length ) { // Are there rooms. for ( k=0; k<classMeeting.rooms.length; k++ ) { // Loop thru rooms. let room = classMeeting.rooms[k]; if ( searchOptions.indexOf(room) == -1 ) { searchOptions.push(`Room ${room}`); } } // Loop thru rooms. } // Are there rooms. } // Loop thru ClassMeetings } // Do the courseIds match? }} // Loop thru ScheduleClass. // Add instructors. for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass. //if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id} ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); } if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match? for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings let classMeeting = SCMnow[scId][j]; if ( DEBUG ) { console.log(`${PC}classMeeting.instructors.length=${classMeeting.instructors.length}`,CL); } if ( classMeeting.instructors.length ) { // Are there instructors. for ( k=0; k<classMeeting.instructors.length; k++ ) { // Loop thru instructors. let instructorName = InstructorLookup[classMeeting.instructors[k]].Name; if ( searchOptions.indexOf(instructorName) == -1 ) { searchOptions.push(instructorName); } } // Loop thru instructors. } // Are there instructors. } // Loop thru ClassMeetings } // Do the courseIds match? }} // Loop thru ScheduleClass. // Add searchOptions to dataListOptions. if ( DEBUG ) { console.log(`${PC}searchOptions=${searchOptions}`,CL); } for ( j=0; j<searchOptions.length; j++ ) { // Loop thru searchOptions. let searchOption = searchOptions[j]; if ( searchOption.toLowerCase().indexOf(search) !== -1 ) { // Was search in searchOptions? // Yes, add to dataListOptions. if ( dataListOptions.indexOf(searchOption) === -1 ) { // Is it not already in dataListOptions? optionAdd = searchOption; dataListOptions.push(optionAdd); } // Is it not already in dataListOptions? if ( DEBUG ) { console.log(`${PC}${search} found in ${searchOption.toLowerCase()}.`,CL); } } // Was search in searchOptions? } // Loop thru searchOptions. } // Is this course in the filter? }}// Loop thru courses. // END Search thru Courses. } } dataListOptions.sort(); if ( DEBUG ) { console.log(`${PC}dataListOptions.length=${dataListOptions.length}`,CL); dataListOptions.forEach(option => { if ( DEBUG ) { console.log(`${PC}option=${option}`,CI); } }); } // Populate datalist with options. let dataListItems = []; dataListOptions.forEach(function (item) { // Create a new <option> element. var option = document.createElement('option'); // Set the value using the item in the JSON array. option.value = item; dataListItems.push(item); // Add the <option> element to the <datalist>. dataList.appendChild(option); }); if ( DEBUG ) { console.log(`${PC}dataListItems=${JSON.stringify(dataListItems)}`,CI); } if ( dataListItems.length == 1 ) { Search_FindMeetings(dataListItems[0]); } else { Search_UnhighlightMeetings(); } } else { // Is there something to search for? // No, clear any highlighted class meetings. Search_UnhighlightMeetings(); } // Is there something to search for? if ( DEBUG ) { console.groupEnd(); } } // END Search_UpdateDatalist. // Search_UnhighlightMeetings() // Unhighlight and clear meetings found by search. function Search_UnhighlightMeetings() { var DEBUG = false; if ( DEBUG ) { console.groupCollapsed(`${PC}Search_UnhighlightMeetings[]`,CG); }// if ( DEBUG ) { console.log(`${PC}Search_FindMeetings.idsToHighlight.length=${Search_FindMeetings.idsToHighlight.length}`,CI); } if ( Search_FindMeetings.idsToHighlight.length ) { // Are there idsToHighlight? for ( let i=0; i<Search_FindMeetings.idsToHighlight.length; i++ ) { // Loop thru idsToHighlight. let thisId = Search_FindMeetings.idsToHighlight[i]; let eToHighlight = document.getElementById(thisId); eToHighlight.style.boxShadow = ''; eToHighlight.style.zIndex = 1; eToHighlight.style.marginRight = '0'; eToHighlight.style.outline = ''; } // Loop thru idsToHighlight. } // Are there idsToHighlight? Search_FindMeetings.idsToHighlight = []; if ( DEBUG ) { console.groupEnd(); } } // END Search_UnhighlightMeetings. // SortObject(obj) // Sort an object by key, function SortObject(obj) { return Object.keys(obj).sort().reduce(function (result, key) { result[key] = obj[key]; return result; }, {}); } // END SortObject. // Element_Highlight() // Hightlight element. function Element_Highlight(id='', by='') { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}Element_Highlight[id=${id}] by=${by}`,CG); }//Collapsed if ( DEBUG ) { console.log(`${PC}Element_Highlight.idsToHighlight.length=${Element_Highlight.idsToHighlight.length}`,CI); } if ( id ) { if ( DEBUG ) { console.log(`${PC}Element_Highlight id=${id}`,CS); } Element_Highlight.idsToHighlight.push(id); let eToHighlight = document.getElementById(id); eToHighlight.classList.add('changeInSC'); } if ( DEBUG ) { console.groupEnd(); } } // END Element_Highlight. Element_Highlight.idsToHighlight = []; // Element_Unhighlight() // Unhighlight all dialog elements. function Element_Unhighlight() { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}Element_Unhighlight[]`,CG); }//Collapsed if ( DEBUG ) { console.log(`${PC}Element_Highlight.idsToHighlight.length=${Element_Highlight.idsToHighlight.length} = ${JSON.stringify(Element_Highlight.idsToHighlight)}`,CI); } if ( Element_Highlight.idsToHighlight.length ) { // Are there idsToHighlight? for ( let i=0; i<Element_Highlight.idsToHighlight.length; i++ ) { // Loop thru idsToHighlight. let thisId = Element_Highlight.idsToHighlight[i]; if ( DEBUG ) { console.log(`${PC}thisId=${thisId}`,CI); } let eToHighlight = document.getElementById(thisId); eToHighlight.classList.remove('changeInSC'); } // Loop thru idsToHighlight. } // Are there idsToHighlight? Element_Highlight.idsToHighlight = []; if ( DEBUG ) { console.groupEnd(); } } // END Element_Unhighlight.