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-07-13 09:03:22 +00:00
|
|
|
|
|
|
|
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;
|
2017-07-13 09:03:22 +00:00
|
|
|
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();
|
2017-07-13 09:03:22 +00:00
|
|
|
}, 500);
|
2017-07-12 11:32:25 +00:00
|
|
|
}
|
|
|
|
onClear() {
|
2017-07-13 09:03:22 +00:00
|
|
|
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)
|
2017-07-13 09:03:22 +00:00
|
|
|
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 {
|
2017-07-13 09:03:22 +00:00
|
|
|
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() {
|
|
|
|
if (this.iniOptions) {
|
|
|
|
return this.iniOptions;
|
|
|
|
}
|
2017-07-12 11:32:25 +00:00
|
|
|
|
2017-10-31 08:44:24 +00:00
|
|
|
let iniOptions = {};
|
|
|
|
if (!iniOptions.locale)
|
|
|
|
iniOptions.locale = this.$translate.use();
|
2017-07-12 11:32:25 +00:00
|
|
|
|
2017-10-31 08:44:24 +00:00
|
|
|
if (!iniOptions.dateFormat && iniOptions.locale === 'es')
|
|
|
|
iniOptions.dateFormat = 'd-m-Y';
|
|
|
|
else if (iniOptions.dateFormat) {
|
|
|
|
let format = iniOptions.dateFormat.split(/[ZT.,/ :-]/);
|
2017-07-13 09:03:22 +00:00
|
|
|
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 08:44:24 +00:00
|
|
|
throw new Error(`Error in dateFormat ${iniOptions.dateFormat}: is not like Flatpickr Formatting Token https://chmln.github.io/flatpickr/formatting/`);
|
2017-07-13 09:03:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2017-10-31 08:44:24 +00:00
|
|
|
return iniOptions;
|
|
|
|
}
|
|
|
|
|
|
|
|
$onInit() {
|
|
|
|
this.iniOptions = this._getOptions();
|
2017-07-12 11:32:25 +00:00
|
|
|
|
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: '<?',
|
2017-07-13 09:03:22 +00:00
|
|
|
iniOptions: '<?'
|
2017-07-12 11:32:25 +00:00
|
|
|
},
|
|
|
|
controller: DatePicker
|
|
|
|
});
|