Dialogs that behave like dialogs
Build a reusable delete confirmation flow
Reuse one confirmation dialog for every task while keeping the selected record and destructive action explicit.
A board with twenty tasks does not need twenty confirmation dialogs. One dialog can receive the selected task, show its name, and delete only after a clear confirm value comes back.
Store the pending task element in JavaScript when Delete is clicked. Put the task title into a normal text node, never into innerHTML. After close, remove the card only when returnValue is confirm, then clear the reference so stale state cannot affect the next interaction.
const board = document.querySelector('#board')
const confirmDialog = document.querySelector('#confirm-dialog')
const confirmName = confirmDialog.querySelector('[data-task-name]')
let pendingTask = null
board.addEventListener('click', event => {
const button = event.target.closest('[data-action=delete]')
if (!button) return
pendingTask = button.closest('[data-task-id]')
confirmName.textContent = pendingTask.querySelector('h2').textContent
confirmDialog.showModal()
})
confirmDialog.addEventListener('close', () => {
if (confirmDialog.returnValue === 'confirm') pendingTask?.remove()
pendingTask = null
})
Confirm deletion on “Write homepage” and only that card should disappear from the DOM.
The confirmation text should name the task and explain the cost. “Delete Write homepage? This cannot be undone” beats a generic “Are you sure?” because the user can verify both target and consequence.
Make the destructive button clear in text, not color alone. Put initial focus on Cancel for an irreversible action. If deletion is reversible, an immediate action plus Undo may beat another modal.
Server deletion can fail after the dialog closes. Treat visible removal as optimistic only when you can restore the card. Otherwise keep it present, mark it busy, wait for success, and show an error outside the closed dialog if the request fails. I keep the dialog markup generic on purpose. The task name and consequence live in normal text nodes you update each time.
Try this on your board: add Delete to several cards, confirm one deletion, cancel another, and open the flow rapidly for different tasks. Verify only the named card changes. If the wrong task disappears, check when pendingTask is assigned and cleared, and block opening a second modal while an operation is active.
Lesson completed