@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
184 lines (183 loc) • 6.56 kB
JavaScript
import GirafeHTMLElement from '../../../base/GirafeHTMLElement';
import LayerTimeFormatter from '../../../tools/time/layertimeformatter';
import { debounce } from '../../../tools/utils/debounce';
export const TimeChangeEvent = 'timeChange';
/**
* The `TimeWidget` class is a custom HTML element used to manage and display a time range or time value
* through one or two sliders or date pickers. It supports two modes (`range` or `value`) and returns
* date strings formatted according to the specified time resolution and mode.
* The initialize method needs to be called first to configure the widget with an object of type ITimeOptions.
*
* This class must be extended, since it doesn't have a template of its own.
*/
class TimeWidget extends GirafeHTMLElement {
constructor(name) {
super(name);
Object.defineProperty(this, "lowerInputElem", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "upperInputElem", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "timeFormatter", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "resolution", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "mode", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "minValue", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "maxValue", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "minDefaultValue", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "maxDefaultValue", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "debounceTime", {
enumerable: true,
configurable: true,
writable: true,
value: 500
});
Object.defineProperty(this, "timeChangeEventDebounced", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
}
/**
* Initializes the widget and sets properties of the input elements. Must be called before using the widget.
*
* @param {ITimeOptions} timeOptions - Configuration options for the time widget.
*/
initialize(timeOptions) {
this.timeFormatter = new LayerTimeFormatter(timeOptions);
this.resolution = this.timeFormatter.resolution;
this.mode = this.timeFormatter.mode;
this.minValue = this.timeFormatter.minValue;
this.maxValue = this.timeFormatter.maxValue;
// Optional, initial time restriction. These values already have been applied to the layer when it was initialized.
this.minDefaultValue = this.timeFormatter.formatDateString(timeOptions.minDefValue ?? '');
this.maxDefaultValue = this.timeFormatter.formatDateString(timeOptions.maxDefValue ?? '');
}
render() {
if (!this.mode) {
// If not initialized, the component can't be displayed
this.renderEmpty();
}
else if (!this.rendered) {
this.renderComponent();
}
else {
super.render();
super.girafeTranslate();
}
}
renderComponent() {
super.render();
this.lowerInputElem = this.getById('input-lower');
this.upperInputElem = this.getById('input-upper');
}
getInputElement(limit) {
if (limit === 'upper' && this.mode === 'range') {
return this.upperInputElem;
}
else {
return this.lowerInputElem;
}
}
/**
* Retrieves the value associated with the input element of the specified limit.
*
* @param {TimeRangeLimit} [limit] - Optional parameter specifying the input Element ('upper' or 'lower')
* for which value is to be fetched.
* @return {string} The raw value retrieved from the input element.
*/
getValue(limit) {
if (limit === 'upper' && this.mode === 'value')
return '';
return this.getInputElement(limit).value;
}
/**
* Get the current time restriction as a formatted query string.
*
* @return {string | undefined} The formatted time restriction as string or undefined if the time restriction is empty.
*
*/
getTimeRestriction() {
let newTime = '';
const lower = this.getValue('lower');
const upper = this.getValue('upper');
if (this.mode === 'value') {
newTime = this.timeFormatter.formatDateString(lower);
}
else {
newTime = this.timeFormatter.formatTimeRange(lower, upper);
}
return newTime === '' ? undefined : newTime;
}
/**
* Dispatches a custom event to notify the parent about the changed time.
*
* @param {boolean} unset - Set the time restriction to undefined.
*/
createTimeChangeEvent(unset = false) {
this.dispatchEvent(new CustomEvent(TimeChangeEvent, {
bubbles: true,
cancelable: true,
detail: unset ? undefined : this.getTimeRestriction()
}));
}
/**
* Dispatches a debounced time change event to prevent frequent server calls.
*
* @param {boolean} [unset=false] - Indicates whether the time will be set to undefined.
*/
dispatchTimeChangeEvent(unset = false) {
// Debounce the time change event to limit server calls
this.timeChangeEventDebounced ??= debounce(this.createTimeChangeEvent, this.debounceTime);
this.timeChangeEventDebounced(unset);
}
connectedCallback() {
this.loadConfig().then(() => {
this.render();
super.girafeTranslate();
});
}
}
export default TimeWidget;