/** * A store for {@link Ext.calendar.model.CalendarBase Calendar} models. * * This store type is used as the base store for * {@link Ext.calendar.view.Base calendar views}. The Calendars store contains one or * more source calendars whose primary purpose is to own * {@link Ext.calendar.Event Events} within the source calendar's * {@link Ext.calendar.store.Events Events store}. * * ### Dynamic Events Store Configuration * * Below is a sample calendar configured to {@link #cfg-autoLoad} source calendars from * "calendars.php": * * Ext.create({ * xtype: 'calendar', * renderTo: Ext.getBody(), * height: 400, * width: 600, * store: { * autoLoad: true, * proxy: { * type: 'ajax', * url: 'calendars.php' * } * } * }); * * As mentioned before, source calendars themselves own Events stores. Loading the * Calendars store and its source calendars will automatically fetch events for the * calendar view's date range. However, by default the Events store belonging to each * source calendar is not configured with a {@link Ext.data.proxy.Server proxy} to fetch * the remote events. Using the above example the expected data response for a single * source calendar would look something like: * * [{ * "id": 1, * "title": "Personal", * "eventStore": { * "proxy": { * "type": "ajax", * "url": "events.php" * } * } * }] * * In the above data response we see: * * - **id** - The unique id for this source calendar record in the Calendars store * - **title** - The source calendar title (used when displayed in a * {@link Ext.calendar.form.CalendarPicker CalendarPicker}) * - **eventStore** - The config options for the source calendar Events store * * **Note:** for more information on the data the Calendar model consumes refer to * {@link Ext.calendar.model.Calendar} * * ### Default Events Store Configuration * * Passing the `eventStore` config back with the calendar offers maximum flexibility as * the Events store config / url can be specified uniquely per source calendar. However, * if the events will all be served up from the same remote source it may be more * effective to configure the Calendars store's {@link #cfg-eventStoreDefaults} with * common defaults. As an example: * * Ext.create({ * xtype: 'calendar', * renderTo: Ext.getBody(), * height: 400, * width: 600, * store: { * autoLoad: true, * proxy: { * type: 'ajax', * url: 'calendars.php' * }, * eventStoreDefaults: { * proxy: { * type: 'ajax', * url: 'events.php' * } * } * } * }); * * With the above configuration a sample response from "calendars.php" including a single * source calendar would be: * * [{ * "id": 1, * "title": "Personal" * }] * * Using the above Calendars config every source calendar passed back from * "calendars.php" will have its events store configured to fetch events from * "events.php". Read operations requesting events will pass up to the remote server: * * - **calendar** - The id of the source calendar * - **startDate** - The start date / time of events for the current calendar view * - **endDate** - The end date / time of events for the current calendar view * * You can configure the param names sent using the Event model's * {@link Ext.calendar.store.Events#cfg-calendarParam calendarParam}, * {@link Ext.calendar.store.Events#cfg-startParam startParam}, and * {{@link Ext.calendar.store.Events#cfg-endParam endParam}} config options. * * **Note:** The date range requested will be somewhat larger than the current visible * date range in the calendar view as set in the Events store's * {@link Ext.calendar.store.Events#cfg-prefetchMode prefetchMode} config option. * Commonly this configuration can be left as its default. * * ### Events Response * * Below is a sample response from 'events.php' for a 1 hour event. * * [{ * "id": 1001, * "calendarId": 1, * "startDate": "2016-09-30T21:30:00.000Z", * "endDate": "2016-09-30T22:30:00.000Z", * "title": "Watch cartoons", * "description": "Catch up with adventurers Finn and Jake" * }] * * Sample response from 'events.php' for an all day event on Sept. 30th 2016 * * [{ * "id": 1001, * "calendarId": 1, * "startDate": "2016-09-30T00:00:00.000Z", * "endDate": "2016-10-01T00:00:00.000Z", * "allDay": true, * "title": "Netflix Binge", * "description": "Watch Luke Cage. Maybe twice." * }] * * An all day event should be indicated as `allDay`: true. Its `startDate` will be the * 00:00:00 hour of the target date and have an `endDate` with a 00:00:00 time on the * following day. * * In the event response we see: * * - **id** - The unique id for the calendar event record * - **calendarId** - The id of the parent source calendar * - **startDate** - The event's start date and time (in UTC format) * - **endDate** - The event's end date and time (in UTC format) * - **title** - The title to display for the event * - **description** - The description to display for the event * * **Note:** for more information on the data the Events model consumes refer to * {@link Ext.calendar.model.Event} * * ### Multi-Calendar Support * * The calendar views also accommodate multiple source calendars within the same view. * The response from the Calendars store (from 'calendars.php' using the above example) * should be an array of objects containing a unique "id" per source calendar along with * unique "title"s. The titles will display in a combo field in the add/edit event forms * as a way to indicate what source calendar an event belongs to as well as in the * {@link Ext.calendar.panel.Panel Calendar panel's} * {@link Ext.calendar.List calendar list}. The id will correlate to the "calendarId" * key in the event response. * * Sample response from 'calendars.php' including two source calendars: "Personal" and * "Work" * * [{ * "id": 1, * "title": "Personal" * }, { * "id": 2, * "title": "Work" * }] * * A view with two source calendars will make two read request each time the view's date * range is rendered. Expected in return is two separate responses containing events * with "calendarId" keys corresponding to the calendar that owns the events. With a * calendar view with both "Personal" and "Work" source calendars two responses would be * expected: one like as seen above including a key of `"calendarId": 1` and one for the * Work calendar as seen here. * * [{ * "id": 2001, * "calendarId": 2, * "startDate": "2016-09-30T21:30:00.000Z", * "endDate": "2016-09-30T22:30:00.000Z", * "title": "Meet with Development", * "description": "Discuss the current cycle requirements" * }] * * **Note:** The "id"s for all events must be unique within a calendar store across all * event stores. Duplicate "id"s even across event stores may result in unintended * consequences. */Ext.define('Ext.calendar.store.Calendars', { extend: 'Ext.data.Store', alias: 'store.calendar-calendars', requires: [ 'Ext.calendar.store.EventSource', 'Ext.calendar.model.Calendar' ], config: { /** * @cfg {Object} eventStoreDefaults * Defaults for the {@link Ext.calendar.model.CalendarBase event stores} * generated by the calendars. */ eventStoreDefaults: null }, model: 'Ext.calendar.model.Calendar', /** * Get the event source for this calendar. * @return {Ext.calendar.store.EventSource} The event source. */ getEventSource: function() { var source = this.eventSource; if (!source) { this.eventSource = source = new Ext.calendar.store.EventSource({ source: this }); } return source; }, onCollectionAdd: function(collection, info) { var cfg = this.getEventStoreDefaults(), items = info.items, len = items.length, i, rec; this.callParent([collection, info]); if (cfg) { for (i = 0; i < len; ++i) { rec = items[i]; if (!rec.hasOwnProperty('eventStoreDefaults')) { rec.eventStoreDefaults = Ext.merge({}, rec.eventStoreDefaults, cfg); } } } }, doDestroy: function() { this.eventSource = Ext.destroy(this.eventSource); this.callParent(); }});