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 Days, 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 Days .

Calendar Model exposes functions that return the following types of sets. All types, except hour, return Days:

  • 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 Week sets, 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:

  1. Define the model
  2. Define an Event Binder (optional)
  3. 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 events with Days. 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 toDays .

Event binding occurs when a Day is created. The constructor calls the getEvents function to populate the contents of the event. The Days 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

results matching ""

    No results matching ""