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

237 lines
5.8 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, moment) {
2018-11-12 10:31:58 +00:00
super($element, $scope);
2019-10-23 15:38:35 +00:00
this.weekDays = vnWeekDays.locales;
2019-01-21 10:45:53 +00:00
this.displayControls = true;
this.moment = moment;
this.defaultDate = Date.vnNew();
}
/**
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
}
lastDay() {
return new Date(
this.defaultDate.getFullYear(),
this.defaultDate.getMonth() + 1,
0
).getDate();
}
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;
this.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 - this.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
}
this.getWeekdays();
}
getWeekdays() {
if (!this.moment) return;
const totalSlots = this.lastDay() + this.weekdayOffset;
const weeks = Math.ceil(totalSlots / 7);
2021-09-20 08:10:25 +00:00
const dated = this.moment(this.defaultDate);
const firstWeekNumber = dated.set('date', 1).isoWeek();
const weekNumbers = [];
for (let w = 0; w < weeks; w++) {
let weekNumber = firstWeekNumber;
2021-09-20 08:10:25 +00:00
if (dated.get('month') == 0 && firstWeekNumber > 1 && w > 0)
weekNumber = 0;
weekNumbers.push(weekNumber + w);
}
this.weekNumbers = weekNumbers;
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.
*
* @param {Date} date The date
2019-10-23 15:38:35 +00:00
* @return {Object} The CSS classes to apply
*/
getDayClasses(date) {
let day = date.getDate();
let wday = date.getDay();
let month = date.getMonth();
2023-01-16 14:18:24 +00:00
const currentDay = Date.vnNew().getDate();
const currentMonth = Date.vnNew().getMonth();
2019-10-23 15:38:35 +00:00
let classes = {
today: day === currentDay && month === currentMonth,
2019-10-23 15:38:35 +00:00
weekend: wday === 6 || wday === 0,
previous: month < this.month,
current: month == this.month,
next: month > this.month,
event: this.hasEvents({$day: date})
2019-10-23 15:38:35 +00:00
};
let userClass = this.getClass({$day: date});
2019-10-23 15:38:35 +00:00
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
*/
2020-02-26 06:02:03 +00:00
select($event, day) {
2019-10-23 15:38:35 +00:00
if (!this.editable) return;
this.change(day);
this.emit('selection', {
2020-02-26 06:02:03 +00:00
$event: $event,
$days: [day],
$type: 'day'
});
2020-08-10 12:29:25 +00:00
// Repaint only if 'selection' event is not listening
if (!this.$events || this.$events && !this.$events['selection'])
this.repaint();
2018-11-12 10:31:58 +00:00
}
2019-10-23 15:38:35 +00:00
/*
* WeekDay selection event
*/
2020-02-26 06:02:03 +00:00
selectWeekDay($event, weekday) {
2019-10-23 15:38:35 +00:00
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', {
2020-02-26 06:02:03 +00:00
$event: $event,
$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', 'moment'];
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: '<?',
hideWeeks: '<?'
2018-11-12 10:31:58 +00:00
}
});