Hi @kevin.hunt,

If you don’t want to be unpleasantly surprised by the Bubble bill, you should avoid refreshing the page every second. Every page load costs WU, just like every workflow that is connected to events such as “page is loaded” or “Do when page is visible”. Such workflows will fire and cost you WU every second, which is a straight route to generating enormous Bubble bills, especially if you have any searches attached to such workflows. Bubble functionality “Do every X seconds” is dedicated to making changes that are purely client-side and only for actions that will not incur any WU.

To have your desired countdown working properly and be sure that your page is loading once, you should:

  1. Put the HTML element on a page (make it 1px x 1px). Let it be visible on page load.
  2. Add inside this HTML the following JavaScript code snippet that will be responsible for counting the time left between your Quiz future date and current date. At the very bottom of the code in “startCountdown()”, insert between brackets your Quiz future date formatted as JSON-safe. The result of the code will be in the following format: (1,2,3,4,5) where: 1 = months left 2 = days left 3 = hours left 4 = minutes left 5 = seconds left Be sure that this code is visible inside this HTML element on the condition that your Quiz future date is not empty (to avoid running code without having a future date).
  3. Put the “JavaScript to Bubble” element (from Toolbox plugin) on a page (make it 1px x 1px). Let it be visible on page load. Element settings: Publish value: checked, Value type: text. In the field “bubble_fn_suffix” add the word “timer”. This element makes JS code results available for you in Bubble. So to see, for example, how many days are left, you will use the following dynamic statement in the text field: JavaScript to Bubble A value: split by (,):item #2. If you’d like to show seconds: JavaScript to Bubble A value: split by (,):item #5. Simple as that.

JS Code

<script>
// Define variables in window scope
window.globalInterval = null;
window.targetDate = null;

function startCountdown(futureDate) {
    // Clear existing interval if any
    if (window.globalInterval) {
        clearInterval(window.globalInterval);
        window.globalInterval = null;
    }

    // Updating target date
    window.targetDate = new Date(futureDate);

    // Function to calculate and display countdown
    function updateCountdown() {
        const currentDate = new Date();
        
        // If future date is in the past or equal to current date
        if (window.targetDate <= currentDate) {
            bubble_fn_timer("0,0,0,0,0");
            clearInterval(window.globalInterval);
            window.globalInterval = null;
            return;
        }

        // Calculating the difference
        const diff = window.targetDate - currentDate;

        // Calculating time components
        const months = Math.floor(diff / (1000 * 60 * 60 * 24 * 30.44));
        const days = Math.floor((diff % (1000 * 60 * 60 * 24 * 30.44)) / (1000 * 60 * 60 * 24));
        const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
        const seconds = Math.floor((diff % (1000 * 60)) / 1000);

        // Publishing the result
        bubble_fn_timer(`${months},${days},${hours},${minutes},${seconds}`);
    }

    // Run immediately
    updateCountdown();

    // Start new interval
    window.globalInterval = setInterval(updateCountdown, 1000);
}

startCountdown(HERE YOUR QUIZ FUTURE DATE FORMATED AS JSON SAFE);

</script>

Enjoy!

Tip: If you’d like to use this solution inside the RG that is showing your Quizzes list, you will need to add such a pair of elements (HTML + “JavaScript to Bubble” element) to every RG row and change “bubble_fn_suffix” from “timer” to “timer_{current cell index}” inside the HTML and in JS code. And of course, your Quiz future date.