Football League Table Calculator | Calculate Standings & Rankings
| Pos | Team | Pld | W | D | L | GF | GA | GD | Pts | Win% | Action |
|---|
🏆 No Teams Added YetAdd your first team to start building your league table |
Share Your League Table
`);
printWindow.document.close();
printWindow.focus();
setTimeout(() => printWindow.print(), 500);
}
copySummary() {
const sortedTeams = this.sortTeams();
let summary = `🏆 Football League Table Summary\n`;
summary += `📅 Generated: ${new Date().toLocaleString()}\n\n`;
sortedTeams.slice(0, 5).forEach((team, index) => {
summary += `${index + 1}. ${team.name} - ${team.points} pts (${team.wins}W ${team.draws}D ${team.losses}L)\n`;
});
if (sortedTeams.length > 5) {
summary += `\n... and ${sortedTeams.length - 5} more teams`;
}
navigator.clipboard.writeText(summary).then(() => {
this.showToast('📋 Summary copied to clipboard!');
}).catch(() => {
this.showToast('Failed to copy summary', 'error');
});
}
shareOnPlatform(platform) {
const sortedTeams = this.sortTeams();
const topTeam = sortedTeams[0];
const shareText = `🏆 Football League Table: ${topTeam?.name || 'No teams'} is leading with ${topTeam?.points || 0} points! Check out the full standings.`;
const shareUrl = window.location.href;
const urls = {
facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}"e=${encodeURIComponent(shareText)}`,
x: `https://x.com/intent/tweet?text=${encodeURIComponent(shareText)}&url=${encodeURIComponent(shareUrl)}`,
whatsapp: `https://wa.me/?text=${encodeURIComponent(shareText + ' ' + shareUrl)}`,
telegram: `https://t.me/share/url?url=${encodeURIComponent(shareUrl)}&text=${encodeURIComponent(shareText)}`,
reddit: `https://reddit.com/submit?url=${encodeURIComponent(shareUrl)}&title=${encodeURIComponent(shareText)}`,
pinterest: `https://pinterest.com/pin/create/button/?url=${encodeURIComponent(shareUrl)}&description=${encodeURIComponent(shareText)}`,
linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(shareUrl)}`,
tiktok: `https://www.tiktok.com/upload?caption=${encodeURIComponent(shareText)}`,
vk: `https://vk.com/share.php?url=${encodeURIComponent(shareUrl)}&title=${encodeURIComponent(shareText)}`,
email: `mailto:?subject=Football League Table&body=${encodeURIComponent(shareText + '\n\n' + shareUrl)}`
};
if (urls[platform]) {
if (platform === 'email') {
window.location.href = urls[platform];
} else if (platform === 'tiktok') {
this.showToast('⚠️ Please manually copy and share on TikTok', 'warning');
navigator.clipboard.writeText(shareText + ' ' + shareUrl);
} else {
window.open(urls[platform], '_blank', 'width=600,height=400');
}
}
}
showToast(message, type = 'success') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = `toast show ${type}`;
if (type === 'error') toast.style.background = '#e74c3c';
else if (type === 'warning') toast.style.background = '#f39c12';
else toast.style.background = '#27ae60';
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
saveToStorage() {
try {
localStorage.setItem('footballLeagueData', JSON.stringify({
teams: this.teams,
winPoints: this.winPoints,
drawPoints: this.drawPoints
}));
} catch (e) {
console.warn('Failed to save to localStorage', e);
}
}
loadFromStorage() {
try {
const data = localStorage.getItem('footballLeagueData');
if (data) {
const parsed = JSON.parse(data);
this.winPoints = parsed.winPoints || 3;
this.drawPoints = parsed.drawPoints || 1;
document.getElementById('winPoints').value = this.winPoints;
document.getElementById('drawPoints').value = this.drawPoints;
return parsed.teams || [];
}
} catch (e) {
console.warn('Failed to load from localStorage', e);
}
return null;
}
}
// Initialize calculator
const calculator = new FootballLeagueCalculator();
// Add some microinteractions
document.addEventListener('DOMContentLoaded', () => {
// Add hover effect to table rows
document.addEventListener('mouseover', (e) => {
if (e.target.closest('tr') && e.target.closest('#tableBody')) {
e.target.closest('tr').style.transform = 'scale(1.02)';
}
});
document.addEventListener('mouseout', (e) => {
if (e.target.closest('tr') && e.target.closest('#tableBody')) {
e.target.closest('tr').style.transform = 'scale(1)';
}
});
// Focus effect on team name input
const teamNameInput = document.getElementById('teamName');
teamNameInput.addEventListener('focus', () => {
teamNameInput.style.boxShadow = '0 0 0 4px rgba(52, 152, 219, 0.2)';
});
teamNameInput.addEventListener('blur', () => {
teamNameInput.style.boxShadow = 'none';
});
// Add loading animation to buttons
document.querySelectorAll('.btn').forEach(btn => {
btn.addEventListener('click', function() {
const originalText = this.innerHTML;
const spinner = '
⏳ Loading...';
if (!this.classList.contains('no-spinner')) {
this.innerHTML = spinner;
this.disabled = true;
setTimeout(() => {
this.innerHTML = originalText;
this.disabled = false;
}, 800);
}
});
});
// Mark buttons that shouldn't show spinner
document.getElementById('addTeamBtn').classList.add('no-spinner');
document.querySelectorAll('.share-btn').forEach(btn => btn.classList.add('no-spinner'));
});
// Performance optimization: Debounce rapid updates
let updateTimeout;
function debounceUpdate(callback, delay = 300) {
clearTimeout(updateTimeout);
updateTimeout = setTimeout(callback, delay);
}
// Add debouncing to input updates
document.addEventListener('input', (e) => {
if (e.target.classList.contains('stats-input') || e.target.classList.contains('team-input')) {
debounceUpdate(() => {
if (e.target.classList.contains('stats-input')) {
calculator.validateNumericInput(e.target);
}
calculator.updateTeamData(e.target);
});
}
});
// Service Worker for offline capability (optional enhancement)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('data:application/javascript,').catch(() => {});
}