Search code examples
javascriptphptailwind-cssdaisyui

Javascript setProperty only seems to works for first element?


I am creating a timer countdown function for a webshop.
Preview:

timer preview

It's using the (Tailwind) DaisyUI countdown element (https://daisyui.com/components/countdown/) and counts down from a dynamic datetime value.

This is working fine for one countdown, but not for multiple on the same page. I've changed all javascript triggers to classes, and created a for-loop for the javascript function, but still only works for the first one found.

What is causing this? Im using the javascript setProperty function to change the time values with a timeout of 1 second. Below my code:


let timerCounter = jQuery('.timer-counter');
    if (typeof timerCounter !== undefined) {
        var datetime = timerCounter.closest('div').find('.timer-item').attr('data-counter-date');
        if (datetime == undefined) {
            return;
        }

        for (let key = 0; key < timerCounter.length; key++) {
            const value = timerCounter[key];
            startTimer(key, datetime);
        }
    }

function startTimer(timerCounter, countDown) {
    var countDownDate = new Date(countDown).getTime();
    var interval = setInterval(function() {

        // Get today's date and time
        var now = new Date().getTime();

        // Find the distance between now and the count down date
        var distance = countDownDate - now;

        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);

        document.querySelector('.timer-hours').style.setProperty('--value', hours);
        document.querySelector('.timer-minutes').style.setProperty('--value', minutes);
        document.querySelector('.timer-seconds').style.setProperty('--value', seconds);

        // If the count down is over, write some text 
        if (distance <= 0) {
            clearInterval(interval);
            location.reload();
        }
    }, 1000);
}

And the PHP component:

<?php
$offset = !empty($args['offset']) ? $args['offset'] : die('offset not definded');
$hours = date_i18n('H', $offset);
$minutes = date_i18n('i', $offset);
$seconds = date_i18n('s', $offset);
$date = date_i18n('Y/m/d H:i:s', $offset);
?>

<div class="timer-item inline-flex flex-col" data-counter-date="<?php echo $date; ?>">
    <span class="text-sm leading-xtight hover:underline text-secondary-900 hover:text-secondary-600"><?php echo __('Shipping today?', 'qore'); ?></span>
    <div class="flex-row flex-wrap items-center justify-start gap-1 font-bold">
        <!-- <span><?php echo __('', 'timer'); ?></span> -->
        <span class="countdown font-mono">
            <span class="timer-hours" style="--value:<?php echo $hours; ?>;"></span>:
            <span class="timer-minutes" style="--value:<?php echo $minutes; ?>;"></span>:
            <span class="timer-seconds" style="--value:<?php echo $seconds; ?>;"></span>
        </span>
        <span><?php echo __('remaining', 'timer') ?></span>
    </div>
</div>

I hope anyone will know the answer for what I am doing wrong.
Thanks in advance!


Solution

  • With some help of ADyson and a small tweak in my code, I managed to get this working.
    I replaced querySelector with querySelectorAll, and have send the correct key in my startTimer function.

    This way I could use:

    document.querySelectorAll('.timer-hours')[key].style.setProperty('--value', hours);
    document.querySelectorAll('.timer-minutes')[key].style.setProperty('--value', minutes);
    document.querySelectorAll('.timer-seconds')[key].style.setProperty('--value', seconds);
    

    Inside my countdown script file.
    Hope this will help others in the future.