document.addEventListener('DOMContentLoaded', () => { const papersGrid = document.getElementById('papersGrid'); const searchInput = document.getElementById('searchInput'); const dateFrom = document.getElementById('dateFrom'); const dateTo = document.getElementById('dateTo'); const searchBtn = document.getElementById('searchBtn'); const loader = document.getElementById('loader'); const noResults = document.getElementById('noResults'); const resultCount = document.getElementById('resultCount'); // Default query for AI papers const DEFAULT_QUERY = 'cat:cs.AI OR cat:cs.LG OR cat:cs.CL'; // Initial Fetch fetchPapers(DEFAULT_QUERY); // Event Listeners searchBtn.addEventListener('click', () => { const query = searchInput.value.trim(); fetchPapers(query ? `all:${query}` : DEFAULT_QUERY); }); searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { searchBtn.click(); } }); // Date Filter Listener (Client-side filter on loaded data) // For simplicity in this demo, we re-fetch or filter if data is present. // Here we'll re-trigger the search logic to apply filters if data exists, // but for a robust app, we'd store the 'allPapers' array. let allPapersData = []; dateFrom.addEventListener('change', applyClientFilters); dateTo.addEventListener('change', applyClientFilters); async function fetchPapers(searchQuery) { showLoader(true); noResults.classList.add('hidden'); papersGrid.innerHTML = ''; try { // ArXiv API endpoint const baseUrl = 'http://export.arxiv.org/api/query?'; const params = new URLSearchParams({ search_query: searchQuery, start: 0, max_results: 50, // Fetch a good amount to filter by date sortBy: 'submittedDate', sortOrder: 'descending' }); const response = await fetch(baseUrl + params.toString()); if (!response.ok) throw new Error('Network response was not ok'); const xmlText = await response.text(); const papers = parseArxivXml(xmlText); allPapersData = papers; applyClientFilters(); // Apply any existing date filters immediately } catch (error) { console.error('Error fetching papers:', error); resultCount.textContent = 'Error fetching data'; noResults.classList.remove('hidden'); showLoader(false); } } function parseArxivXml(xmlString) { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlString, "text/xml"); const entries = xmlDoc.getElementsByTagName("entry"); const papers = []; for (let i = 0; i < entries.length; i++) { const entry = entries[i]; // Title const title = entry.getElementsByTagName("title")[0].textContent; // Summary (Abstract) - Remove newlines and trim const summary = entry.getElementsByTagName("summary")[0].textContent.replace(/\s+/g, ' ').trim(); // Published Date const published = entry.getElementsByTagName("published")[0].textContent; // Authors const authors = []; const authorNodes = entry.getElementsByTagName("author"); for (let j = 0; j < authorNodes.length; j++) { authors.push(authorNodes[j].getElementsByTagName("name")[0].textContent); } // Link (PDF) const links = entry.getElementsByTagName("link"); let pdfLink = ""; for(let k=0; k { const paperDate = new Date(paper.published); let isValid = true; if (fromVal && paperDate < fromVal) isValid = false; if (toVal && paperDate > toVal) isValid = false; return isValid; }); displayPapers(filteredPapers); } function displayPapers(papers) { showLoader(false); resultCount.textContent = `Found ${papers.length} papers`; if (papers.length === 0) { noResults.classList.remove('hidden'); return; } papers.forEach(paper => { // Create Web Component const card = document.createElement('paper-card'); // Pass data to component card.setAttribute('title', paper.title); card.setAttribute('summary', paper.summary); card.setAttribute('authors', paper.authors.join(', ')); card.setAttribute('date', new Date(paper.published).toLocaleDateString()); card.setAttribute('pdf-link', paper.pdfLink); card.setAttribute('abs-link', paper.idLink); papersGrid.appendChild(card); }); } function showLoader(show) { if (show) { loader.classList.remove('hidden'); papersGrid.classList.add('hidden'); resultCount.textContent = 'Searching...'; } else { loader.classList.add('hidden'); papersGrid.classList.remove('hidden'); } } });