A simple countdown clock in vanilla javascript using simple php and Ajax.


#1

I really didn’t know where to put this simple script, but thought this would be the best place to put it. It takes info from a simple php file :
[php]<?php

/* Makes it so we don’t have to decode the json coming from JQuery */
header(‘Content-type: application/json’);

$endDate = filter_input(INPUT_POST, ‘myDate’);

if ($endDate = ‘endDate’) {
$data[‘team’] = “Tigers”;
$home = new DateTime(‘2018-03-29 13:10:00’, new DateTimeZone(“America/Detroit”));
$data[‘home’] = $home->format(“Y-m-d H:i:s”);
$data[‘home_display’] = $home->format(“l - F j, Y”);
$data[‘home_opponent’] = “Pirates”;

$away = new DateTime('2018-04-05 13:10:00', new DateTimeZone("America/Detroit"));
$data['away'] = $away->format("Y-m-d H:i:s");
$data['away'] = $away->format("F j, Y");
$data['away_opponent'] = "White Sox";
output($data);

}
function errorOutput($output, $code = 500) {
http_response_code($code);
echo json_encode($output);
}

/*

  • If everything validates OK then send success message to Ajax / JavaScript
    */

function output($output) {
http_response_code(200);
echo json_encode($output);
}
[/php]

An here is the javascript for the countdown clock:
[php] function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
‘total’: t,
‘days’: days,
‘hours’: hours,
‘minutes’: minutes,
‘seconds’: seconds
};
}

    function initializeClock(id, endtime) {
        var clock = document.getElementById(id);
        var daysSpan = clock.querySelector('.days');
        var hoursSpan = clock.querySelector('.hours');
        var minutesSpan = clock.querySelector('.minutes');
        var secondsSpan = clock.querySelector('.seconds');

        function updateClock() {
            var t = getTimeRemaining(endtime);

            daysSpan.textContent = t.days;
            hoursSpan.textContent = ('0' + t.hours).slice(-2);
            minutesSpan.textContent = ('0' + t.minutes).slice(-2);
            secondsSpan.textContent = ('0' + t.seconds).slice(-2);

            if (t.total <= 0) {
                clearInterval(timeinterval);
            }
        }

        updateClock();
        var timeinterval = setInterval(updateClock, 1000);
    }


    function ajaxRoutine() {
        var grabDate = "myDate=endDate";

        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            //console.log('readyState: ' + xhr.readyState, 'xhr.status: ' + xhr.status);
            if (xhr.readyState === 2) {
                //console.log(xhr.status);
                if (xhr.status === 410) {
                    gameover();
                }
            }
            if (xhr.readyState === 4 && xhr.status === 200) {
                var info = JSON.parse(xhr.responseText);
                console.log('info', info);
                console.log('info.home', info.home);
                var opening_day_home = new Date(Date.parse(info.home));
                var team = info.home_opponent + " -vs- " + info.team;

                document.getElementById("countdown_team").textContent = team;
                document.getElementById("opening").textContent = info.home_display;
                initializeClock('game1', opening_day_home);
                //var opening_day_away = new Date(Date.parse(info.away));
                //initializeClock('game2', opening_day_away);

            }
        }; // End of Ready State:

        xhr.open('POST', 'countdown_date.php', true);
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.send(grabDate);
    }

    ajaxRoutine();[/php]

It uses plain vanilla javascript so there no library that you have to get or utilize and finally some HTML and CSS:
[php]






Days



Hours



Minutes



Seconds


[/php]

[code] article#baseball_countdown {
width: 100%;
max-width: 190px;
height: auto;
position: absolute;
top: 5px;
left: 550px;
}
h1#countdown_team, h2#opening {
font-family: “Palatino Linotype”, “Book Antiqua”, Palatino, serif;
font-size: 1.0em;
line-height: 1.2;
text-align: center;
margin: 0;
}
h2#opening {
font-family: Arial, Helvetica, sans-serif;
font-size: 0.6em;
font-style: italic;
font-weight: 300;
}
div#game1 {
display: block;
width: 100%;
max-width: 220px;
height: auto;
margin: 5px auto;
background-color: pink;
}
div#game1 figure.box {
float: left;
display: block;
width: 100%;
max-width: 40px;
height: 70px;
color: #fff;
text-align: center;
padding: 0;
margin-left: 5px;
}

div#game1 figure.box div {
    background-color: #2e2e2e;
    height: 40px;
    line-height: 40px;
}

div#game1 figure.box figcaption {
    font-family: Arial, Helvetica, sans-serif;

    font-size: 0.6em;
    line-height: 20px;
    font-weight: bold;
    color: #000;
}[/code]

Like I said it’s a very basic countdown counter, but I figure someone might learn a little bit about PHP, Ajax and Javascript. I plan on improving the counter and adding some interesting features in the weeks and months to come. You can see it in action at http://www.pepster.com/index


#2

this will always evaluate to true
[php]if ($endDate = ‘endDate’) {[/php]
Thanks I just did it to prevent an error when trying to run it separately - in other words it’s basically not needed ;D. 0ops, that’s why I always try to put === instead ==


#3

Hey! You edited my post! Scoundrel :stuck_out_tongue:

Anywho, if you want to have fun with javascript I’ve thrown together a little snippet for you. It delves into some more or less new stuff we have to play around with, classes, custom elements, templates, string literals, shadow dom, the fetch api, promises, css grid, etc. glhf :slight_smile:

https://jsfiddle.net/wjghb9qq/

[php]‘use strict’;

class UserList extends HTMLElement {
createdCallback() {
this.createShadowRoot().innerHTML = `

:host {
display: block;
}

    .list {
  display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
    }
    
    user-list-item {
      padding: 1em;
      border: 1px solid #ccc;
    }
    
    user-list-item h4 {
      margin-bottom: 0;
    }
    
    user-list-item span {
      display: block;
    }
  </style>
  <div class="list"></div>
  <template>
  	<user-list-item user=''></user-list-item>
  </template>
`;

this.list = this.shadowRoot.querySelector('.list');
this.template = this.shadowRoot.querySelector('template');
this.updateList();

}

get url() {
return this.getAttribute(‘url’);
}

set url(val) {
this.setAttribute(‘url’, val);
this.updateList();
}

updateList() {
if (!this.url) {
return;
}

return fetch(this.url)
  .then((response) => response.json())
  .then((users) => {
    users.forEach((user) => {
      const item = this.template.content.cloneNode(true);
      item.lastElementChild.setAttribute('user', user.id);
      item.lastElementChild.innerHTML = `<h4>${user.name}</h4>
      <span>${user.email}</span>
      <span>${user.address.suite}, ${user.address.street}</span>
      <span>${user.address.zipcode}</span>`;

      this.list.appendChild(item);
    });
  });

}

}

document.registerElement(‘user-list’, UserList);[/php]

[php]Loading user list…[/php]


#4

Ooops, I meant to quote…this thread is doomed with me making mistakes. LOL ;D