1document.addEventListener('DOMContentLoaded', async function () { 2 const STOREFRONT_TOKEN = window.APP_CONFIG.token; 3 const ROOT_CATEGORY_ID = 24; 4 const EXCLUDED_MODEL_IDS = [1792]; // replace with real category IDs 5 6 const modelSelect = document.getElementById('model'); 7 const yearSelect = document.getElementById('year'); 8 const searchBtn = document.getElementById('searchBtn'); 9 const resetBtn = document.getElementById('resetBtn'); 10 11 let modelData = []; 12 13 // GraphQL query using categoryTree 14 const query = ` 15 query { 16 site { 17 categoryTree { 18 entityId 19 name 20 path 21 children { 22 entityId 23 name 24 path 25 children { 26 entityId 27 name 28 path 29 } 30 } 31 } 32 } 33 } 34 `; 35 36 // Helper to find category by ID recursively 37 function findCategoryById(tree, id) { 38 for (const cat of tree) { 39 if (cat.entityId == id) return cat; 40 if (cat.children) { 41 const found = findCategoryById(cat.children, id); 42 if (found) return found; 43 } 44 } 45 return null; 46 } 47 48 // Fetch models & years 49 async function fetchModels() { 50 const res = await fetch('/graphql', { 51 method: 'POST', 52 headers: { 53 'Content-Type': 'application/json', 54 'Authorization': `Bearer ${STOREFRONT_TOKEN}` 55 }, 56 body: JSON.stringify({ query }) 57 }); 58 59 const data = await res.json(); 60 const tree = data.data.site.categoryTree; 61 const root = findCategoryById(tree, ROOT_CATEGORY_ID); 62 63 if (!root || !root.children) return []; 64 65 return root.children 66 .filter(model => !EXCLUDED_MODEL_IDS.includes(model.entityId)) 67 .map(model => ({ 68 id: model.entityId, 69 name: model.name, 70 years: (model.children || []).filter(c => /^\d{4}$/.test(c.name)) 71 })); 72 } 73 74 // Populate models dropdown 75 function populateModels(data) { 76 modelSelect.innerHTML = '<option value="">Select Model</option>'; 77 data.forEach(model => { 78 const opt = document.createElement('option'); 79 opt.value = model.id; 80 opt.textContent = model.name; 81 modelSelect.appendChild(opt); 82 }); 83 } 84 85 // Populate years dropdown based on selected model 86 function populateYears(modelId) { 87 yearSelect.innerHTML = '<option value="">Select Year</option>'; 88 const selected = modelData.find(m => m.id == modelId); 89 if (!selected) return; 90 selected.years.forEach(year => { 91 const opt = document.createElement('option'); 92 opt.value = year.path; 93 opt.textContent = year.name; 94 yearSelect.appendChild(opt); 95 }); 96 } 97 98 // Save selection to session 99 function saveSelection() { 100 sessionStorage.setItem('selectedModel', modelSelect.value); 101 sessionStorage.setItem('selectedYear', yearSelect.value); 102 } 103 104 // Restore selection safely after dropdown is populated 105 function restoreSelection() { 106 const savedModel = sessionStorage.getItem('selectedModel'); 107 const savedYear = sessionStorage.getItem('selectedYear'); 108 109 // Restore model if it exists 110 if (savedModel && [...modelSelect.options].some(opt => opt.value === savedModel)) { 111 modelSelect.value = savedModel; 112 populateYears(savedModel); 113 } 114 115 // Restore year if it exists 116 if (savedYear && [...yearSelect.options].some(opt => opt.value === savedYear)) { 117 yearSelect.value = savedYear; 118 } 119 } 120 121 // Event listeners 122 modelSelect.addEventListener('change', function () { 123 populateYears(this.value); 124 saveSelection(); 125 }); 126 127 yearSelect.addEventListener('change', function () { 128 saveSelection(); // only save; no auto-redirect 129 }); 130 131 searchBtn.addEventListener('click', function () { 132 const selectedModel = modelSelect.value; 133 const selectedYear = yearSelect.value; 134 135 if (!selectedModel || !selectedYear) { 136 alert('Please select a model and year'); 137 return; 138 } 139 140 saveSelection(); 141 const model = modelData.find(m => m.id == selectedModel); 142 const year = model.years.find(y => y.path == selectedYear); 143 144 if (year) window.location.href = year.path; 145 }); 146 147 resetBtn.addEventListener('click', function () { 148 sessionStorage.removeItem('selectedModel'); 149 sessionStorage.removeItem('selectedYear'); 150 modelSelect.value = ''; 151 yearSelect.innerHTML = '<option value="">Select Year</option>'; 152 }); 153 154 // Initialize 155 modelData = await fetchModels(); 156 populateModels(modelData); 157 restoreSelection(); // restore AFTER models are populated 158});
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.