You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
287 lines
8.1 KiB
JavaScript
287 lines
8.1 KiB
JavaScript
class SmartDateField
|
|
{
|
|
constructor(field, options)
|
|
{
|
|
this._dateYmdParser = new RegExp('^([0-9]{4})[,\._\/\-]+([0-9]{1,2})[,\._\/\-]+([0-9]{1,2})$');
|
|
this._dateDmyParser = new RegExp('^([0-9]{1,2})[,\._\/\-]+([0-9]{1,2})[,\._\/\-]+([0-9]{4})$');
|
|
|
|
this._loadOptions(options);
|
|
|
|
this._formatter = new SmartDateFormat(this._format, this._minimalDate, this._maximalDate);
|
|
|
|
this._lastCorrectValue = (this._defaultDate === null ? null : this._formatter.formatDate(this._defaultDate));
|
|
|
|
this._initField(field);
|
|
|
|
this._subscribeEvents();
|
|
}
|
|
|
|
|
|
_loadDefaultOptions()
|
|
{
|
|
this._format = 'd.m.y';
|
|
this._minimalDate = new Date(1900, 0, 1);
|
|
this._maximalDate = new Date(2099, 11, 31);
|
|
this._defaultDate = null;
|
|
}
|
|
|
|
_loadOptions(options)
|
|
{
|
|
this._loadDefaultOptions();
|
|
|
|
if (typeof(options) !== 'object' || options == null) {
|
|
return;
|
|
}
|
|
|
|
if (typeof(options.format) === 'string'
|
|
&& options.format.indexOf('d') >= 0
|
|
&& options.format.indexOf('m') >= 0
|
|
&& options.format.indexOf('y') >= 0) {
|
|
this._format = options.format;
|
|
}
|
|
|
|
if (typeof(options.minimal) !== 'undefined') {
|
|
let date = this._parseDateValue(options.minimal);
|
|
this._minimalDate = date;
|
|
}
|
|
|
|
if (typeof(options.maximal) !== 'undefined') {
|
|
let date = this._parseDateValue(options.maximal);
|
|
this._maximalDate = date;
|
|
}
|
|
|
|
if (typeof(options.default) !== 'undefined') {
|
|
let date = this._parseDateValue(options.default);
|
|
this._defaultDate = date;
|
|
}
|
|
|
|
this._correctDateOptions();
|
|
}
|
|
|
|
_correctDateOptions()
|
|
{
|
|
if (this._minimalDate.valueOf() > this._maximalDate.valueOf()) {
|
|
let temporaryDate = this._minimalDate;
|
|
this._minimalDate = this._maximalDate;
|
|
this._maximalDate = temporaryDate;
|
|
}
|
|
|
|
if (this._defaultDate === null) {
|
|
return;
|
|
}
|
|
|
|
if (this._defaultDate.valueOf() < this._minimalDate.valueOf()) {
|
|
this._defaultDate = this._minimalDate;
|
|
}
|
|
|
|
if (this._defaultDate.valueOf() > this._maximalDate.valueOf()) {
|
|
this._defaultDate = this._maximalDate;
|
|
}
|
|
}
|
|
|
|
_parseDateValue(date)
|
|
{
|
|
if (typeof(date) === 'object' && date !== null && date instanceof Date) {
|
|
return date;
|
|
}
|
|
|
|
if (typeof(date) !== 'string' || date.trim() === '') {
|
|
return null;
|
|
}
|
|
|
|
let parsed = this._dateYmdParser.exec(date);
|
|
|
|
if (parsed !== null) {
|
|
return new Date(Number(parsed[1]), Number(parsed[2]) - 1, Number(parsed[3]));
|
|
}
|
|
|
|
parsed = this._dateDmyParser.exec(date);
|
|
|
|
if (parsed === null) {
|
|
return null;
|
|
}
|
|
|
|
return new Date(Number(parsed[3]), Number(parsed[2]) - 1, Number(parsed[1]));
|
|
}
|
|
|
|
_initField(field)
|
|
{
|
|
this._field = field;
|
|
this._field.placeholder = this._formatter.getPlaceHolder();
|
|
|
|
if (this._isEmptyValue(this._field.value)) {
|
|
this._field.value = (this._defaultDate === null ? '' : this._formatter.formatDate(this._defaultDate));
|
|
}
|
|
else {
|
|
this.correctValue(true);
|
|
}
|
|
}
|
|
|
|
_subscribeEvents()
|
|
{
|
|
let _this = this;
|
|
|
|
let correct = function (event) {
|
|
if (event === null || event.type !== 'keyup') {
|
|
_this.correctValue(true);
|
|
}
|
|
|
|
if (_this._isServiceCode(event.keyCode)) {
|
|
return;
|
|
}
|
|
|
|
if (event.keyCode === 27) { // Escape
|
|
_this.returnLastCorrectValue();
|
|
}
|
|
|
|
_this.correctValue(true);
|
|
};
|
|
|
|
this._field.addEventListener('change', correct);
|
|
this._field.addEventListener('keyup', correct);
|
|
|
|
this._field.addEventListener('blur', function () {
|
|
_this.correctValue(true);
|
|
|
|
if (!_this._isEmptyValue(_this._field.value)) {
|
|
_this.returnLastCorrectValue();
|
|
}
|
|
});
|
|
}
|
|
|
|
_isServiceCode(code) {
|
|
return code === 8 /* backspace */
|
|
|| code === 46 /* delete */
|
|
|| code === 16 /* shift */
|
|
|| code === 17 /* shift */
|
|
|| code === 18 /* shift */
|
|
|| code === 20 /* caps lock */
|
|
|| code === 35 /* end */
|
|
|| code === 36 /* home */
|
|
|| code === 37 /* left */
|
|
|| code === 39 /* right */
|
|
|| code === 46 /* delete */;
|
|
}
|
|
|
|
_isEmptyValue(value)
|
|
{
|
|
return value.trim() === '';
|
|
}
|
|
|
|
getDefaultValue()
|
|
{
|
|
return this._defaultDate === null ? '' : this._formatter.formatDate(this._defaultDate);
|
|
}
|
|
|
|
correctValue(autocomplete)
|
|
{
|
|
this._formatter.parse(this._field.value, autocomplete);
|
|
|
|
let parsedValue = this._getLimitedParsedValue();
|
|
|
|
if (this._formatter.isComplete()) {
|
|
this._lastCorrectValue = parsedValue;
|
|
}
|
|
|
|
if (this._field.value === parsedValue) {
|
|
return;
|
|
}
|
|
|
|
this._setValueToField(parsedValue);
|
|
}
|
|
|
|
setValue(value)
|
|
{
|
|
let date = this._parseDateValue(value);
|
|
|
|
if (date === null || date.valueOf() < this._minimalDate.valueOf() || date.valueOf() > this._maximalDate.valueOf()) {
|
|
return;
|
|
}
|
|
|
|
this._lastCorrectValue = this._formatter.formatDate(date);
|
|
this._field.value = this._lastCorrectValue;
|
|
}
|
|
|
|
_getLimitedParsedValue()
|
|
{
|
|
if (!this._formatter.isComplete()) {
|
|
return this._formatter.getCorrectedValue();
|
|
}
|
|
|
|
let date = this._formatter.getParsedDate();
|
|
|
|
if (date.valueOf() < this._minimalDate.valueOf()) {
|
|
return this._formatter.formatDate(this._minimalDate);
|
|
}
|
|
else if (date.valueOf() > this._maximalDate.valueOf()) {
|
|
return this._formatter.formatDate(this._maximalDate);
|
|
}
|
|
|
|
return this._formatter.getCorrectedValue();
|
|
}
|
|
|
|
_setValueToField(newValue)
|
|
{
|
|
let position = this._field.selectionStart;
|
|
let isAtEnd = (position === this._field.value.length);
|
|
|
|
this._field.value = newValue;
|
|
|
|
if (!isAtEnd && position < this._field.value.length) {
|
|
this._field.selectionStart = position;
|
|
this._field.selectionEnd = position;
|
|
}
|
|
}
|
|
|
|
returnLastCorrectValue()
|
|
{
|
|
if (this._lastCorrectValue !== null) {
|
|
this._field.value = this._lastCorrectValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
SmartDateField.initBy = function (id) {
|
|
return SmartDateField.initFor(document.getElementById(id));
|
|
};
|
|
|
|
SmartDateField.initFor = function (field, options) {
|
|
if (typeof(field) !== 'object'
|
|
|| field === null
|
|
|| field.tagName.toLowerCase() !== 'input'
|
|
|| field.type.toLowerCase() !== 'text') {
|
|
return;
|
|
}
|
|
|
|
if (typeof(field._smartDate) === 'object' && field._smartDate !== null && field._smartDate instanceof SmartDateField) {
|
|
return;
|
|
}
|
|
|
|
field._smartDate = new SmartDateField(field, options);
|
|
};
|
|
|
|
jQuery.fn.smartdate = function (options) {
|
|
let collection = [];
|
|
let field = null;
|
|
|
|
for (let i = 0; i < this.length; i++) {
|
|
field = SmartDateField.initFor(this[i], options);
|
|
|
|
if (field !== null) {
|
|
collection.push(field);
|
|
}
|
|
}
|
|
|
|
return jQuery(this);
|
|
};
|
|
|
|
jQuery.fn.setDateValue = function (value) {
|
|
for (let i = 0; i < this.length; i++) {
|
|
if (typeof(this[i]._smartDate) === 'object' && this[i]._smartDate !== null && this[i]._smartDate instanceof SmartDateField) {
|
|
this[i]._smartDate.setValue(value);
|
|
}
|
|
}
|
|
|
|
return jQuery(this);
|
|
};
|