@craftkit/craft-widget-calendar
Version:
Fully customizable JavaScript calendar widget for Craftkit
190 lines (165 loc) • 4.9 kB
JavaScript
import * as Craft from '@craftkit/craft-uikit';
import { Day } from './Day.js';
/**
* Month
*
* Collect Days and its view.
* To fill up 6 week container, This object also has a part of days in prev month and next month.
*
* @packagename Craft.Widget.Calendar.Month
*
* @example
*
* let month = new Month({
* yyyy : '2020',
* mm : '01',
* delegate : this.delegate,
* Day : Craft.Widget.Calendar.Day,
* });
*
* var day = month.index['2020-01-15'];
* day.classes.push('today');
* day.renderView();
*
*/
export class Month extends Craft.UI.View {
/**
* Month constructor
*
* @param {Object} options - options
* @param {String} options.yyyy - year
* @param {String} options.mm - month
* @param {Object} options.delegate - Calendar event handler
* @param {Craft.Widget.Calendar.Day} options.Day - Day class
* @param {Craft.Widget.Calendar.StyleSheet} options.StyleSheet - StyleSheet class
*/
constructor(options){
super();
this.packagename = 'Craft.Widget.Calendar.Month';
this.delegate = options.delegate;
this.dayClass = options.Day;
this.styleSheet = options.StyleSheet;
if( Number(options.yyyy) ){
this.yyyy = ('0000'+options.yyyy).slice(-4);
}else{
this.yyyy = moment().format('YYYY');
}
if( Number(options.mm) ){
this.mm = ('00'+options.mm).slice(-2);
}else{
this.mm = moment().format('MM');
}
this.dd = '01';
this.iso = this.yyyy + '-' + this.mm;
this.prev_days = []; // array of Day object to fill the first week
this.this_days = []; // array of Day object
this.next_days = []; // array of Day object to fill the last week
this.days = []; // all of Day objects
this.index = {}; // iso8601 : Day object
this.this_month = '';
this.prev_month = '';
this.next_month = '';
this.today = moment();
this.build();
}
/**
* Build Days in this month. (internal utility called from the constructor)
*
* @protected
*/
build(){
this.this_month = new moment( this.iso + '-' + this.dd );
this.prev_month = this.this_month.clone().subtract(1,'month');
this.next_month = this.this_month.clone().add(1,'month');
// prev month
let prev_month_last_day = this.prev_month.endOf('month').date();
let prev_month_rest_days = this.prev_month.endOf('month').day() === 6 ? 0 : this.prev_month.endOf('month').day() + 1;
let prev_month_month = this.prev_month.format('MM');
let prev_month_year = this.prev_month.format('YYYY');
let prev_month_weekday_cursor = 0;
for( let i=prev_month_rest_days; i>=1; i-- ){
let weekday = prev_month_weekday_cursor % 7;
let day = new this.dayClass({
delegate : this.delegate,
yyyy : prev_month_year,
mm : prev_month_month,
dd : prev_month_last_day - i + 1,
classes : ['weekday'+weekday,'prev_month'],
StyleSheet : this.styleSheet,
});
day.loadView();
this.prev_days.push(day);
this.days.push(day);
this.index[day.iso] = day;
prev_month_weekday_cursor++;
}
// this month
let this_month_year = this.this_month.year();
let this_month_month = this.this_month.month() + 1;
let weekday_cursor = this.this_month.weekday();
let today_iso = this.today.format('YYYY-MM-DD');
for( let i=0; i<this.this_month.daysInMonth(); i++ ){
let weekday = weekday_cursor % 7;
let day = new this.dayClass({
delegate : this.delegate,
yyyy : this_month_year,
mm : this_month_month,
dd : i + 1,
classes : ['weekday'+weekday,'this_month'],
StyleSheet : this.styleSheet,
});
if( day.iso == today_iso ){
day.classes.push('today');
}
day.loadView();
this.this_days.push(day);
this.days.push(day);
this.index[day.iso] = day;
weekday_cursor++;
}
// next month
let next_month_month = this.next_month.month() + 1;
let next_month_year = this.next_month.year();
let next_month_rest_days = 42 - (prev_month_rest_days + this.this_month.endOf('month').date());
for( let i=0; i<next_month_rest_days; i++ ){
let weekday = weekday_cursor % 7;
let day = new this.dayClass({
delegate : this.delegate,
yyyy : next_month_year,
mm : next_month_month,
dd : i + 1,
classes : ['weekday'+weekday,'next_month'],
StyleSheet : this.styleSheet,
});
day.loadView();
this.next_days.push(day);
this.days.push(day);
this.index[day.iso] = day;
weekday_cursor++;
}
}
/**
* Lifecycle method : viewDidLoad
*
* deploy Days
*
* @protected
*/
viewDidLoad(callback){
this.days.map( (day) => this.appendView(day) );
}
/**
* style
* @protected
*/
style(componentId){
return this.styleSheet.month;
}
/**
* template
* @protected
*/
template(componentId){
return `<div class="root"></div>`;
}
}