Calendar Model: Simple Calendar Data
Make it easy to get and work with calendrical data. This is the central idea behind Calendar Model. At the heart of Calendar Model is the Day
. A Day
is a decorated JS Date object. It is decorated with an events
property, and several convenience methods for getting common calendar-related Date properties. The events
property allows you to associate events of any sort to a day.
Calendar Model contains two sets of functions:
- Calendar functions, which return sets of
Day
s, and hours. - Calendar utility functions, which provide helper methods useful to working with calendarical data.
Calendar Model only cares about data. It leaves presentation up to you. In addition, while Calendar Model provides default implementations for all its functionality, you can override most of the defaults.
Calendar Functions
Calendar functions can be queried to return sets (Arrays) of Day
s .
Calendar Model exposes functions that return the following types of sets. All types, except hour
, return Day
s:
- Hour: Returns string representations of hours, either 12-hour based, or 24-hour based
- Day
- Week (by default 7 days)
- Month (by default 5 weeks)
Month and Week expose functions that can create two types of sets
:
- Flat: A one-dimensional Array
- Nested: A two-dimensional Array. Nested
sets
are useful when you want a collection of Weeksets
, for example, if you are created a table-based calendar.
Day queries only return Flat sets.
NOTE: Most Calendar functions take named parameters.
Basic Use
A basic calendar model can be created with the following steps:
- Define the model
- Define an Event Binder (optional)
- Define the data's presentation
Consult the sample application to see a working example of Calendar Model.
Define the Model
Because Calendar Model is a collection of functions, there are a number of ways you can define a given model implementation. You only need to include those functions you will be using in your application. You can use them as stand-alone functions, or add them as methods to an object.
Event Binding
It is very common for calendar applications to display events on specific dates (and times). Calendar Model uses construction-time, one-way event binding to associate event
s with Day
s. The contents of the events
property, and the method of binding are very flexible.
Calendar Model provides default implementations of an event binder, and an events
property data structure (it is Array based); however, you can also provide your own implementation.
Date Formatting
By default, Calendar Model formats dates using the standard, International format: dd/mm/yyyy. If you want to use another format, you can override the default date formatter by providing your own date formatter function. For details on how to do this, see the examples section below.
Examples
Create a Week-based Calendar, without Events
The following code creates a display-only, week-based calendar model comprised of two weeks worth of days, beginning on March 17th, 2017. This calendar will not contain events
data.
import {getNWeeks} from 'calendar-model/lib/week';
// @return {Array<Day>}
export default function getNWeeks({startDate: '03/17/2017', numOfWeeks: 2});
Create a Week-based Calendar that has Events
The following code creates a nested, month-based calendar model with events
data. This code uses Calendar Model's defaiult event binder, which can be created by calling the makeEventFinder
method with one parameter (see Binding Events
for more information).
import makeEventFinder from 'calendar-model/lib/utils/event.finder';
import {getNestedWeeks} from 'calendar-model/lib/month';
// @return {Function}
export default function initCalendar(calendarData) {
// makeEventFinder returns a stateful function that accepts a Day, and returns events for that day.
const getEvents = makeEventFinder(calendarData);
// @return {Array<Day>}
return function getMonth(startDate, numOfWeeks) {
return getNestedWeeks({startDate, getEvents, numOfWeeks});
}
}
The same pattern used to return a week--based calendar, can be used to create a day-based calendar:
Create a Day-based Calendar, without Events
// @return {Array<Day>}
export default function getNDays({startDate, numOfWeeks});
There is also a Month-based convenience method, which returns five weeks by default:
Create a Month-based Calendar, without Events
// @return {Array<Day>}
export default function getMonth({startDate});
Define an Event Binder
Each Day
in a result set returned by Calendar Model contains an events
property. The events
property can store an arbitrary set (Array) of data. Event data lives outside of the Calendar Model, and is one-way, one-time bound toDay
s .
Event binding occurs when a Day
is created. The constructor calls the getEvents
function to populate the contents of the event. The Day
s inner Date
instance is passed as an argument to the getEvents
function. For example, given the following event data format:
{
'01/02/2017': [{time: '9:00', title: 'My Event' }]
}
The following Event Binder would bind events to the appropriate days:
function makeEventFinder(eventData){
return function getEvents(date) {
return eventData[format(date)] || [];
};
}
The above code is, in fact, Calendar Model's default Event Binder, which can be overridden.
Define the Data's Presentation
You can present the calendar data in whatever format you like. Below is an example of rendering a month-based calendar using JSX (when presenting tabular data for multiple weeks, use a nested
result set):
<table className="calendar-example">
<TableHead />
<tbody>
{props.calendarDays.map((week, index) => {
return (
<tr key={index} className="week">
{week.map((day, idx) => {
return (
<td key={idx} className={getDayClassName(day, props.month)}>
<div className="day-contents">
<h3>{day.dayOfMonth}</h3>
<ul className="events">
{day.events.map((ev, idx) => {
return (
<li key={idx}>
{ev.time}: {ev.title}
</li>
)
})}
</ul>
</div>
</td>);
})}
</tr>);
})}
</tbody>
</table>
Helper Methods
Calendar Model exposes several helper methods, which it also uses internally. These helper methods are contained in the following categories:
Time Utils
Week Utils
Month Utils
Format
Event Binder
Name Finder