1 "Mark All As Present" Button for Attendance Tracking Shared by Hadley Sutherland, Centre Street Church 24 days ago 15.1 Check-in, Group, Small Groups Beginner Why This is Helpful Staff have shared that it’s easier to deselect absentees rather than manually selecting everyone who is present. How It Works This recipe adds a "Mark All As Present" button to the attendance page, allowing staff to mark everyone as attended with one click and then simply uncheck those who are absent. "Confirm" Marks all attendees as present. Setup 1️⃣ Go to a "Group Attendance Detail" block settings. 2️⃣ Navigate to Advanced Settings > Pre-HTML. Paste This Code Copy and paste the following code into the Pre-HTML section: <script> function insertMarkAllPresentButton() { let targetContainer = document.querySelector(".col-xs-12.col-sm-8.d-sm-flex") || document.querySelector(".did-attend-filter .btn-group"); if (targetContainer && !document.getElementById("mark-all-present-group")) { let searchFilter = targetContainer.querySelector(".search-filter"); // Create the btn-group wrapper for correct styling let btnGroup = document.createElement("div"); btnGroup.className = "btn-group"; btnGroup.id = "mark-all-present-group"; // Unique ID to prevent duplication btnGroup.style.marginLeft = "8px"; // Keep spacing consistent // Create "Mark All As Present" button inside btn-group let markAllBtn = document.createElement("button"); markAllBtn.id = "mark-all-present"; markAllBtn.className = "btn btn-primary"; markAllBtn.type = "button"; markAllBtn.textContent = "Mark All As Present"; // Append button to btn-group btnGroup.appendChild(markAllBtn); // Insert the btn-group before search filter (or at the end if missing) if (searchFilter) { targetContainer.insertBefore(btnGroup, searchFilter); } else { targetContainer.appendChild(btnGroup); } // Auto-adjust button width setTimeout(() => { btnGroup.style.width = markAllBtn.offsetWidth + "px"; }, 50); // Add click event for "Mark All As Present" markAllBtn.addEventListener("click", function(event) { event.preventDefault(); event.stopPropagation(); // Get the width of the button before hiding it let buttonWidth = btnGroup.offsetWidth; btnGroup.style.width = buttonWidth + "px"; // Keep button width consistent // Hide original button markAllBtn.style.display = "none"; // Create Confirm and Cancel buttons inside btn-group let confirmBtn = document.createElement("button"); confirmBtn.textContent = "Confirm"; confirmBtn.className = "btn btn-success"; confirmBtn.type = "button"; confirmBtn.style.flex = "1"; let cancelBtn = document.createElement("button"); cancelBtn.textContent = "Cancel"; cancelBtn.className = "btn btn-danger"; cancelBtn.type = "button"; cancelBtn.style.flex = "1"; // Preserve `.btn-group` structure and replace only the button btnGroup.innerHTML = ""; btnGroup.appendChild(confirmBtn); btnGroup.appendChild(cancelBtn); // Confirm button selects checkboxes confirmBtn.addEventListener("click", function() { document.querySelectorAll(".checkbox-card input[type='checkbox']").forEach(checkbox => { if (!checkbox.checked) { checkbox.click(); } }); resetButtons(); }); // Cancel button just restores "Mark All As Present" cancelBtn.addEventListener("click", function() { resetButtons(); }); // Restore original button function resetButtons() { btnGroup.innerHTML = ""; btnGroup.appendChild(markAllBtn); markAllBtn.style.display = "inline-block"; btnGroup.style.width = ""; // Reset width for dynamic sizing } }); return true; } return false; } // Use MutationObserver to detect when the target container appears dynamically const observer = new MutationObserver(() => { if (insertMarkAllPresentButton()) { observer.disconnect(); // Stop observing once inserted } }); // Start observing changes in the document body observer.observe(document.body, { childList: true, subtree: true }); </script>