salix/client/core/src/datePicker/datePicker.js

194 lines
6.4 KiB
JavaScript
Raw Normal View History

2017-07-12 11:32:25 +00:00
import {module} from '../module';
import Component from '../lib/component';
import Flatpickr from 'vendor/src/flatpickr';
import './style.scss';
// equivalences to format date between flatpicker and angularjs
2017-09-19 13:03:39 +00:00
export const formatEquivalence = {
2017-07-12 11:32:25 +00:00
d: 'dd', // Day of the month, 2 digits with leading zeros (01 to 31)
j: 'd', // Day of the month without leading zeros (1 to 31)
m: 'MM', // Month in year, padded (01-12)
n: 'M', // Month in year (1-12)
y: 'yy', // A two digit representation of a year (00-99)
Y: 'yyyy', // A full numeric representation of a year, 4 digits (1999 or 2003)
H: 'HH', // Hour in AM/PM, padded (01-12)
h: 'H', // Hour in AM/PM, (1-12)
i: 'mm', // Minutes (00 to 59)
s: 'ss' // Seconds (00 to 59)
};
class DatePicker extends Component {
2017-07-12 12:32:15 +00:00
constructor($element, $translate, $filter, $timeout) {
2017-07-12 11:32:25 +00:00
super($element);
this.input = $element[0].querySelector('input');
this.$translate = $translate;
this.$filter = $filter;
2017-07-12 12:32:15 +00:00
this.$timeout = $timeout;
2017-07-12 11:32:25 +00:00
this.enabled = true;
2017-07-13 11:12:09 +00:00
this._modelView = null;
2017-07-12 11:32:25 +00:00
this._model = undefined;
2017-10-31 09:40:12 +00:00
this._optionsChecked = false;
2017-11-02 07:18:37 +00:00
this.hasFocus = false;
this.hasMouseIn = false;
componentHandler.upgradeElement($element[0].firstChild);
2017-07-12 11:32:25 +00:00
}
get model() {
return this._model;
}
set model(value) {
this._model = value;
if (value && !this.modelView) {
2017-10-31 08:44:24 +00:00
let options = this._getOptions();
let initialDateFormat = (options && options.dateFormat) ? options.dateFormat : 'Y-m-d';
2017-10-11 12:21:32 +00:00
let format = this._formatFlat2Angular(initialDateFormat);
2017-07-12 11:32:25 +00:00
this.modelView = this.$filter('date')(value, format);
}
}
get modelView() {
return this._modelView;
}
set modelView(value) {
this._modelView = value;
this.input.value = value;
2017-07-12 11:32:25 +00:00
this._setModel(value);
2017-10-03 12:41:35 +00:00
this.$timeout(() => {
this.mdlUpdate();
}, 500);
2017-07-12 11:32:25 +00:00
}
onClear() {
this.modelView = null;
2017-07-12 11:32:25 +00:00
}
mdlUpdate() {
let mdlField = this.element.firstChild.MaterialTextfield;
if (mdlField)
mdlField.updateClasses_();
}
_formatFlat2Angular(string) { // change string Flatpickr format to angular format (d-m-Y -> dd-MM-yyyy)
let aux = string.split(/[ZT.,/ :-]/);
2017-07-12 11:32:25 +00:00
let parts = [];
aux.forEach(
val => {
2017-09-19 13:03:39 +00:00
parts.push(formatEquivalence[val]);
2017-07-12 11:32:25 +00:00
}
);
2017-07-13 11:12:09 +00:00
if (string.indexOf(' ') !== -1 || string.indexOf('T') !== -1) { // datetime format
2017-07-12 11:32:25 +00:00
let dates = parts.slice(0, 3).join('-');
let hours = parts.slice(3, parts.length).join(':');
return `${dates} ${hours}`.trim();
} else if (string.indexOf(':') !== -1) { // only time format
return parts.join(':');
2017-10-03 12:41:35 +00:00
} // only date format
return parts.join('-');
2017-07-12 11:32:25 +00:00
}
_setModel(value) {
2017-07-12 12:32:15 +00:00
let model;
2017-07-12 11:32:25 +00:00
if (!value) {
2017-07-12 12:32:15 +00:00
model = undefined;
2017-10-11 12:21:32 +00:00
} else if (!this.iniOptions || (this.iniOptions.dateFormat && this.iniOptions.dateFormat.startsWith('Y-m-d'))) {
2017-07-12 12:32:15 +00:00
model = value;
2017-07-12 11:32:25 +00:00
} else {
let formats = this.iniOptions.dateFormat.split(/[ZT.,/ :-]/);
let aux = value.split(/[ZT.,/ :-]/);
2017-07-12 11:32:25 +00:00
let date = {};
formats.forEach(
(k, i) => {
if (k.toLowerCase() === 'y') {
date.year = aux[i];
} else if (k === 'm' || k === 'n') {
date.month = aux[i];
} else if (k === 'd' || k === 'j') {
date.day = aux[i];
} else if (k.toLowerCase() === 'h') {
date.hour = aux[i];
} else if (k === 'i') {
date.minutes = aux[i];
} else if (k === 's') {
date.seccons = aux[i];
}
}
);
let dateStr = '';
let hourStr = '';
if (date.year && date.month && date.day) {
dateStr = `${date.year}-${date.month}-${date.day}`;
}
if (date.hour) {
hourStr = date.hour;
if (date.minutes) {
hourStr += ':' + date.minutes;
} else {
hourStr += ':00';
}
if (date.seccons) {
hourStr += ':' + date.seccons;
} else {
hourStr += ':00';
}
}
2017-07-12 12:32:15 +00:00
model = `${dateStr} ${hourStr}`.trim();
2017-07-13 06:58:48 +00:00
}
2017-07-12 12:32:15 +00:00
2017-07-12 12:57:40 +00:00
if (this.model !== model) {
this.model = model;
}
2017-07-12 11:32:25 +00:00
}
2017-10-31 08:44:24 +00:00
_getOptions() {
2017-10-31 09:40:12 +00:00
if (this.iniOptions && this._optionsChecked) {
2017-10-31 08:44:24 +00:00
return this.iniOptions;
2017-10-31 09:40:12 +00:00
} else if (!this.iniOptions) {
this.iniOptions = {};
2017-10-31 08:44:24 +00:00
}
2017-07-12 11:32:25 +00:00
2017-10-31 09:40:12 +00:00
if (!this.iniOptions.locale)
this.iniOptions.locale = this.$translate.use();
2017-07-12 11:32:25 +00:00
2017-10-31 09:40:12 +00:00
if (!this.iniOptions.dateFormat && this.iniOptions.locale === 'es')
this.iniOptions.dateFormat = 'd-m-Y';
else if (this.iniOptions.dateFormat) {
let format = this.iniOptions.dateFormat.split(/[ZT.,/ :-]/);
if (format.length <= 1) {
throw new Error(`Error: Invalid string format ${format}`);
}
format.forEach(
val => {
2017-09-19 13:03:39 +00:00
if (!formatEquivalence[val]) {
2017-10-31 09:40:12 +00:00
throw new Error(`Error in dateFormat ${this.iniOptions.dateFormat}: is not like Flatpickr Formatting Token https://chmln.github.io/flatpickr/formatting/`);
}
}
);
}
2017-10-31 09:40:12 +00:00
this._optionsChecked = true;
return this.iniOptions;
2017-10-31 08:44:24 +00:00
}
$onInit() {
this.iniOptions = this._getOptions();
2017-11-02 07:18:37 +00:00
this.isTimePicker = (this.iniOptions && this.iniOptions.enableTime && this.iniOptions.noCalendar);
2017-10-31 08:44:24 +00:00
this.vp = new Flatpickr(this.input, this.iniOptions);
2017-07-12 11:32:25 +00:00
}
$onDestroy() {
if (this.vp)
this.vp.destroy();
}
}
2017-07-12 12:32:15 +00:00
DatePicker.$inject = ['$element', '$translate', '$filter', '$timeout'];
2017-07-12 11:32:25 +00:00
module.component('vnDatePicker', {
template: require('./datePicker.html'),
bindings: {
model: '=',
label: '@?',
name: '@?',
enabled: '<?',
rule: '<?',
iniOptions: '<?'
2017-07-12 11:32:25 +00:00
},
controller: DatePicker
});