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 export const fromatEquivalence = { 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 { constructor($element, $translate, $filter, $timeout) { super($element); this.input = $element[0].querySelector('input'); this.$translate = $translate; this.$filter = $filter; this.$timeout = $timeout; this.enabled = true; this._modelView = null; this._model = undefined; componentHandler.upgradeElement($element[0].firstChild); } get model() { return this._model; } set model(value) { this._model = value; if (value && !this.modelView) { let format = this._formatFlat2Angular(this.iniOptions.dateFormat || 'Y-m-d'); this.modelView = this.$filter('date')(value, format); } } get modelView() { return this._modelView; } set modelView(value) { this._modelView = value; this.input.value = value; this._setModel(value); this.$timeout( () => { this.mdlUpdate(); }, 500); } onClear() { this.modelView = null; } 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.,/ :-]/); let parts = []; aux.forEach( val => { parts.push(fromatEquivalence[val]); } ); if (string.indexOf(' ') !== -1 || string.indexOf('T') !== -1) { // datetime format 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(':'); } else { // only date format return parts.join('-'); } } _setModel(value) { let model; if (!value) { model = undefined; } else if (!this.iniOptions.dateFormat || (this.iniOptions.dateFormat && this.iniOptions.dateFormat.startsWith('Y-m-d'))) { model = value; } else { let formats = this.iniOptions.dateFormat.split(/[ZT.,/ :-]/); let aux = value.split(/[ZT.,/ :-]/); 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'; } } model = `${dateStr} ${hourStr}`.trim(); } if (this.model !== model) { this.model = model; } } $onInit() { if (!this.iniOptions) this.iniOptions = {}; if (!this.iniOptions.locale) this.iniOptions.locale = this.$translate.use(); 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 => { if (!fromatEquivalence[val]) { throw new Error(`Error in dateFormat ${this.iniOptions.dateFormat}: is not like Flatpickr Formatting Token https://chmln.github.io/flatpickr/formatting/`); } } ); } if (this.input) this.vp = new Flatpickr(this.input, this.iniOptions); } $onDestroy() { if (this.vp) this.vp.destroy(); } } DatePicker.$inject = ['$element', '$translate', '$filter', '$timeout']; module.component('vnDatePicker', { template: require('./datePicker.html'), bindings: { model: '=', label: '@?', name: '@?', enabled: '