Countdown timer widget

Kristin S_ M_
Kilo Guru

Hi,

I'm looking for a countdown timer widget for the Service Portal. I have found some code online made for html/javascript/css, but am having trouble with encorporating it into a Portal widget. 

HTML:

<div>
<h1>Countdown Clock</h1>
<div id="clockdiv">
  <div>
    <span class="days"></span>
    <div class="smalltext">Days</div>
  </div>
  <div>
    <span class="hours"></span>
    <div class="smalltext">Hours</div>
  </div>
  <div>
    <span class="minutes"></span>
    <div class="smalltext">Minutes</div>
  </div>
  <div>
    <span class="seconds"></span>
    <div class="smalltext">Seconds</div>
  </div>
</div>

</div>

CSS:

body{
	text-align: center;
	background: #00ECB9;
  font-family: sans-serif;
  font-weight: 100;
}

h1{
  color: #396;
  font-weight: 100;
  font-size: 40px;
  margin: 40px 0px 20px;
}

#clockdiv{
	font-family: sans-serif;
	color: #fff;
	display: inline-block;
	font-weight: 100;
	text-align: center;
	font-size: 30px;
}

#clockdiv > div{
	padding: 10px;
	border-radius: 3px;
	background: #00BF96;
	display: inline-block;
}

#clockdiv div > span{
	padding: 15px;
	border-radius: 3px;
	background: #00816A;
	display: inline-block;
}

.smalltext{
	padding-top: 5px;
	font-size: 16px;
}

Server Script/javascript

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.innerHTML = t.days;
    hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
    minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
    secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

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

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

var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
initializeClock('clockdiv', deadline);

Currently it's failing due to the "document" reference in the javascript line 17 as far as I understand from my error messages. 

Optimally, I would like to be able to input the "due date" (where the countdown reaches 0) in Instance Options, but this did not seem intuitive as there is no date variable in the option builder. 

So, my question is: does anybody have a countdown timer code they would be willing to share? Or can anybody help me find out what I need to make this work with existing code?

 

 

 

3 REPLIES 3

Inactive_Us1474
Giga Guru

In order for this code to work, you can put the entire code in the template and using the below template :

<div>
<script>
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.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

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

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

var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
initializeClock('clockdiv', deadline);

</script>
<h1>Countdown Clock</h1>
<div id="clockdiv">
<div>
<span class="days"></span>
<div class="smalltext">Days</div>
</div>
<div>
<span class="hours"></span>
<div class="smalltext">Hours</div>
</div>
<div>
<span class="minutes"></span>
<div class="smalltext">Minutes</div>
</div>
<div>
<span class="seconds"></span>
<div class="smalltext">Seconds</div>
</div>
</div>

</div>

Thanks, I managed to get this to work, and made a few edits.

 

<div>
<div>
 <script>
     
   function getTimeRemaining(endtime) {
   
   
   var dnow = new Date();
     
     //var dnow = data.nows;
   
   //var z = "Europe/Paris"
  //var dnow = new moment().tz(z);
 var t = Date.parse(endtime) - Date.parse(dnow);
 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.innerHTML = t.days;
 hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
 minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
 secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);


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


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

deadline = '2018-06-21 07:00:00';
//var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
initializeClock('clockdiv', deadline);


</script>
  <a ng-href="?id=kb_article&sys_id=1fc4627a1c62d3489c4646981559e915">
<div id="clockdiv">
  <divv>
   Welcome back in  
  </divv>
  <div class="days"></div>
  <div class="smalltext">Days</div>
  <div class="hours"></div>
 <div class="smalltext">Hours</div>
   <div class="minutes"></div>
 <div class="smalltext">Minutes</div>
  <div class="seconds"></div>
 <div class="smalltext">Seconds</div>  
 <!--div>
 <span class="days"></span>
 <div class="smalltext">Days</div>
 </div>
 <div>
 <span class="hours"></span>
 <div class="smalltext">Hours</div>
 </div>
 <div>
 <span class="minutes"></span>
 <div class="smalltext">Minutes</div>
 </div>
 <div>
 <span class="seconds"></span>
 <div class="smalltext">Seconds</div>
 </div-->
</div>
</a>

</div>
</div>

 

However a new problem arose: This works brilliantly in Chrome and Firefox, but fails in Internet Explorer (11), and instead displays "NaN Days, NaN hours etcetc.

As the countdown is on the front page of the end-user portal, getting everyone to migrate to Chrome is not an option. 

Hoping someone will be able to help with a quick fix. If I don't find any other solution by tomorrow I will have to find a workaround by replacing the countdown with just the target date for IE users. Would appreciate tips on how to do that easily as well. 

 

rahulpandey
Kilo Sage

Hi,

 

Please find attached the widget xml, you can import and use it.

About the usage of dynamic variable as options. You can call this widget as below

HTML

<div>
<sp-widget widget="data.countDownWidget"></sp-widget>
</div>

 

Server side code

(function() {
	var deadLine;
var gr = new GlideRecord('table');
if(gr.get('sys_id_of_record/logic'))
deadLine= gr.due_date.dateNumericValue(); // use dateNumericValue() to get time in millisecond
 var countDownWidgetOptions = {"deadLine": deadLine};
    data.countDownWidget = $sp.getWidget('countdown', countDownWidgetOptions);
})();

 

This way, you could use this widget multiple times just by passing deaLine value which is nothing but the value of due_date(any date field) in millisecond. I have attached a working screenshot 🙂