salix/front/core/components/calendar/index.js

194 lines
4.5 KiB
JavaScript
Raw Normal View History

2018-11-12 10:31:58 +00:00
import ngModule from '../../module';
2019-10-23 15:38:35 +00:00
import FormInput from '../form-input';
2018-11-12 10:31:58 +00:00
import './style.scss';
/**
2019-04-29 09:49:43 +00:00
* Flat calendar.
2018-11-12 10:31:58 +00:00
*
2019-10-23 15:38:35 +00:00
* @property {Array} defaultDate Array of events
2019-09-25 18:06:42 +00:00
* @property {Function} hasEvents Determines if an events exists for a day
* @property {Function} getClass Class to apply to specific day
2019-10-23 15:38:35 +00:00
* @event selection Emitted when day or weekday is selected
* @event move Emitted when month changes
2018-11-12 10:31:58 +00:00
*/
2019-10-23 15:38:35 +00:00
export default class Calendar extends FormInput {
constructor($element, $scope, vnWeekDays) {
2018-11-12 10:31:58 +00:00
super($element, $scope);
2019-10-23 15:38:35 +00:00
this.weekDays = vnWeekDays.locales;
2018-11-12 10:31:58 +00:00
this.defaultDate = new Date();
2019-01-21 10:45:53 +00:00
this.displayControls = true;
}
/**
2019-10-23 15:38:35 +00:00
* The initial date
*
* @return {Date} - Default date
*/
2018-11-12 10:31:58 +00:00
get defaultDate() {
return this._defaultDate;
}
set defaultDate(value) {
2019-09-25 18:06:42 +00:00
if (value) {
value = new Date(value);
value.setHours(0, 0, 0, 0);
value.setDate(1);
}
2019-01-21 10:45:53 +00:00
2019-09-25 18:06:42 +00:00
this._defaultDate = value;
2019-10-23 15:38:35 +00:00
this.month = value.getMonth();
2019-01-21 10:45:53 +00:00
this.repaint();
}
/**
* Returns first day of month from a given date
*
* @param {Date} date - Origin date
* @return {Integer}
*/
firstDay(date) {
2019-10-23 15:38:35 +00:00
return new Date(
2019-01-21 10:45:53 +00:00
date.getFullYear(),
2019-10-23 15:38:35 +00:00
date.getMonth(),
1
);
2019-01-21 10:45:53 +00:00
}
/**
2019-10-23 15:38:35 +00:00
* Repaints the calendar.
2019-01-21 10:45:53 +00:00
*/
repaint() {
2019-10-23 15:38:35 +00:00
const firstWeekday = this.firstDay(this.defaultDate).getDay() - 1;
let weekdayOffset = firstWeekday >= 0 ? firstWeekday : 6;
2018-11-12 10:31:58 +00:00
2019-10-23 15:38:35 +00:00
let dayIndex = new Date(this.defaultDate.getTime());
dayIndex.setDate(1 - weekdayOffset);
2018-11-12 10:31:58 +00:00
this.days = [];
2019-01-21 10:45:53 +00:00
2019-10-23 15:38:35 +00:00
for (let i = 1; i <= 42; i++) {
this.days.push(new Date(dayIndex.getTime()));
dayIndex.setDate(dayIndex.getDate() + 1);
2018-11-12 10:31:58 +00:00
}
}
/**
2019-10-23 15:38:35 +00:00
* Gets CSS classes to apply to the specified day.
*
2019-10-23 15:38:35 +00:00
* @param {Date} day The day
* @return {Object} The CSS classes to apply
*/
2019-10-23 15:38:35 +00:00
getDayClasses(day) {
let wday = day.getDay();
let month = day.getMonth();
2019-10-23 15:38:35 +00:00
let classes = {
weekend: wday === 6 || wday === 0,
previous: month < this.month,
current: month == this.month,
next: month > this.month,
event: this.hasEvents({$day: day})
};
2019-10-23 15:38:35 +00:00
let userClass = this.getClass({$day: day});
if (userClass) classes[userClass] = true;
2019-10-23 15:38:35 +00:00
return classes;
2019-01-21 10:45:53 +00:00
}
/**
* Moves to next month(s)
2019-01-21 10:45:53 +00:00
*/
2019-10-23 15:38:35 +00:00
moveNext() {
this.move(1);
2018-11-12 10:31:58 +00:00
}
2019-01-21 10:45:53 +00:00
/**
* Moves to previous month(s)
2019-01-21 10:45:53 +00:00
*/
2019-10-23 15:38:35 +00:00
movePrevious() {
this.move(-1);
2018-11-12 10:31:58 +00:00
}
2019-01-21 10:45:53 +00:00
/**
2019-10-23 15:38:35 +00:00
* Moves @direction months backwards/forwards.
2019-01-21 10:45:53 +00:00
*
2019-10-23 15:38:35 +00:00
* @param {Number} direction Negative to move backwards, positive forwards
2019-01-21 10:45:53 +00:00
*/
2019-10-23 15:38:35 +00:00
move(direction) {
let date = new Date(this.defaultDate.getTime());
date.setMonth(date.getMonth() + direction);
this.defaultDate = date;
this.repaint();
this.emit('move', {$date: date});
}
2019-01-21 10:45:53 +00:00
2019-10-23 15:38:35 +00:00
/*
* Day selection event
*/
select(day) {
if (!this.editable) return;
this.change(day);
this.emit('selection', {
$days: [day],
$type: 'day'
});
2019-10-23 15:38:35 +00:00
this.repaint();
2018-11-12 10:31:58 +00:00
}
2019-10-23 15:38:35 +00:00
/*
* WeekDay selection event
*/
2019-10-23 15:38:35 +00:00
selectWeekDay(weekday) {
if (!this.editable) return;
let days = [];
2019-10-23 15:38:35 +00:00
for (let day of this.days) {
if (day.getDay() === weekday && day.getMonth() == this.month)
days.push(day);
2019-01-21 10:45:53 +00:00
}
2019-10-23 15:38:35 +00:00
this.field = days[0];
this.emit('selection', {
$days: days,
$type: 'weekday',
$weekday: weekday
});
2019-10-23 15:38:35 +00:00
this.repaint();
}
2019-09-25 18:06:42 +00:00
hasEvents() {
return false;
}
getClass() {
return '';
}
2018-11-12 10:31:58 +00:00
2019-10-23 15:38:35 +00:00
repeatLast() {
if (!this.formatDay) return;
let days = this.element.querySelectorAll('.days > .day');
for (let i = 0; i < days.length; i++) {
this.formatDay({
$day: this.days[i],
$element: days[i]
});
}
}
}
Calendar.$inject = ['$element', '$scope', 'vnWeekDays'];
2018-11-12 10:31:58 +00:00
2019-10-23 15:38:35 +00:00
ngModule.vnComponent('vnCalendar', {
2018-11-12 10:31:58 +00:00
template: require('./index.html'),
controller: Calendar,
bindings: {
2019-05-17 11:27:51 +00:00
defaultDate: '=?',
2019-09-25 18:06:42 +00:00
hasEvents: '&?',
getClass: '&?',
2019-10-23 15:38:35 +00:00
formatDay: '&?',
2019-01-21 10:45:53 +00:00
displayControls: '<?',
2019-10-23 15:38:35 +00:00
hideYear: '<?',
hideContiguous: '<?'
2018-11-12 10:31:58 +00:00
}
});