Email List Management: Store and manage a list of subscribed emails locally.
Success Feedback with Email Display: Show the email of the user who subscribed in the success message.
Improved Validation: Check for duplicate subscriptions within the modal’s lifecycle.
Optional Name Input: Allow users to enter their name along with their email.
Animations: Add more animations to the success message.
Dark Mode Toggle: Allow users to switch between light and dark modes
.Accessibility Improvements: Ensure the modal is accessible to keyboard users.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Subscription Modal with Emojis and Graphics</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#openModal {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
transition: background-color 0.3s, box-shadow 0.3s;
}
#openModal:hover {
background-color: #0056b3;
box-shadow: 0 0 20px rgba(0, 123, 255, 0.8), 0 0 30px rgba(0, 123, 255, 0.6);
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
animation: fadeIn 0.5s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 300px;
text-align: center;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
animation: slideIn 0.5s;
transition: background-color 0.3s;
}
@keyframes slideIn {
from { transform: translateY(-50px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.close-button {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close-button:hover {
color: black;
}
.modal-header {
margin-bottom: 20px;
}
.modal-header img {
width: 100%;
border-radius: 8px;
}
form {
margin-top: 15px;
}
input[type="email"] {
padding: 10px;
width: 80%;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
transition: border-color 0.3s, box-shadow 0.3s;
}
input[type="email"]:focus {
border-color: #007BFF;
outline: none;
box-shadow: 0 0 10px rgba(0, 123, 255, 0.8);
}
select {
padding: 10px;
width: 80%;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
transition: border-color 0.3s, box-shadow 0.3s;
}
select:focus {
border-color: #007BFF;
box-shadow: 0 0 10px rgba(0, 123, 255, 0.8);
}
button {
padding: 10px 15px;
background-color: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s, box-shadow 0.3s;
}
button:hover {
background-color: #218838;
box-shadow: 0 0 20px rgba(40, 167, 69, 0.8), 0 0 30px rgba(40, 167, 69, 0.6);
}
.reset-button {
background-color: #dc3545; /* Red */
}
.reset-button:hover {
background-color: #c82333; /* Darker Red */
box-shadow: 0 0 20px rgba(220, 53, 69, 0.8), 0 0 30px rgba(220, 53, 69, 0.6);
}
.success-message, .error-message, .already-subscribed-message {
margin-top: 15px;
display: none; /* Hide messages by default */
}
.success-message {
color: #28a745;
animation: fadeInMessage 0.5s;
}
.error-message, .already-subscribed-message {
color: #dc3545;
animation: fadeInMessage 0.5s;
}
@keyframes fadeInMessage {
from { opacity: 0; }
to { opacity: 1; }
}
.loading {
display: none;
margin-top: 10px;
}
.spinner {
width: 30px;
height: 30px;
border: 4px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top: 4px solid #007BFF;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Emoji styles */
.emoji {
font-size: 24px; /* Adjust emoji size */
}
</style>
</head>
<body>
<button id="openModal" aria-haspopup="dialog" aria-controls="subscriptionModal">📰 Subscribe Now</button>
<div id="subscriptionModal" class="modal" role="dialog" aria-labelledby="modalTitle" aria-modal="true">
<div class="modal-content">
<span class="close-button" aria-label="Close modal">×</span>
<div class="modal-header">
<img src="https://via.placeholder.com/280x100.png?text=Your+Logo+Here" alt="Your Logo">
</div>
<h2 id="modalTitle">📩 Subscribe to Our Newsletter!</h2>
<form id="subscriptionForm" aria-labelledby="modalTitle">
<input type="email" placeholder="📧 Enter your email" required aria-required="true">
<select id="newsletterType" required aria-required="true">
<option value="">🗓️ Select Newsletter Type</option>
<option value="daily">Daily Updates ☀️</option>
<option value="weekly">Weekly Digest 📅</option>
<option value="monthly">Monthly Highlights 📅🌟</option>
</select>
<button type="submit">✅ Subscribe</button>
<button type="button" class="reset-button" id="resetButton" aria-label="Reset email input">❌ Reset</button>
</form>
<div class="loading" id="loading">
<div class="spinner"></div>
</div>
<div class="success-message" id="successMessage">🎉 Thank you for subscribing!</div>
<div class="error-message" id="errorMessage">⚠️ Please enter a valid email address.</div>
<div class="already-subscribed-message" id="alreadySubscribedMessage">🚫 You've already subscribed!</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const modal = document.getElementById("subscriptionModal");
const openModalButton = document.getElementById("openModal");
const closeModalButton = document.querySelector(".close-button");
const form = document.getElementById("subscriptionForm");
const successMessage = document.getElementById("successMessage");
const errorMessage = document.getElementById("errorMessage");
const alreadySubscribedMessage = document.getElementById("alreadySubscribedMessage");
const loading = document.getElementById("loading");
const emailInput = form.querySelector('input[type="email"]');
const resetButton = document.getElementById("resetButton");
const newsletterType = document.getElementById("newsletterType");
// Open modal
openModalButton.onclick = function() {
modal.style.display = "block";
emailInput.value = ''; // Reset input field
newsletterType.value = ''; // Reset select field
resetButton.style.display = 'inline-block'; // Show reset button
successMessage.style.display = 'none';
errorMessage.style.display = 'none';
alreadySubscribedMessage.style.display = 'none';
}
// Close modal
closeModalButton.onclick = function() {
modal.style.display = "none";
}
// Close modal when clicking outside
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
// Form submission
form.onsubmit = function(e) {
e.preventDefault(); // Prevent default form submission
const email = emailInput.value;
const type = newsletterType.value;
loading.style.display = "block"; // Show loading spinner
// Simulate a network request
setTimeout(() => {
loading.style.display = "none"; // Hide loading spinner
const alreadySubscribed = false; // Simulated subscription check (replace with actual check)
if (alreadySubscribed) {
alreadySubscribedMessage.style.display = "block"; // Show already subscribed message
} else if (email && validateEmail(email)) {
successMessage.style.display = "block"; // Show success message
// You can replace the next line with actual subscription logic
console.log(`Subscribed: ${email}, Type: ${type}`);
} else {
errorMessage.style.display = "block"; // Show error message
}
}, 1000); // Simulating a network request delay
}
// Email validation function
function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // Basic email validation regex
return re.test(email);
}
// Reset button functionality
resetButton.onclick = function() {
emailInput.value = ''; // Clear input field
newsletterType.value = ''; // Clear select field
successMessage.style.display = 'none'; // Hide success message
errorMessage.style.display = 'none'; // Hide error message
alreadySubscribedMessage.style.display = 'none'; // Hide already subscribed message
}
});
</script>
</body>
</html>
HTML