JIT
HTML Code for Dynamic Stopwatch List with Add and Remove Functions
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); const lastMember = memberList.lastElementChild; memberList.removeChild(lastMember); memberCount--; delete timers[memberCount]; } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v1
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); const lastMember = memberList.lastElementChild; memberList.removeChild(lastMember); memberCount--; delete timers[memberCount]; } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v2
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); const lastMember = memberList.lastElementChild; memberList.removeChild(lastMember); memberCount--; delete timers[memberCount]; } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); // Initial call to set up event listeners. attachEventListeners(); </script> </body> </html>
Updated files
v3
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); const lastMember = memberList.lastElementChild; memberList.removeChild(lastMember); delete timers[memberCount - 1]; // Corrected delete line. memberCount--; } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v4
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); const lastMember = memberList.lastElementChild; memberList.removeChild(lastMember); // Rebuild timers object without the deleted member const newTimers = {}; let newIndex = 0; for (let i = 0; i < memberCount - 1; i++) { if (timers[i]) { newTimers[newIndex] = timers[i]; // Update data-index and timer id in the DOM const stopwatch = memberList.children[i].querySelector('.stopwatch'); const timerSpan = memberList.children[i].querySelector('.timer'); const resetButton = memberList.children[i].querySelector('.reset-button'); stopwatch.dataset.index = newIndex; timerSpan.id = `timer-${newIndex}`; resetButton.dataset.index = newIndex; newIndex++; } } timers = newTimers; memberCount--; attachEventListeners(); } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v5
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); memberList.removeChild(memberList.lastElementChild); // Remove the last member visually delete timers[memberCount - 1]; // Delete the timer data // Re-index the timers object and update the DOM const newTimers = {}; for (let i = 0, j = 0; i < memberCount - 1; i++) { if (timers[i]) { newTimers[j] = timers[i]; // Update DOM attributes const stopwatch = memberList.children[i].querySelector('.stopwatch'); const timerSpan = memberList.children[i].querySelector('.timer'); const resetButton = memberList.children[i].querySelector('.reset-button'); stopwatch.dataset.index = j; timerSpan.id = `timer-${j}`; resetButton.dataset.index = j; j++; } } timers = newTimers; memberCount--; attachEventListeners(); } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v6
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); memberList.removeChild(memberList.lastElementChild); delete timers[memberCount - 1]; const newTimers = {}; for (let i = 0, j = 0; i < memberCount - 1; i++) { if (memberList.children[i]) { // check if element exists newTimers[j] = timers[i]; const stopwatch = memberList.children[i].querySelector('.stopwatch'); const timerSpan = memberList.children[i].querySelector('.timer'); const resetButton = memberList.children[i].querySelector('.reset-button'); stopwatch.dataset.index = j; timerSpan.id = `timer-${j}`; resetButton.dataset.index = j; j++; } } timers = newTimers; memberCount--; attachEventListeners(); } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); if(timers[index]){ const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); if (timers[index]) { const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; } }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v7
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); memberList.removeChild(memberList.lastElementChild); delete timers[memberCount - 1]; const newTimers = {}; let newIndex = 0; for (let i = 0; i < memberCount - 1; i++) { if (memberList.children[i]) { newTimers[newIndex] = timers[i]; const stopwatch = memberList.children[i].querySelector('.stopwatch'); const timerSpan = memberList.children[i].querySelector('.timer'); const resetButton = memberList.children[i].querySelector('.reset-button'); stopwatch.dataset.index = newIndex; timerSpan.id = `timer-${newIndex}`; resetButton.dataset.index = newIndex; newIndex++; } } timers = newTimers; memberCount--; attachEventListeners(); } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); if (timers[index]) { const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); if (timers[index]) { const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; } }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>
Updated files
v8
<!DOCTYPE html> <html> <head> <title>Dynamic Stopwatch List</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .code-container { background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: 300px; } .member-row { display: flex; align-items: center; margin-bottom: 10px; } .member-name { flex-grow: 1; padding: 8px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; } .stopwatch-container { display: flex; align-items: center; margin-left: 10px; } .stopwatch { width: 20px; height: 20px; background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"%3E%3Cpath d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6l3.8 2.3 1-1.6-3.3-2 0-5z" fill="%23888"/%3E%3C/svg%3E'); background-size: cover; cursor: pointer; } .timer { font-family: monospace; margin-left: 5px; font-size: 14px; } .reset-button{ margin-left:5px; cursor:pointer; font-size: 12px; } .add-remove-buttons{ display: flex; justify-content: center; margin-top: 10px; } .add-remove-buttons button { margin: 0 5px; cursor: pointer; } </style> </head> <body> <div class="code-container"> <div id="member-list"> <div class="member-row"> <input type="text" class="member-name" value="Member 1"> <div class="stopwatch-container"> <div class="stopwatch" data-index="0"></div> <span class="timer" id="timer-0">0:00</span> <button class="reset-button" data-index="0">Reset</button> </div> </div> </div> <div class="add-remove-buttons"> <button id="add-member">Add Member</button> <button id="remove-member">Remove Member</button> </div> </div> <script> let memberCount = 1; let timers = { 0: { running: false, seconds: 0, interval: null }, }; function createMemberRow(index) { const memberRow = document.createElement('div'); memberRow.className = 'member-row'; memberRow.innerHTML = ` <input type="text" class="member-name" value="Member ${index + 1}"> <div class="stopwatch-container"> <div class="stopwatch" data-index="${index}"></div> <span class="timer" id="timer-${index}">0:00</span> <button class="reset-button" data-index="${index}">Reset</button> </div> `; return memberRow; } function addMember() { const memberList = document.getElementById('member-list'); timers[memberCount] = { running: false, seconds: 0, interval: null }; memberList.appendChild(createMemberRow(memberCount)); memberCount++; attachEventListeners(); } function removeMember() { if (memberCount > 1) { const memberList = document.getElementById('member-list'); memberList.removeChild(memberList.lastElementChild); delete timers[memberCount - 1]; const newTimers = {}; let newIndex = 0; for (let i = 0; i < memberCount - 1; i++) { if (memberList.children[i]) { newTimers[newIndex] = timers[i]; const stopwatch = memberList.children[i].querySelector('.stopwatch'); const timerSpan = memberList.children[i].querySelector('.timer'); const resetButton = memberList.children[i].querySelector('.reset-button'); stopwatch.dataset.index = newIndex; timerSpan.id = `timer-${newIndex}`; resetButton.dataset.index = newIndex; newIndex++; } } timers = newTimers; memberCount--; attachEventListeners(); } } function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = (seconds % 60).toFixed(2).padStart(5, '0'); return `${minutes}:${remainingSeconds}`; } function attachEventListeners() { const stopwatches = document.querySelectorAll('.stopwatch'); const resetButtons = document.querySelectorAll('.reset-button'); stopwatches.forEach(stopwatch => { stopwatch.addEventListener('click', () => { const index = parseInt(stopwatch.dataset.index); if (timers[index]) { const timerData = timers[index]; if (timerData.running) { clearInterval(timerData.interval); timerData.running = false; } else { timerData.running = true; timerData.interval = setInterval(() => { timerData.seconds += 0.01; if (timerData.seconds > 100) { clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 100; } document.getElementById(`timer-${index}`).textContent = formatTime(timerData.seconds); }, 10); } } }); }); resetButtons.forEach(button => { button.addEventListener('click', () => { const index = parseInt(button.dataset.index); if (timers[index]) { const timerData = timers[index]; clearInterval(timerData.interval); timerData.running = false; timerData.seconds = 0; document.getElementById(`timer-${index}`).textContent = '0:00'; } }); }); } document.getElementById('add-member').addEventListener('click', addMember); document.getElementById('remove-member').addEventListener('click', removeMember); attachEventListeners(); </script> </body> </html>