Calendar Model
TOC
Simple Calendar Data
NOTE: For full details, see the online API docs
The idea behind Calendar Model is simple: Make it easy to get and work with calendrical data. Calendar Model only cares about the data. It leaves the presentation of the data up to you. In addition, while Calendar Model provides default implementations for all its functionality, you can override most of the defaults.
Calendar Model is implemented as a set of functions. These functions can be queried to return result sets. Each result set contains a collection (Array) of Day
objects.
A
Day
object is a decorated JSDate
. It extendsDate
with a few convenience methods, and anevents
property.An
event
is an arbitrary set of data (Array) associated with aDay
.
Calendar Model conforms to the following pattern:
--> Input: Date --> Output: Day
Calendar Model exposes functions that return the following types of result sets:
- Month (by default 5 weeks)
- Week (by default 7 days)
- Day
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
.
Day queries only return Flat sets.
Calendar Model is really small. It also has no external dependencies.
Install from NPM
1.yarn add calendar-model
or
npm i calendar-model -S
Get Source
2.git clone https://github.com/joe-crick/calendar-model.git
Installing
3.Once you've cloned the repo, install dependencies
yarn
or
npm i
Compile
4.To compile Calendar Model, run:
npm run build
The build transpiles the JS, and creates docs. The transpiled JS will be located in the lib
folder. Docs are located in the docs
folder.
Basic Use
5.A basic calendar 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
5.1.Because Calendar Model is a collection of functions, there are a number of ways you can define a given implementation of Calendar Model. 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. Below are a few examples:
Create a Week-based Calendar, without Events
// @return {Array<Day>}
export default function getNWeeks({date, numOfWeeks});
Create a Week-based Calendar that has Events
// @return {Function}
export default function initCalendar(calendarData) {
// makeEventFinder returns a stateful function that has access to calendarData
const getEvents = makeEventFinder(calendarData);
// @return {Array<Day>}
return function getMonth(date, numOfWeeks) {
return getNWeeks({date, 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({date, 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({date});
Define an Event Binder
5.2.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 to Day
s.
Event binding occurs when a Day
is created. The constructor calls the getEvents
function to
populate the contents of the event. The output of the getEvents
function is assigned to the
events property of the Day
. In Calendar Model's default getEvents
implementation, the Day
s
Date
instance is passed as an argument to the getEvents
function, which returns an array of
events for that day.
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
5.3.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, a nested result set is recommended):
<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
6.Calendar Model exposes several helper methods:
formatDate
: Formats a date in International format (DD/MM/YYYY).monthNameFinder
: Returns the text name for a given month.weekDayNameFinder
: Returns the text name for a given week.getNextWeekDay
: Given a seed date, returns a Day 7 days in the future.getPrevWeekDay
: Given a seed date, returns a Day 7 days in the past.
Enjoy!