148 lines
3.7 KiB
JavaScript
148 lines
3.7 KiB
JavaScript
import MaskedPattern from './pattern.js';
|
|
import MaskedRange from './range.js';
|
|
import IMask from '../core/holder.js';
|
|
import { isString } from '../core/utils.js';
|
|
import '../core/change-details.js';
|
|
import './base.js';
|
|
import '../core/continuous-tail-details.js';
|
|
import './factory.js';
|
|
import './pattern/chunk-tail-details.js';
|
|
import './pattern/cursor.js';
|
|
import './pattern/fixed-definition.js';
|
|
import './pattern/input-definition.js';
|
|
import './regexp.js';
|
|
|
|
const DefaultPattern = 'd{.}`m{.}`Y';
|
|
|
|
// Make format and parse required when pattern is provided
|
|
|
|
/** Date mask */
|
|
class MaskedDate extends MaskedPattern {
|
|
static extractPatternOptions(opts) {
|
|
const {
|
|
mask,
|
|
pattern,
|
|
...patternOpts
|
|
} = opts;
|
|
return {
|
|
...patternOpts,
|
|
mask: isString(mask) ? mask : pattern
|
|
};
|
|
}
|
|
|
|
/** Pattern mask for date according to {@link MaskedDate#format} */
|
|
|
|
/** Start date */
|
|
|
|
/** End date */
|
|
|
|
/** Format typed value to string */
|
|
|
|
/** Parse string to get typed value */
|
|
|
|
constructor(opts) {
|
|
super(MaskedDate.extractPatternOptions({
|
|
...MaskedDate.DEFAULTS,
|
|
...opts
|
|
}));
|
|
}
|
|
updateOptions(opts) {
|
|
super.updateOptions(opts);
|
|
}
|
|
_update(opts) {
|
|
const {
|
|
mask,
|
|
pattern,
|
|
blocks,
|
|
...patternOpts
|
|
} = {
|
|
...MaskedDate.DEFAULTS,
|
|
...opts
|
|
};
|
|
const patternBlocks = Object.assign({}, MaskedDate.GET_DEFAULT_BLOCKS());
|
|
// adjust year block
|
|
if (opts.min) patternBlocks.Y.from = opts.min.getFullYear();
|
|
if (opts.max) patternBlocks.Y.to = opts.max.getFullYear();
|
|
if (opts.min && opts.max && patternBlocks.Y.from === patternBlocks.Y.to) {
|
|
patternBlocks.m.from = opts.min.getMonth() + 1;
|
|
patternBlocks.m.to = opts.max.getMonth() + 1;
|
|
if (patternBlocks.m.from === patternBlocks.m.to) {
|
|
patternBlocks.d.from = opts.min.getDate();
|
|
patternBlocks.d.to = opts.max.getDate();
|
|
}
|
|
}
|
|
Object.assign(patternBlocks, this.blocks, blocks);
|
|
super._update({
|
|
...patternOpts,
|
|
mask: isString(mask) ? mask : pattern,
|
|
blocks: patternBlocks
|
|
});
|
|
}
|
|
doValidate(flags) {
|
|
const date = this.date;
|
|
return super.doValidate(flags) && (!this.isComplete || this.isDateExist(this.value) && date != null && (this.min == null || this.min <= date) && (this.max == null || date <= this.max));
|
|
}
|
|
|
|
/** Checks if date is exists */
|
|
isDateExist(str) {
|
|
return this.format(this.parse(str, this), this).indexOf(str) >= 0;
|
|
}
|
|
|
|
/** Parsed Date */
|
|
get date() {
|
|
return this.typedValue;
|
|
}
|
|
set date(date) {
|
|
this.typedValue = date;
|
|
}
|
|
get typedValue() {
|
|
return this.isComplete ? super.typedValue : null;
|
|
}
|
|
set typedValue(value) {
|
|
super.typedValue = value;
|
|
}
|
|
maskEquals(mask) {
|
|
return mask === Date || super.maskEquals(mask);
|
|
}
|
|
optionsIsChanged(opts) {
|
|
return super.optionsIsChanged(MaskedDate.extractPatternOptions(opts));
|
|
}
|
|
}
|
|
MaskedDate.GET_DEFAULT_BLOCKS = () => ({
|
|
d: {
|
|
mask: MaskedRange,
|
|
from: 1,
|
|
to: 31,
|
|
maxLength: 2
|
|
},
|
|
m: {
|
|
mask: MaskedRange,
|
|
from: 1,
|
|
to: 12,
|
|
maxLength: 2
|
|
},
|
|
Y: {
|
|
mask: MaskedRange,
|
|
from: 1900,
|
|
to: 9999
|
|
}
|
|
});
|
|
MaskedDate.DEFAULTS = {
|
|
...MaskedPattern.DEFAULTS,
|
|
mask: Date,
|
|
pattern: DefaultPattern,
|
|
format: (date, masked) => {
|
|
if (!date) return '';
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const year = date.getFullYear();
|
|
return [day, month, year].join('.');
|
|
},
|
|
parse: (str, masked) => {
|
|
const [day, month, year] = str.split('.').map(Number);
|
|
return new Date(year, month - 1, day);
|
|
}
|
|
};
|
|
IMask.MaskedDate = MaskedDate;
|
|
|
|
export { MaskedDate as default };
|