Skip to content
Snippets Groups Projects

Reworked countdown to use JS for counting

Open Alexander Bukach requested to merge issue/countdown-796110:8.x-1.x into 8.x-1.x
Files
5
+ 84
75
var _countdown_accuracy, _countdown_freq, _countdown_interval, _countdown_direction, _countdown_this;
function init_countdown(accuracy) {
_countdown_accuracy = String('dhms').indexOf(accuracy);
_countdown_interval = [24, 60, 60, 1];
_countdown_freq = [86400, 3600, 60, 1];
_countdown_direction = -1;
}
function countUp() {
_countdown_this.objDirText.nodeValue = _countdown_this.objDirText.nodeValue.replace(' until', ' since');
_countdown_direction = 1;
_countdown_this.initTime[0] = 0;
_countdown_this.initTime[1] = 0;
_countdown_this.initTime[2] = 0;
_countdown_this.initTime[3] = 0;
_countdown_this.objEM[0].innerHTML = String('0');
_countdown_this.objEM[1].innerHTML = String('0');
_countdown_this.objEM[2].innerHTML = String('0');
_countdown_this.objEM[3].innerHTML = String('0');
}
jQuery.fn.extend({
onready: function () {
return this.each(function () {
this.objEM = new Array();
this.initTime = new Array();
for (i = 0; i < this.childNodes.length; i++) {
thisChild = this.childNodes.item(i);
if (thisChild.tagName == 'EM') {
this.objEM[this.objEM.length] = thisChild;
this.initTime[this.initTime.length] = parseInt(thisChild.innerHTML);
} else if (thisChild.nodeName == '#text') {
if (thisChild.nodeValue.indexOf(' since') >= 0) {
_countdown_direction = 1;
this.objDirText = thisChild;
} else if (thisChild.nodeValue.indexOf(' until') >= 0) {
this.objDirText = thisChild;
}
(function ($, Drupal) {
Drupal.behaviors.countdown = {
attach: function (context, settings) {
function calculateTimeRemaining(targetTimestamp) {
const currentTime = Date.now(); // Get the current time in milliseconds
const timeDifference = targetTimestamp - currentTime; // Calculate the time difference
if (timeDifference <= 0) {
return {
days: 0, hours: 0, minutes: 0, seconds: 0,
};
}
// Calculate days, hours, minutes, and seconds
const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
const hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((timeDifference % (1000 * 60)) / 1000);
return {
days: days, hours: hours, minutes: minutes, seconds: seconds,
};
}
function getIntervalInMilliseconds(frequency) {
switch (frequency) {
case 'd':
return 3600000;
case 'h':
return 60000;
case 'm':
return 1000;
case 's':
return 200;
default:
return 60000;
}
}
function formatRemainingTime(timeObject, accuracy) {
const { days, hours, minutes, seconds } = timeObject;
const parts = [];
// Add each non-zero part to the parts array with translatable strings using Drupal.t()
if (days !== 0) {
parts.push(Drupal.t('@days days', { '@days': days }));
}
if ((days !== 0 || hours !== 0) && (accuracy === 'h' || accuracy === 'm' || accuracy === 's')) {
parts.push(Drupal.t('@hours hours', { '@hours': hours }));
}
if ((days !== 0 || hours !== 0 || minutes !== 0) && (accuracy === 'm' || accuracy === 's')) {
parts.push(Drupal.t('@minutes minutes', { '@minutes': minutes }));
}
if ((days !== 0 || hours !== 0 || minutes !== 0 || seconds !== 0) && accuracy === 's') {
parts.push(Drupal.t('@seconds seconds', { '@seconds': seconds }));
}
// Join the parts into a single string separated by commas
return parts.join(', ');
}
_countdown_this = this;
setInterval(function () {
more = 1;
for (accuracy = _countdown_accuracy; accuracy >= 0 && more; accuracy--) {
value = _countdown_this.initTime[accuracy];
if (_countdown_direction == 1) {
if (accuracy > 0 && value >= _countdown_interval[accuracy - 1] - 1) {
newValue = 0;
} else {
newValue = value + 1;
more = 0;
}
$(once('countdown', '.countdown-wrapper')).each(function () {
var $element = $(this);
var settings = drupalSettings.countdown[$element.attr('id')];
function updateText() {
const timeRemaining = calculateTimeRemaining(settings.timestamp * 1000);
var message;
if (timeRemaining.days <= 0 && timeRemaining.hours <= 0 && timeRemaining.minutes <= 0 && timeRemaining.seconds <= 0) {
message = '@time since @event';
} else {
if (value) {
newValue = value - 1;
more = 0;
} else if (accuracy == 0) {
countUp();
accuracy = _countdown_accuracy + 1;
continue;
} else {
newValue = _countdown_interval[accuracy - 1] - 1;
}
message = '@time until @event';
}
_countdown_this.initTime[accuracy] = newValue;
_countdown_this.objEM[accuracy].innerHTML = String(newValue);
var text = Drupal.t(message, {
'@time': formatRemainingTime(timeRemaining, settings.accuracy),
'@event': settings.event,
});
$element.text(text);
}
}, _countdown_freq[_countdown_accuracy] * 1000);
});
}
});
(function ($, Drupal) {
Drupal.behaviors.countdown = {
attach: function (context, settings) {
if (drupalSettings.countdown.countdownblock.accuracy != 'd') {
init_countdown(drupalSettings.countdown.countdownblock.accuracy);
$("#block-countdown .block__content").onready();
}
}
updateText();
setInterval(updateText, getIntervalInMilliseconds(settings.accuracy));
});
},
};
})(jQuery, Drupal);
Loading