2020-11-23 21:11:09 +01:00
|
|
|
/**
|
|
|
|
* EGroupware eTemplate2 - Countdown timer widget
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package etemplate
|
|
|
|
* @subpackage api
|
|
|
|
* @link http://www.egroupware.org
|
|
|
|
* @author Hadi Nategh
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*egw:uses
|
|
|
|
/vendor/bower-asset/jquery/dist/jquery.js;
|
|
|
|
et2_core_baseWidget;
|
|
|
|
*/
|
|
|
|
|
|
|
|
import './et2_core_common';
|
|
|
|
import {ClassWithAttributes} from "./et2_core_inheritance";
|
|
|
|
import {et2_createWidget, et2_register_widget, WidgetConfig} from "./et2_core_widget";
|
|
|
|
import {et2_date} from "./et2_widget_date";
|
|
|
|
import {et2_baseWidget} from "./et2_core_baseWidget";
|
2021-01-28 11:07:52 +01:00
|
|
|
import {et2_valueWidget} from "./et2_core_valueWidget";
|
2020-11-23 21:11:09 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class which implements the "countdown" XET-Tag
|
2021-01-28 11:07:52 +01:00
|
|
|
*
|
2021-01-28 15:02:38 +01:00
|
|
|
* Value for countdown is the expiry date of the counter or a numeric timeout in seconds.
|
|
|
|
*
|
|
|
|
* The timeout has the benefit, that it does not depend on the correct set time and timezone of the browser / computer of the user.
|
2020-11-23 21:11:09 +01:00
|
|
|
*/
|
2021-01-28 11:07:52 +01:00
|
|
|
export class et2_countdown extends et2_valueWidget {
|
2020-11-23 21:11:09 +01:00
|
|
|
static readonly _attributes: any = {
|
|
|
|
format: {
|
|
|
|
name: "display format",
|
|
|
|
type: "string",
|
|
|
|
default: "s", // s or l
|
|
|
|
description: "Defines display format; s (Initial letter) or l (Complete word) display, default is s."
|
2020-11-24 13:46:05 +01:00
|
|
|
},
|
|
|
|
onFinish: {
|
|
|
|
name: "on finish countdown",
|
|
|
|
type: "js",
|
|
|
|
default: et2_no_init,
|
|
|
|
description: "Callback function to call when the countdown is finished."
|
2020-11-30 14:35:28 +01:00
|
|
|
},
|
|
|
|
hideEmpties: {
|
|
|
|
name: "hide empties",
|
|
|
|
type: "string",
|
|
|
|
default: true,
|
|
|
|
description: "Only displays none empty values."
|
2020-12-02 16:54:50 +01:00
|
|
|
},
|
2021-01-29 19:34:28 +01:00
|
|
|
precision: {
|
|
|
|
name: "how many counters to show",
|
|
|
|
type: "integer",
|
|
|
|
default: 0, // =all
|
|
|
|
description: "Limit number of counters, eg. 2 does not show minutes and seconds, if days are displayed"
|
|
|
|
},
|
2020-12-02 16:54:50 +01:00
|
|
|
alarm: {
|
|
|
|
name: "alarm",
|
|
|
|
type: "any",
|
|
|
|
default: "",
|
|
|
|
description: "Defines an alarm set before the countdown is finished, it should be in seconds"
|
|
|
|
},
|
|
|
|
onAlarm: {
|
|
|
|
name: "alarm callback",
|
|
|
|
type: "js",
|
|
|
|
default: "",
|
|
|
|
description: "Defines a callback to gets called at alarm - timer. This only will work if there's an alarm set."
|
2020-11-23 21:11:09 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
private time : et2_date;
|
|
|
|
|
|
|
|
private timer = null;
|
|
|
|
private container : JQuery = null;
|
|
|
|
private days : JQuery = null;
|
|
|
|
private hours : JQuery = null;
|
|
|
|
private minutes : JQuery = null;
|
|
|
|
private seconds : JQuery = null;
|
2021-01-28 15:02:38 +01:00
|
|
|
private offset;
|
2020-11-23 21:11:09 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
|
|
|
constructor(_parent, _attrs?: WidgetConfig, _child?: object) {
|
|
|
|
// Call the inherited constructor
|
|
|
|
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_countdown._attributes, _child || {}));
|
|
|
|
|
|
|
|
// Build countdown dom container
|
|
|
|
this.container = jQuery(document.createElement("div"))
|
|
|
|
.addClass("et2_countdown");
|
|
|
|
this.days = jQuery(document.createElement("span"))
|
|
|
|
.addClass("et2_countdown_days").appendTo(this.container);
|
|
|
|
this.hours = jQuery(document.createElement("span"))
|
|
|
|
.addClass("et2_countdown_hours").appendTo(this.container);
|
|
|
|
this.minutes = jQuery(document.createElement("span"))
|
|
|
|
.addClass("et2_countdown_minutes").appendTo(this.container);
|
|
|
|
this.seconds = jQuery(document.createElement("span"))
|
|
|
|
.addClass("et2_countdown_seconds").appendTo(this.container);
|
|
|
|
// create a date widget
|
|
|
|
this.time = <et2_date> et2_createWidget('date-time', {});
|
|
|
|
this.setDOMNode(this.container[0]);
|
2021-01-28 15:02:38 +01:00
|
|
|
this.offset = (new Date).getTimezoneOffset();
|
2020-11-23 21:11:09 +01:00
|
|
|
}
|
|
|
|
|
2021-01-28 11:07:52 +01:00
|
|
|
public set_value(_time)
|
2020-11-23 21:11:09 +01:00
|
|
|
{
|
|
|
|
if (_time == "") return;
|
2021-01-28 15:02:38 +01:00
|
|
|
if (!isNaN(_time))
|
|
|
|
{
|
|
|
|
let t = new Date();
|
|
|
|
t.setSeconds(t.getSeconds()+parseInt(_time));
|
|
|
|
_time = t;
|
|
|
|
this.offset = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.offset = (new Date).getTimezoneOffset();
|
|
|
|
}
|
2020-11-23 21:11:09 +01:00
|
|
|
this.time.set_value(_time);
|
|
|
|
let self = this;
|
|
|
|
this.timer = setInterval(function(){
|
2020-11-24 13:46:05 +01:00
|
|
|
if (self._updateTimer() <= 0)
|
|
|
|
{
|
|
|
|
clearInterval(self.timer);
|
|
|
|
if (typeof self.onFinish == "function") self.onFinish();
|
|
|
|
}
|
2020-11-23 21:11:09 +01:00
|
|
|
}, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
private _updateTimer()
|
|
|
|
{
|
|
|
|
let tempDate = new Date();
|
|
|
|
let now = new Date(
|
|
|
|
tempDate.getFullYear(),
|
|
|
|
tempDate.getMonth(),
|
|
|
|
tempDate.getDate(),
|
|
|
|
tempDate.getHours(),
|
2021-01-28 15:02:38 +01:00
|
|
|
tempDate.getMinutes()-this.offset,
|
2020-11-23 21:11:09 +01:00
|
|
|
tempDate.getSeconds()
|
|
|
|
);
|
|
|
|
|
|
|
|
let time = new Date (this.time.getValue());
|
|
|
|
let distance = time.getTime() - now.getTime();
|
|
|
|
|
|
|
|
if (distance < 0) return 0;
|
2020-12-02 16:54:50 +01:00
|
|
|
if (this.options.alarm > 0 && this.options.alarm == distance/1000 && typeof this.onAlarm == 'function')
|
|
|
|
{
|
|
|
|
this.onAlarm();
|
|
|
|
}
|
2020-11-30 14:35:28 +01:00
|
|
|
let values = {
|
|
|
|
days: Math.floor(distance / (1000 * 60 * 60 * 24)),
|
|
|
|
hours: Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
|
|
|
|
minutes: Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)),
|
|
|
|
secounds: Math.floor((distance % (1000 * 60)) / 1000)
|
|
|
|
};
|
|
|
|
|
|
|
|
this.days.text(values.days+this._getIndicator("days"));
|
|
|
|
this.hours.text(values.hours+this._getIndicator("hours"))
|
|
|
|
this.minutes.text(values.minutes+this._getIndicator("minutes"));
|
|
|
|
this.seconds.text(values.secounds+this._getIndicator("seconds"));
|
2020-11-23 21:11:09 +01:00
|
|
|
|
2020-11-30 14:35:28 +01:00
|
|
|
if (this.options.hideEmpties)
|
|
|
|
{
|
|
|
|
if (values.days == 0)
|
|
|
|
{
|
|
|
|
this.days.hide();
|
|
|
|
if(values.hours == 0)
|
|
|
|
{
|
|
|
|
this.hours.hide();
|
|
|
|
if(values.minutes == 0)
|
|
|
|
{
|
|
|
|
this.minutes.hide();
|
|
|
|
if(values.secounds == 0) this.seconds.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-29 19:34:28 +01:00
|
|
|
if (this.options.precision)
|
|
|
|
{
|
|
|
|
const units = ['days','hours','minutes','seconds'];
|
|
|
|
for (let u=0; u < 4; ++u)
|
|
|
|
{
|
|
|
|
if (values[units[u]])
|
|
|
|
{
|
|
|
|
for(let n=u+this.options.precision; n < 4; n++)
|
|
|
|
{
|
|
|
|
this[units[n]].hide();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this[units[u]].hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-23 21:11:09 +01:00
|
|
|
return distance;
|
|
|
|
}
|
|
|
|
|
|
|
|
private _getIndicator(_v)
|
|
|
|
{
|
|
|
|
return this.options.format == 's' ? egw.lang(_v).substr(0,1) : egw.lang(_v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
et2_register_widget(et2_countdown, ["countdown"]);
|