js-custom-datepicker
Version:
Сalendar was written on javascript using es6 format and was redone to es5 using webpack and babel tools. There are many classes for easy styling for the desired website design.
232 lines (197 loc) • 7.04 kB
JavaScript
import {Control} from './control';
import {Calendar} from './calendar';
import {Default} from './settings';
import '../lib/date';
import DOM from '../lib/dom';
import * as cls from '../lib/class';
import * as _ from '../lib/helper';
export const jsCustomDatepicker = (input, userSettings) => {
if (!input) {
return new TypeError('No element specified');
} else {
input.readOnly = true;
}
const root = window;
const _document = root.document;
const options = _.extend(Default, userSettings);
const input_opt = input.getAttribute('data-options');
if (input_opt) {
try {
let _options = JSON.parse(input_opt);
for (let i in _options) {
options[i] = _options[i];
}
} catch (e) {
console.error(e);
}
}
options.isInput = input.tagName === 'INPUT';
options.element = input;
options.getDate = e => {
let target = e.target;
kill();
createCalendar(target.value || target.getAttribute('data-date'));
};
options.getDateIsoFormat = (date, check) => {
if (typeof date === 'string') {
let parts = date.match(/(\d+)/g), i = 0, fmt = {};
if (parts) {
options.dateFormat.replace(/(YYYY|dd|mm)/g, part => {
fmt[part] = i++;
});
return new Date(parts[fmt['YYYY']], parts[fmt['mm']] - 1, parts[fmt['dd']]);
} else if (!check) {
return new Date();
}
} else {
return date;
}
};
const createCalendar = date => {
let _date = options.getDateIsoFormat(date || '');
if (_date instanceof Object && _date.toString() === 'Invalid Date') {
_date = new Date();
}
options.current_day = _date.getDate();
options.current_month = _date.getMonth() + 1;
options.current_year = _date.getFullYear();
if (options.minYear) {
options.years = {
from: options.minYear
};
}
if (options.maxYear) {
options.to = {
from: options.maxYear
};
}
if (options.maxDate) {
options.maxYear = options.getDateIsoFormat(options.maxDate).getFullYear();
}
if (options.minDate) {
options.minYear = options.getDateIsoFormat(options.minDate).getFullYear();
}
let cal = DOM.createTag('div', {'class': 'custom-calendar'});
cal.appendChild(Control(options));
cal.appendChild(Calendar(options, {
close: close
}));
if (!options.isInput) {
cls.add(cal, 'static');
input.appendChild(cal);
} else {
_document.body.appendChild(cal);
}
if (typeof jsCustomSelect === 'function') {
let _select = cal.getElementsByClassName('js-custom-select');
for (let i = 0; i < _select.length; i++) {
options['select' + _select[i].getAttribute('data-type') + 'Obj'] = new jsCustomSelect(_select[i], options.select);
}
}
if (options.isInput) {
setPositionBox();
if (_.browser.addEventListener) {
if (_.browser.touch) {
root.addEventListener('touchsend', events, false);
} else {
root.addEventListener('mouseup', events, false);
}
root.addEventListener('resize', setPositionBox, false);
} else {
root.onclick = events.close;
root.onresize = setPositionBox;
}
}
};
const events = {
handleEvent: function (event) {
switch (event.type) {
case 'mouseup':
case 'touchsend':
let target = event.target;
if (!target.classList.contains('dp-wpl-open') && !target.closest('.custom-calendar:not(.static)')) {
close(0, event, true);
}
break;
}
}
};
const setPositionBox = () => {
let dp = _document.querySelector('.custom-calendar:not(.static)');
if (!dp || !options.isInput) {
return false;
}
let _currentInput = _document.querySelector('.dp-wpl-open');
let coords = _currentInput.getBoundingClientRect();
let doc = _document.documentElement;
if ((doc.clientWidth - coords.left - options.width) > 0) {
dp.style.left = coords.left + 'px';
} else {
dp.style.left = coords.right - options.width + 'px';
}
dp.style.top = ((root.pageYOffset || doc.scrollTop) - (doc.clientTop || 0) + coords.top + coords.height + 10) + 'px';
dp.style.width = options.width + 'px';
dp.style.position = 'absolute';
dp.style.display = 'block';
};
const close = (time, event, _isInput) => {
let _close = () => {
if (options.isInput || _isInput) {
DOM.remove(_document.querySelector('.custom-calendar:not(.static)'));
cls.remove(_document.querySelector('.dp-wpl-open'), 'dp-wpl-open');
if (typeof input.onchange === 'function') {
input.onchange();
}
if (_.browser.addEventListener) {
if (_.browser.touch) {
root.removeEventListener('touchsend', events, false);
} else {
root.removeEventListener('mouseup', events, false);
}
root.removeEventListener('resize', setPositionBox, false);
} else {
root.onclick = null;
root.onresize = null;
}
}
if (options.onClose) {
options.onClose.call(event, input, options.selectedDate);
}
};
if (time) {
setTimeout(_close, time);
} else {
_close();
}
};
const kill = () => {
if (options.isInput) {
DOM.remove(_document.querySelector('.custom-calendar:not(.static)'));
} else {
DOM.remove(input.querySelector('.custom-calendar'));
}
};
if (options.isInput) {
input.onclick = e => {
let target = e.target;
if (!target.classList.contains('dp-wpl-open')) {
cls.add(target, 'dp-wpl-open');
createCalendar(target.value);
}
};
} else {
createCalendar();
}
return {
getOptions: () => {
return options;
},
setOptions: _options => {
for (let i in _options) {
options[i] = _options[i];
}
},
close: close,
kill: kill
};
};