1const userCardTemplate = document.querySelector("[data-user-template]"); 2const userCardContainer = document.querySelector("[data-user-cards-container]"); 3const searchInput = document.querySelector("[data-search]"); 4const gridViewBtn = document.querySelector('[data-view="grid"]'); 5const listViewBtn = document.querySelector('[data-view="list"]'); 6const racesResultURL = func(globalresultsurl); 7 8let users = []; 9let currentView = 'grid'; 10 11// Show spinner 12const spinner = document.getElementById('spinner'); 13spinner.classList.add('active'); 14 15// Extract year from date string 16function extractYear(dateString) { 17 const yearMatch = dateString.match(/\d{4}/); 18 return yearMatch ? parseInt(yearMatch[0]) : new Date().getFullYear(); 19} 20 21// Render grid view 22function renderGridView(cardsToRender) { 23 userCardContainer.innerHTML = ''; 24 cardsToRender.forEach(user => { 25 userCardContainer.appendChild(user.element); 26 }); 27} 28 29// Render list view (grouped by year) 30function renderListView(cardsToRender) { 31 userCardContainer.innerHTML = ''; 32 33 // Group cards by year 34 const groupedByYear = cardsToRender.reduce((acc, user) => { 35 if (!acc[user.year]) { 36 acc[user.year] = []; 37 } 38 acc[user.year].push(user); 39 return acc; 40 }, {}); 41 42 // Sort years in descending order 43 const sortedYears = Object.keys(groupedByYear).sort((a, b) => b - a); 44 45 // Create year groups 46 sortedYears.forEach(year => { 47 const yearGroup = document.createElement('div'); 48 yearGroup.className = 'year-group'; 49 50 const yearHeader = document.createElement('div'); 51 yearHeader.className = 'year-header'; 52 yearHeader.textContent = year; 53 54 const yearItems = document.createElement('div'); 55 yearItems.className = 'year-items'; 56 57 groupedByYear[year].forEach(user => { 58 yearItems.appendChild(user.element); 59 }); 60 61 yearGroup.appendChild(yearHeader); 62 yearGroup.appendChild(yearItems); 63 userCardContainer.appendChild(yearGroup); 64 }); 65} 66 67// Switch views 68function switchView(view) { 69 currentView = view; 70 71 // Update button states 72 if (view === 'grid') { 73 gridViewBtn.classList.add('active'); 74 listViewBtn.classList.remove('active'); 75 userCardContainer.classList.remove('list-view'); 76 userCardContainer.classList.add('grid-view'); 77 renderGridView(users.filter(user => !user.element.classList.contains('hide'))); 78 } else { 79 listViewBtn.classList.add('active'); 80 gridViewBtn.classList.remove('active'); 81 userCardContainer.classList.remove('grid-view'); 82 userCardContainer.classList.add('list-view'); 83 renderListView(users.filter(user => !user.element.classList.contains('hide'))); 84 } 85} 86 87// Search functionality 88searchInput.addEventListener("input", (e) => { 89 const value = e.target.value.toLowerCase(); 90 users.forEach(user => { 91 const isVisible = user.Race.toLowerCase().includes(value) || 92 user.Address.toLowerCase().includes(value) || 93 user.Date.toLowerCase().includes(value); 94 user.element.classList.toggle("hide", !isVisible); 95 }); 96 97 // Re-render based on current view 98 if (currentView === 'grid') { 99 renderGridView(users.filter(user => !user.element.classList.contains('hide'))); 100 } else { 101 renderListView(users.filter(user => !user.element.classList.contains('hide'))); 102 } 103}); 104 105// View toggle event listeners 106gridViewBtn.addEventListener('click', () => switchView('grid')); 107listViewBtn.addEventListener('click', () => switchView('list')); 108 109// Fetch and display results 110fetch(racesResultURL) 111 .then(res => res.json()) 112 .then(data => { 113 users = data.map(user => { 114 const card = userCardTemplate.content.cloneNode(true).children[0]; 115 const header = card.querySelector("[data-header]"); 116 const body = card.querySelector("[data-body]"); 117 const text = card.querySelector("[data-body-text]"); 118 const header_image = card.querySelector("[data-header-image]"); 119 const result = card.querySelector("[data-result]"); 120 121 // List view specific elements 122 const listDate = card.querySelector("[data-list-date]"); 123 const listLocation = card.querySelector("[data-list-location]"); 124 const listImage = card.querySelector("[data-list-image]"); 125 126 // Set card data 127 header.textContent = user.Race; 128 body.textContent = user.Address; 129 text.textContent = user.Date; 130 131 // Set header_image src for grid view 132 header_image.innerHTML = "<a href='" + user.Website
132+ "' target='_blank'><img class='backdrop' loading='lazy' src='" + user.Image + "'/></a>"; 133 result.innerHTML = "<a href='" + user.Result + "' target='_top'>View More...</a>"; 134 135 // Set list view image 136 if (listImage) { 137 listImage.innerHTML = "<a href='" + user.Website + "' target='_blank'><img loading='lazy' src='" + user.Image + "' alt='" + user.Race + "'/></a>"; 138 } 139 140 // Set list view specific data 141 if (listDate) { 142 const dateSpan = listDate.querySelector('span:last-child'); 143 if (dateSpan) dateSpan.textContent = user.Date; 144 } 145 if (listLocation) { 146 const locationSpan = listLocation.querySelector('span:last-child'); 147 if (locationSpan) locationSpan.textContent = user.Address; 148 } 149 150 userCardContainer.append(card); 151 152 // Extract year from date 153 const year = extractYear(user.Date); 154 155 // Return results data with year 156 return { 157 ...user, 158 element: card, 159 year: year 160 }; 161 }); 162 }) 163 .finally(() => { 164 // Hide spinner after fetching 165 spinner.classList.remove('active'); 166 }); 167 168const get_card = document.querySelector(".user-cards"); 169get_card.addEventListener("click", (e) => { 170 console.log(e.target.textContent); 171});
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.