Many classes have shortcut names used when creating (instantiating) a class with a
configuration object. The shortcut name is referred to as an alias
(or xtype
if the
class extends Ext.Component). The alias/xtype is listed next to the class name of
applicable classes for quick reference.
Framework classes or their members may be specified as private
or protected
. Else,
the class / member is public
. Public
, protected
, and private
are access
descriptors used to convey how and when the class or class member should be used.
Public classes and class members are available for use by any other class or application code and may be relied upon as a stable and persistent within major product versions. Public classes and members may safely be extended via a subclass.
Protected class members are stable public
members intended to be used by the
owning class or its subclasses. Protected members may safely be extended via a subclass.
Private classes and class members are used internally by the framework and are not intended to be used by application developers. Private classes and members may change or be omitted from the framework at any time without notice and should not be relied upon in application logic.
static
label next to the
method name. *See Static below.Below is an example class member that we can disect to show the syntax of a class member (the lookupComponent method as viewed from the Ext.button.Button class in this case).
Let's look at each part of the member row:
lookupComponent
in this example)( item )
in this example)Ext.Component
in this case). This may be omitted for methods that do not
return anything other than undefined
or may display as multiple possible values
separated by a forward slash /
signifying that what is returned may depend on the
results of the method call (i.e. a method may return a Component if a get method calls is
successful or false
if unsuccessful which would be displayed as
Ext.Component/Boolean
).PROTECTED
in
this example - see the Flags section below)Ext.container.Container
in this example). The source
class will be displayed as a blue link if the member originates from the current class
and gray if it is inherited from an ancestor or mixed-in class.view source
in the example)item : Object
in the example).undefined
a "Returns" section
will note the type of class or object returned and a description (Ext.Component
in the
example)Available since 3.4.0
- not pictured in
the example) just after the member descriptionDefaults to: false
)The API documentation uses a number of flags to further commnicate the class member's function and intent. The label may be represented by a text label, an abbreviation, or an icon.
classInstance.method1().method2().etc();
false
is returned from
an event handler- Indicates a framework class
- A singleton framework class. *See the singleton flag for more information
- A component-type framework class (any class within the Ext JS framework that extends Ext.Component)
- Indicates that the class, member, or guide is new in the currently viewed version
- Indicates a class member of type config
- Indicates a class member of type property
- Indicates a class member of type
method
- Indicates a class member of type event
- Indicates a class member of type
theme variable
- Indicates a class member of type
theme mixin
- Indicates that the class, member, or guide is new in the currently viewed version
Just below the class name on an API doc page is a row of buttons corresponding to the types of members owned by the current class. Each button shows a count of members by type (this count is updated as filters are applied). Clicking the button will navigate you to that member section. Hovering over the member-type button will reveal a popup menu of all members of that type for quick navigation.
Getting and setter methods that correlate to a class config option will show up in the methods section as well as in the configs section of both the API doc and the member-type menus just beneath the config they work with. The getter and setter method documentation will be found in the config row for easy reference.
Your page history is kept in localstorage and displayed (using the available real estate) just below the top title bar. By default, the only search results shown are the pages matching the product / version you're currently viewing. You can expand what is displayed by clicking on the button on the right-hand side of the history bar and choosing the "All" radio option. This will show all recent pages in the history bar for all products / versions.
Within the history config menu you will also see a listing of your recent page visits. The results are filtered by the "Current Product / Version" and "All" radio options. Clicking on the button will clear the history bar as well as the history kept in local storage.
If "All" is selected in the history config menu the checkbox option for "Show product details in the history bar" will be enabled. When checked, the product/version for each historic page will show alongside the page name in the history bar. Hovering the cursor over the page names in the history bar will also show the product/version as a tooltip.
Both API docs and guides can be searched for using the search field at the top of the page.
On API doc pages there is also a filter input field that filters the member rows using the filter string. In addition to filtering by string you can filter the class members by access level, inheritance, and read only. This is done using the checkboxes at the top of the page.
The checkbox at the bottom of the API class navigation tree filters the class list to include or exclude private classes.
Clicking on an empty search field will show your last 10 searches for quick navigation.
Each API doc page (with the exception of Javascript primitives pages) has a menu view of metadata relating to that class. This metadata view will have one or more of the following:
Ext.button.Button
class has an alternate class name of Ext.Button
). Alternate class
names are commonly maintained for backward compatibility.Runnable examples (Fiddles) are expanded on a page by default. You can collapse and expand example code blocks individually using the arrow on the top-left of the code block. You can also toggle the collapse state of all examples using the toggle button on the top-right of the page. The toggle-all state will be remembered between page loads.
Class members are collapsed on a page by default. You can expand and collapse members using the arrow icon on the left of the member row or globally using the expand / collapse all toggle button top-right.
Viewing the docs on narrower screens or browsers will result in a view optimized for a smaller form factor. The primary differences between the desktop and "mobile" view are:
The class source can be viewed by clicking on the class name at the top of an API doc page. The source for class members can be viewed by clicking on the "view source" link on the right-hand side of the member row.
The Ext JS calendar is a powerful new component that allows users to incorporate their date and event data to create stunning custom calendars. The calendar utilizes a minimalistic design philosophy so that it can be extended to cater to any requirements. This minimalistic ideology extends to the data level as well.
The calendar package has been developed to excel in both toolkits, modern and classic. This means that you can create a cross platform solution to display your calendar information on any medium.
For a full example of the calendar integrated with Google Calendars, see our examples page.
You can also find smaller, and more specific examples in our Kitchen Sink:
Your calendar package should be located within the packages folder that came with your Ext JS Premium purchase. This packages folder should be copied to the root packages directory of the ext folder you use to generate applications.
For instance, if you have generated your application using Sencha Cmd, you would move the calendar package from:
{premiumLocation}/ext/packages/calendar
to:
{yourApplication}/ext/packages/calendar
or:
{yourWorkspace}/ext/packages/calendar
Once your package is in appropriately located, you'll need to modify your app.json
file. Open {appDir}/app.json
and add "calendar" to the "requires" block. It should now look like similar to the following code snippet:
"requires": [
"calendar"
],
Do keep in mind that your requires block may contain other items depending on your default theme.
Your application should now be ready to use the calendar!
Note: The calendar package is only available in Ext Premium. For more information about Ext Premium and our other products, please check out the products page.
You can also utilize the calendar package without a Cmd built application. However, you may need to use Cmd to build the initial CSS/JS builds if they do not appear in your package's build folder.
We generally try to include pre-built packages, but sometimes they slip through the cracks and are not available until the next release.
Building a package is quick and simple. The process produces a singular JS/CSS file for inclusion in your non-Cmd application. To build these files, issue the following command from your CLI:
//target a specific theme
sencha package build {themeName}
Classic themes will just be theme names (triton, neptune, etc).
Modern themes will be prepended with "modern-" (modern-neptune).
or
//build for all themes
sencha package build
You should now have a build folder that contains the following built files:
calendar/{toolkit}/calendar.js
calendar/{toolkit}/{theme}/resources/calendar-all.css
You can now include these outputs by whatever method you are using.
At the heart of it, the calendar package is a collection of views that digest and visualize data based on its timeframe (months, days, weeks, etc).
The most common form of the calendar is actually a composite of views, wrapped in panels (more about panels below).
This little snippet will create a full multi-view calendar that displays a compilation of the three most common
calendar views (month, week, day).
Ext.create('Ext.calendar.panel.Panel', {
renderTo: Ext.getBody(),
width:700,
height:700
});
Now that you've seen a few of the views in action, let's talk a little about each view in particular.
Displays a series of weeks, one week per row. Days are arranged in a table like format, each cell represents a single day. There is no time axis for this view.
The view range is calculated to show an entire week based on the value.
Displays a full month. The visible date range is calculated to show the entire month.
Displays a series of days, where each column represents a single day. A vertical time axis is included in this view.
The same as the Days but restricted to a single day.
Each event visible in the view is a widget subclass. Similar to the data model, there is an API defined by Ext.calendar.EventBase and a default implementation in Ext.calendar.Event. The same event class is used across all views, however it is displayed in 3 modes (with matching sass mixins):
weekspan -> Used in view.Weeks for events that have a duration longer than 24 hours. Also used in view.Days for the all day view.
weekinline -> Used in view.Weeks for events that have a duration shorter than 24 hours.
day -> Used in the body of view.Days.
The base view class has a timezone configuration that indicates the timezone to display events in. If one is not specified, it defaults to the current user TZ. This can affect how events are displayed, possibly even different days for the same event.
The base view class has a compact config. This boolean configures whether or not the view is in compact mode. It’s expected that this will be used as a platform config or a responsive config. Setting compact mode by itself does not modify how the view displays, however what it does do is apply the compactOptions config over the top over the current configuration options. These compactOptions are what is used to specify what compactness means for a particular view.
UI events can require validation and the ability to veto them. For some events, a decision can’t be deferred (for example, starting a drag). However, things like dropping an event don’t require immediate processing to resolve. In fact, a remote source may need to be consulted to determine this. To do this in a consistent manner, promises are used to handle the possibly asynchronous nature of the validation. These validation events typically follow this pattern:
listeners: {
validatefoo: : function(view, context) {
context.validate = context.validate.then(function() {
return true;
});
}
}
As we can see above there is a validate promise already on the context object. The user can chain onto the existing promise provided, or create a new one, however it is important that context.validate is overwritten by the time the event handler returns so the user promise can be consumed.
Now that we've discussed the underlying views, let's talk about the things you'll be working with most often. Panels!
While the views themselves are the power behind the calendar, you will likely not interact them directly. Each view is wrapped in a panel that provide a lot of additional controls.
Remember this example?
Ext.create('Ext.calendar.panel.Panel', {
renderTo: Ext.getBody(),
width:700,
height:700
});
Ext.calendar.panel.Panel is actually a composition panel that compiles three different panels into a single view. It also includes navigational controls, a title to show the active value, and a switcher control to navigate between the views. This is the view one would see for a calendar application and will probably be the most commonly consumed component by developers.
Let's look at the view panels that make up the composition panel.
Month utilizes Ext.calendar.panel.Month
Ext.create('Ext.calendar.panel.Month', {
renderTo: Ext.getBody(),
width:700,
height:700
});
Week utilizes Ext.calendar.panel.Week
Ext.create('Ext.calendar.panel.Week', {
renderTo: Ext.getBody(),
width:700,
height:700
});
Day utilizes Ext.calendar.panel.Day.
Ext.create('Ext.calendar.panel.Day', {
renderTo: Ext.getBody(),
width:700,
height:700
});
In addition to the above three panels, there are also panels for the other two views not found in the combined class.
Days utilizes Ext.calendar.panel.Days.
Ext.create('Ext.calendar.panel.Days', {
renderTo: Ext.getBody(),
width:700,
height:700
});
Weeks utilizes Ext.calendar.panel.Weeks.
Ext.create('Ext.calendar.panel.Weeks', {
renderTo: Ext.getBody(),
width:700,
height:700
});
By virtue of being panels, all of these classes gain panel abilities (docking, titles, etc) in addition to including a base header class that can display header information.
These view wrappers relay events and configurations directly onto the panel itself This allows listeners, getters and
setters to be called directly on the panel, without needing to do panel.getView().foo()
.
These panels don’t introduce any new functionality or modify the views in any way. They are just small convenience classes that introduce the headers.
Data is an integral part of the calendar package. Since the calendar can display many different types of views, the data package brings some complexity.
There are two data model types in the calendar package.
The calendar model is essentially a group for events. Several calendars may be displayed on the same view. Typically, a calendar will hold events of a particular related type. The calendar has a method to return the store that will contain the events for that calendar.
An event is an occurrence with a start date, end date, and duration. Each event must belong to one and only one calendar.
For each model type, there is a base (EventBase/CalendarBase) that defines the required interface to use these model types. They are declared as mixins, but have some abstract parts that must be implemented by the consuming class. The calendar package provides a default implementation of both model classes.
Throughout the calendar package, the get/set methods of a model are never called. Instead, all data is accessed/manipulated via getter and setter methods:
record.setTitle(record.getTitle() + ‘!’); // Yes
record.set(‘title’, record.get(‘title’) + ‘!’); // No
The calendar makes no assumptions about the structure of the data provided, only that it exists. This abstraction of data access ensures flexibility for a wide range of data structures to be used.
As an example of this concept, the default model implementation of Ext.calendar.model.Event has a startDate
and
endDate
field on the model. The getDuration
method is calculated based on these values. Another possible
implementation could be to have a startDate
and duration
field on the model and have the getEndDate
be a
calculated quantity. The API makes no distinction here, as long as the EventBase
interface is fulfilled.
There are 3 store types in the calendar package.
The calendar store holds a list of Calendar
. This small extension adds a method to return an EventSource for all
calendars in this store (see below). This store type is the type of store bound to all views.
The event store holds a list of Event
for a particular Calendar
. The store is typically created by calling the
events
method on a Calendar
model. When used with a calendar view, this will happen automatically. The event store
is intended to be filled for a particular date range, which should be governed by the appropriate view. This store type
implements pre-fetching (and pruning) for a smoother experience when switching between dates in the view.
The EventSource store holds an aggregated list of events for all calendars in a Calendars
store, that are valid for
a particular date range. This is a utility class used by the views as a single point of communication. The
responsibility of this class is to control each Events
store to keep a single flattened list of events to
display. The content of this store is driven by the attached Events
stores and the current date range.
Loading calendar data is divided between model types. A typical initial load of a calendar happens in 2 stages:
[{
"calendarId": 1,
“title”: “Personal”
}, {
“calendarId”: 2,
“title”: “Work”
}]
calendarId
are sent to the server. Here is an example of a sample response for calendar's events:[{
"id“: 1001,
“calendarId“: 1,
“endDate“: "2016-05-30T01:30:00.000Z",
“startDate“: "2016-05-30T00:30:00.000Z",
“title“: "Meet with Development"
}, {
“id“: 1002,
“calendarId“: 1,
“endDate“: "2016-05-31T03:00:00.000Z",
“startDate“: "2016-05-31T01:00:00.000Z",
“title“: “Review with Marketing"
}]
Throughout the lifetime of the calendar component, a number of similar requests for events will likely be made for pre-fetching and loading data.
All dates in the data package are to be specified as UTC.
An event that is "all day" must be TZ immune and end at midnight the following day. For example, if an event is all day On Jan 1st and Jan 2nd, then the start of the event is Jan 01 00:00:00 GMT and the end date is Jan 03 00:00:00 GMT.
Calendars have an editable flag. If this is set to false, the UI will not allow adding, editing or removing of events inside the calendar.
Because the forms depend on the model types, they follow much the same pattern. There is a minimal API declared for the forms, nothing specific about the fields. The form receives a record (blank record for creation) and is expected to populate the data. There is both an add and edit form. The default implementation treats these forms as the same.
Fashion theming follows the same pattern as other components found in the framework.
There is one slight addition to theming, because the system allows for specifying colors as part of the data model. As such, the color palette for basic event styling is handled as part of the javascript code. If a calendar does not have a color assigned, a default will be pulled from the pool of calendars and be claimed for that calendar id.
To specify custom colors, there are 3 items to override:
Ext.define('MyPalette', {
override: 'Ext.calendar.theme.Theme',
colors: [
'rgb(44,151,222)',
'rgb(233,75,53)',
'rgb(30,206,109)',
'rgb(156,86,184)',
'rgb(60,214,220)',
'rgb(232,126,3)',
'rgb(0,189,156)'
],
lightColor: 'rgb(238,238,238)',
darkColor: 'rgb(34,34,34)'
});