Online Digital Flashcard Library

Online Digital Flashcard Library

Create, manage, and study your own digital flashcard decks.

Card 0 of 0

No deck selected. Please create or select a deck.

'; cardProgress.textContent = "Card 0 of 0"; return; } const deck = flashcardData.decks.find(d => d.id == deckId); if (!deck) return; studySession.deck = deck; studySession.currentIndex = 0; studySession.shuffledIndices = Array.from(Array(deck.cards.length).keys()); flashcardData.lastStudiedDeckId = deck.id; saveData(); renderCurrentCard(); }; const renderCurrentCard = () => { if (!studySession.deck || studySession.deck.cards.length === 0) { flashcardContainer.innerHTML = '

This deck is empty. Add cards in the "Manage Library" tab.

'; cardProgress.textContent = "Card 0 of 0"; return; } const cardIndex = studySession.shuffledIndices[studySession.currentIndex]; const card = studySession.deck.cards[cardIndex]; flashcardContainer.innerHTML = `
${card.term}
${card.definition}
`; cardProgress.textContent = `Card ${studySession.currentIndex + 1} of ${studySession.deck.cards.length}`; }; deckSelector.addEventListener('change', (e) => loadDeckForStudy(e.target.value)); flipCardBtn.addEventListener('click', () => flashcardContainer.querySelector('.flashcard')?.classList.toggle('flipped')); nextCardBtn.addEventListener('click', () => { if (studySession.deck && studySession.currentIndex < studySession.deck.cards.length - 1) { studySession.currentIndex++; renderCurrentCard(); } }); prevCardBtn.addEventListener('click', () => { if (studySession.deck && studySession.currentIndex > 0) { studySession.currentIndex--; renderCurrentCard(); } }); shuffleBtn.addEventListener('click', () => { if (!studySession.deck || studySession.deck.cards.length < 2) return; // Fisher-Yates shuffle for (let i = studySession.shuffledIndices.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [studySession.shuffledIndices[i], studySession.shuffledIndices[j]] = [studySession.shuffledIndices[j], studySession.shuffledIndices[i]]; } studySession.currentIndex = 0; renderCurrentCard(); showMessage('Deck shuffled!', false); }); // --- MANAGE LIBRARY TAB LOGIC --- const renderDeckManagement = () => { deckManagementList.innerHTML = ''; if (flashcardData.decks.length === 0) { deckManagementList.innerHTML = '

You have no decks. Create one above to get started.

'; return; } flashcardData.decks.forEach(deck => { const deckContainer = document.createElement('div'); deckContainer.className = 'border border-gray-200 rounded-lg'; deckContainer.innerHTML = `

${deck.name}

${deck.cards.map(card => `
${card.term}: ${card.definition}
`).join('') || '

This deck is empty.

'}
`; deckManagementList.appendChild(deckContainer); }); }; addDeckBtn.addEventListener('click', () => { const name = newDeckNameInput.value.trim(); if (!name) { showMessage('Please enter a deck name.'); return; } flashcardData.decks.push({ id: Date.now(), name: name, cards: [] }); newDeckNameInput.value = ''; saveData(); renderDeckManagement(); showMessage('Deck created successfully!', false); }); deckManagementList.addEventListener('click', (e) => { const target = e.target; // Add Card if (target.classList.contains('add-card-btn')) { const deckId = target.dataset.deckId; const form = target.closest('.add-card-form'); const termInput = form.querySelector('.new-card-term'); const defInput = form.querySelector('.new-card-def'); const term = termInput.value.trim(); const def = defInput.value.trim(); if (!term || !def) { showMessage('Both term and definition are required.'); return; } const deck = flashcardData.decks.find(d => d.id == deckId); deck.cards.push({ id: Date.now(), term, definition: def }); termInput.value = ''; defInput.value = ''; saveData(); renderDeckManagement(); } // Delete Card if (target.classList.contains('delete-card-btn')) { const deckId = target.dataset.deckId; const cardId = target.dataset.cardId; const deck = flashcardData.decks.find(d => d.id == deckId); deck.cards = deck.cards.filter(c => c.id != cardId); saveData(); renderDeckManagement(); } // Delete Deck if (target.classList.contains('delete-deck-btn')) { const deckId = target.dataset.deckId; if (confirm('Are you sure you want to delete this entire deck?')) { flashcardData.decks = flashcardData.decks.filter(d => d.id != deckId); if (flashcardData.lastStudiedDeckId == deckId) { flashcardData.lastStudiedDeckId = null; } saveData(); renderDeckManagement(); } } // Download PDF if (target.classList.contains('download-pdf-btn')) { handlePdfDownload(target.dataset.deckId); } }); // --- PDF DOWNLOAD LOGIC --- const handlePdfDownload = (deckId) => { const deck = flashcardData.decks.find(d => d.id == deckId); if (!deck) return; showMessage('Preparing PDF...', false); // Create a temporary, hidden element for PDF generation const pdfElement = document.createElement('div'); pdfElement.style.position = 'absolute'; pdfElement.style.left = '-9999px'; pdfElement.style.width = '800px'; pdfElement.style.padding = '20px'; pdfElement.innerHTML = `

${deck.name}

${deck.cards.map(card => ` `).join('')}
Term Definition
${card.term} ${card.definition}
`; document.body.appendChild(pdfElement); const { jsPDF } = window.jspdf; html2canvas(pdfElement, { scale: 2 }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'in', format: 'letter' }); const pdfWidth = pdf.internal.pageSize.getWidth() - 1; const pdfHeight = (canvas.height * pdfWidth) / canvas.width; pdf.addImage(imgData, 'PNG', 0.5, 0.5, pdfWidth, pdfHeight); pdf.save(`${deck.name.replace(/ /g, '_')}_Flashcards.pdf`); document.body.removeChild(pdfElement); showMessage('PDF downloaded!', false); }).catch(err => { console.error("PDF Generation Error:", err); showMessage("An error occurred during PDF generation."); document.body.removeChild(pdfElement); }); }; // --- INITIALIZATION --- const initializeApp = () => { loadData(); switchTab('tab1'); }; initializeApp(); });
Scroll to Top