1document.addEventListener("DOMContentLoaded", function () { 2 parkerDebugLog("DOM Content Loaded"); 3 4 // Add loaded class to form container to prevent flash of unstyled content 5 const formContainer = document.querySelector('.form-container'); 6 if (formContainer) { 7 formContainer.classList.add('loaded'); 8 } 9 10 // Check if using unmanaged data (default is managed) 11 const urlParams = new URLSearchParams(window.location.search); 12 const useUnmanagedData = urlParams.get('use_unmanaged_data') === '1'; 13 parkerDebugLog('ð DATA SOURCE:', useUnmanagedData ? 'SALESFORCE (Direct API)' : 'DATABASE (Managed)'); 14 15 const programsDropdown = document.querySelector('#TargetX_SRMb__Program__c'); 16 const programTermsDropdown = document.querySelector('#custom_program_term'); 17 const submitButton = document.getElementById("submit-btn"); 18 let programLabelInput = document.querySelector('#program-label'); 19 20 // #submit-btn only exists in the "appconfig" (step-1 program/term picker) 21 // context â this script also runs on plain step-2+ pages that never render it. 22 if (submitButton) { 23 submitButton.textContent = 'Next'; 24 } 25 26 if (!programLabelInput) { 27 programLabelInput = document.createElement('input'); 28 programLabelInput.type = 'hidden'; 29 programLabelInput.name = 'available_program'; 30 programLabelInput.id = 'available_program'; 31 } 32 33 if (programsDropdown && programTermsDropdown) { 34 35 const programTermsFormGroup = programTermsDropdown.closest('.form-group'); 36 37 // Hide program terms dropdown on page load 38 programTermsFormGroup.style.display = 'none'; 39 40 let debounceTimer; 41 programsDropdown.addEventListener("change", function () { 42 clearTimeout(debounceTimer); 43 debounceTimer = setTimeout(() => { 44 45 const selectedProgramProcess = programsDropdown.value; 46 47 parkerDebugLog("=== PROGRAM SELECTED ==="); 48 parkerDebugLog("Program Field:", programsDropdown); 49 parkerDebugLog("Selected Program Value:", selectedProgramProcess); 50 parkerDebugLog("Selected Program Label:", programsDropdown.options[programsDropdown.selectedIndex].text); 51 52 if (programsDropdown) { 53 Array.from(programsDropdown.options).forEach(option => { 54 parkerDebugLog(`Value: ${option.value}, Label: ${option.text}`); 55 }); 56 } else { 57 parkerDebugWarn("Dropdown not found."); 58 } 59 60 parkerDebugLog("Available Programs: ", window.jsonDecodedAvailablePrograms); 61 parkerDebugLog("Available Program Terms Keys:", Object.keys(window.jsonDecodedAvailableProgramTerms)); 62 parkerDebugLog("Full Available Program Terms:", window.jsonDecodedAvailableProgramTerms); 63 64 // Show program terms once program is selected 65 if (programTermsFormGroup) { 66 FieldHandler.toggleVisibility(programTermsFormGroup, true); 67 } 68 69 // Hide dropdown if no program is selected 70 if (!selectedProgramProcess) { 71 FieldHandler.toggleVisibility(programTermsFormGroup, false); 72 return; 73 } 74 75 // Get terms for the selected program 76 const terms = window.jsonDecodedAvailableProgramTerms[selectedProgramProcess]; 77 78 parkerDebugLog("Terms for this program:", terms); 79 parkerDebugLog("Number of terms:", terms ? terms.length : 0); 80 81 // If no terms or terms array is empty, show "No terms available" 82 if (!terms || terms.length === 0) { 83 parkerDebugWarn("No terms available for this program."); 84 programTermsDropdown.innerHTML = '<option value="">No terms available</option>'; 85 return; 86 } 87 88 // Filter for active terms 89 const activeTerms = getActiveTerms(terms); 90 if (!activeTerms || activeTerms.length === 0) { 91 parkerDebugWarn("No active terms available."); 92 programTermsDropdown.innerHTML = '<option value="">No active terms available</option>'; 93 return; 94 } 95 96 // Sort terms chronologically by month/year parsed from name 97 const sortedTerms = sortTermsChronologically(activeTerms); 98 99 // Populate dropdown with sorted active terms 100 FieldHandler.populateDropdown(programTermsDropdown, sortedTerms, 'Select a term'); 101 102 }, 300); // Debounce delay of 300ms 103 }); 104 } 105 106 /** 107 * Filters terms based on their start and end dates. 108 * @param {Array} terms - Array of term objects. 109 * @returns {Array} - Filtered array of active terms. 110 */ 111 function getActiveTerms(terms) { 112 const today = new Date(); 113 const activeTerms = terms.filter(term => { 114 const startDate = new Date(term.start_date); 115 const endDate = new Date(term.end_date); 116 const isActive = startDate <= today && endDate >= today; 117 parkerDebugLog("Term:", term, "Is Active:", isActive); 118 return isActive; 119 }); 120 parkerDebugLog("Filtered Active Terms:", activeTerms); 121 return activeTerms; 122 } 123 124 /** 125 * Sorts terms chronologically by parsing month/season and year from term name. 126 * Handles formats like: 127 * "May 2026 - Summer" 128 * "EKG/MA May 2026 - Summer" 129 * "UG/GR Summer 2026" 130 */ 131 function sortTermsChronologically(terms) { 132 const monthOrder = { 133 'january': 0, 'february': 1, 'march': 2, 'april': 3, 134 'may': 4, 'june': 5, 'july': 6, 'august': 7, 135 'september': 8, 'october': 9, 'november': 10, 'december': 11 136 }; 137 138 // Map seasons to approximate month for sorting when no month is present 139 const seasonOrder = { 140 'winter': 0, // January 141 'spring': 3, // April 142 'summer': 4, // May 143 'fall': 8 // September 144 }; 145 146 function getTermSortKey(termName) { 147 const lower = termName.toLowerCase(); 148 149 // Extract year (any 4-digit number) 150 const yearMatch = termName.match(/\b(\d{4})\b/);
151 const year = yearMatch ? parseInt(yearMatch[1], 10) : 9999; 152 153 // Try to find a month name anywhere in the string 154 let month = -1; 155 for (const [name, idx] of Object.entries(monthOrder)) { 156 if (lower.includes(name)) { 157 month = idx; 158 break; 159 } 160 } 161 162 // If no month found, try to find a season name 163 if (month === -1) { 164 for (const [name, idx] of Object.entries(seasonOrder)) { 165 if (lower.includes(name)) { 166 month = idx; 167 break; 168 } 169 } 170 } 171 172 if (month === -1) month = 99; 173 174 return year * 100 + month; 175 } 176 177 return [...terms].sort((a, b) => getTermSortKey(a.name) - getTermSortKey(b.name)); 178 } 179});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.