import BaseField from './BaseField';
import DateTimePickerField from './DateTimePickerField';
import { __ } from '@devoinc/applications-builder/i18n';
import dateRange from '../utils/dateRange';
/**
*
* @param id {string} Id of the HTML element of the widget
* @param key {string} Key to use when saving to datanode
* @param customPropsFrom {Object} Custom properties for from DateTimeWidget
* @param customPropsTo {Object} Custom properties for to DateTimeWidget
* @param timepicker {boolean} If True the DatePickers will allow hour and minute selection
* @param apply {Function} function executed when the state changes
* @param dataNode {DataNode} DataNode where state will be saved on save()
*
* @category Fields
* @class
* Allows to select a date range from two date time pickers.
* @extends BaseField
*/
class DateTimePickerRangeField extends BaseField {
constructor(props = {}) {
let now = Date.now();
props = Object.assign(
{
id: null,
template: `<div class="lt-date-time-picker-field">
<label><strong>${__('FROM: ')}</strong></label>
<div id="{{id}}_from"></div>
</div>
<div class="lt-date-time-picker-field">
<label><strong>${__('TO: ')}</strong></label>
<div id="{{id}}_to"></div>
</div>`,
class: 'lt-date-time-picker-range-field',
props: [{}, {}],
timepicker: false,
default: {
from: now - 24 * 60 * 60 * 1000,
to: now,
},
value: { from: 0, to: 0 },
dtPickers: { from: null, to: null },
},
props
);
super(props);
if (!this.el) return undefined;
return this;
}
/**
* Updates the component view / DOM representation on state change
* @override
*/
setDOM() {}
setDefault() {
if (this.default !== null) {
this._setValue(this.default);
}
}
/**
* Sets the value state programmatically.
* @param dates
* @override
*/
setValue(dates) {
this._setValue(dates);
this.setDOM(); // update component view
}
_setValue(dates) {
if (!dates) return;
// Capture wrong dates
if (dates.from > dates.to || dates.to > Date.now()) {
throw new Error(__('Wrong dates'));
}
// Update child component's values
const sides = Object.keys(this.dtPickers);
for (let side of sides) {
if (this.dtPickers[side]) this.dtPickers[side].setValue(dates[side]);
}
this.value = dates;
}
/**
* Builds the DOM representation (view) on initialization.
* @override
*/
buildDOM() {
if (this.class) this.el.classList.add(this.class);
const re = new RegExp('{{id}}', 'gi');
this.el.innerHTML = this.template.replace(re, this.getCleanId());
const sides = Object.keys(this.dtPickers);
for (let i = 0; i < sides.length; i++) {
let side = sides[i];
this.dtPickers[side] = new DateTimePickerField(
Object.assign(
{
id: `#${this.getCleanId()}_${side}`,
default: this.default[side],
timepicker: this.timepicker,
onChange: (value) => {
this.value[side] = value;
if (this.onChange) this.onChange(this.value);
},
},
this.props[i]
)
);
}
this.dtPickers.from.sibilings = [null, this.dtPickers.to];
this.dtPickers.to.sibilings = [this.dtPickers.from, null];
}
highlight() {
if (this.dtPickers) {
const sides = Object.keys(this.dtPickers);
for (let side of sides) {
if (this.dtPickers[side]) this.dtPickers[side].highlight();
}
}
}
/**
* Updates the end of the date range to the current time
*/
refresh() {
let current = this.value;
let oldTo = current.to;
current.to = moment().valueOf();
current.from = current.from + (current.to - oldTo);
this._setValue(current);
this.onChange(this.value);
}
}
export default DateTimePickerRangeField;
Source