/** * For an overview of calendar views see {@link Ext.calendar.view.Base} * * The Month view shows events over an entire month. The view shows a summary of the * events that occur on each day. The month view uses the current date (or the date set * on the {@link #value} config) to determine the month to show. * * The Month view displays (as needed) days from trailing/leading months as required to * fill the space in the view based on the {@link #value} and the * {@link #firstDayOfWeek}. In the following example, the view will start on Sun Dec * 27 and conclude on Sat Feb 6 because we require 6 rows to display the month of * January. * * { * value: new Date(2010, 0, 1) // Fri * firstDayOfWeek: 0 // Sunday * } * * The {@link #visibleWeeks} can be specified as `null` to allow the view to * calculate the appropriate number of rows to show in the view, as this varies * from month to month. This defaults to the largest possible value (6 weeks) so that * the view size is consistent across months. * * ### Date Range Navigation * * In addition to {@link #navigate}, {@link #movePrevious}, and * {@link #moveNext} the Month view let you quickly navigate between months and * years. The {@link #previousMonth} and {@link #nextMonth} methods allow for * programmatic month-to-month navigation while {@link #previousYear} and * {@link #nextYear} navigate the view across years. * * ### Alternative Classes * * If your view requires a header showing the days of the week consider using * {@link Ext.calendar.panel.Weeks} instead. For a multi-week view refer to * {@link Ext.calendar.view.Weeks}. */Ext.define('Ext.calendar.view.Month', { extend: 'Ext.calendar.view.Weeks', xtype: 'calendar-monthview', config: { /** * @cfg {Date} [value=new Date()] * The current month to show. The value will default to the * first date of the configured month. For example: * * calendar.setValue(new Date(2010, 0, 13)); * console.log(calendar.getValue()); // -> 2010-01-01 */ value: undefined, /** * @cfg {Number} [visibleWeeks=6] * The number of weeks to show in this view. If specified as `null`, the view will generate * the appropriate number of rows to display a full month based on the passed * {@link #cfg!value}. In a majority of cases, this will be 5, however some months * will only require 4, while others will need 6. Defaults to the largest value to keep * the view size consistent. */ visibleWeeks: 6 }, /** * Move forward by a number of months. * @param {Number} [months=1] The number of months to move. */ nextMonth: function(months) { this.navigate(this.getNavigateValue(months), Ext.Date.MONTH); }, /** * Move forward by a number of years. * @param {Number} [years=1] The number of years to move. */ nextYear: function(years) { this.navigate(this.getNavigateValue(years), Ext.Date.YEAR); }, /** * Move backward by a number of months. * @param {Number} [months=1] The number of months to move. */ previousMonth: function(months) { this.navigate(-this.getNavigateValue(months), Ext.Date.MONTH); }, /** * Move backward by a number of years. * @param {Number} [years=1] The number of years to move. */ previousYear: function(years) { this.navigate(-this.getNavigateValue(years), Ext.Date.YEAR); }, privates: { displayRangeProp: 'month', /** * @property {Number} maxWeeks * The maximum amount of weeks to be shown * * @private */ maxWeeks: 6, /** * @property {String[]} rowClasses * The row classes for the view when they are to be displayed as * @private */ $rowClasses: [ Ext.baseCSSPrefix + 'calendar-month-4weeks', Ext.baseCSSPrefix + 'calendar-month-5weeks', Ext.baseCSSPrefix + 'calendar-month-6weeks' ], $todayCellHighlightCls: Ext.baseCSSPrefix + 'today-cell-highlight', trackRanges: true, /** * Calculate the relevant date ranges given the current value. * @param {Date} [start] The start to recalculate from. Defaults to the current value. * @return {Object} The active values. * @return {Ext.calendar.date.Range} return.visible The visible date range. * @return {Ext.calendar.date.Range} return.active The active range for the view. * @return {Ext.calendar.date.Range} return.month The month range for the view. * @return {Number} return.requireWeeks The number of weeks in the current view. * * @private */ doRecalculate: function(start) { var me = this, D = Ext.Date, daysInWeek = D.DAYS_IN_WEEK, firstDayOfWeek = me.getFirstDayOfWeek(), requiredWeeks = me.maxWeeks, visibleWeeks = me.getVisibleWeeks(), visibleDays = me.getVisibleDays(), R = Ext.calendar.date.Range, days, end, first, l, last, startOffset; start = D.getFirstDateOfMonth(start || me.getValue()); // The number of days before the value date to reach the previous firstDayOfWeek startOffset = (start.getDay() + daysInWeek - firstDayOfWeek) % daysInWeek; first = me.toUtcOffset(start); l = D.getLastDateOfMonth(start); last = me.toUtcOffset(l); // A null value means we need to figure out how many weeks we need if (visibleWeeks === null) { if (startOffset >= visibleDays) { startOffset = visibleDays - startOffset; } days = startOffset + D.getDaysInMonth(start); requiredWeeks = Math.ceil(days / daysInWeek); } end = daysInWeek * requiredWeeks - (daysInWeek - visibleDays); start = D.subtract(first, D.DAY, startOffset); end = D.add(start, D.DAY, end); return { // For compat with day views full: new R(start, end), visible: new R(start, end), active: new R(start, D.subtract(end, D.DAY, 1)), month: new R(first, last), requiredWeeks: requiredWeeks }; }, doRefresh: function() { var me = this, cls = me.$rowClasses, weeks = me.dateInfo.requiredWeeks; me.element.replaceCls(cls, cls[weeks - 1 - cls.length]); me.callParent(); }, getMoveBaseValue: function() { return this.utcToLocal(this.dateInfo.month.start); }, getMoveInterval: function() { return { unit: Ext.Date.MONTH, amount: 1 }; }, generateCells: function() { // Always generate the max number of cells and we'll hide/show as needed. return this.callParent([this.maxWeeks, false]); }, /** * Gets the value to navigate by, if no value is specified then * it will default to `1`. * @param {Number} n Get the value to navigate by. * @return {Number} The value to navigate by, `1` if no value is passed. * * @private */ getNavigateValue: function(n) { return n || n === 0 ? n : 1; } }});