Store

The Store represents a data container which holds flat data or tree structures. An item in the Store is often called a ´record´ and it is simply an instance of the Model (or any subclass thereof).

Typically, you load data into a store to display it in a Grid or a ComboBox. The Store is the backing data component for any component that is showing data in a list style UI.

The Store offers an API to edit, filter, group and sort the records.

Data is stored in a JSON array

Store with flat data

To create a flat store simply provide an array of JavaScript or JSON objects that describe your records

const store = new Store({
    data : [
        { id : 1, name : 'ABBA', country : 'Sweden' },
        { id : 2, name : 'Beatles', country : 'UK' }
    ]
});

// retrieve record by id
const beatles = store.getById(2);

By default, when using inline data (supplied directly to the store by the app, not loaded remotely by an AjaxStore or CrudManager) the incoming data objects are cloned by the created records. This means that those objects will not get "polluted" when default values are applied, or when records are manipulated later. But cloning reduces record creation performance a bit, if the raw data objects are not directly used elsewhere you can opt out of cloning by setting the useRawData config to true.

Note that if the first object in the incoming data is un-extensible (~immutable), the entire incoming dataset will be cloned even if configured with useRawData: true.

Store with tree data

To create a tree store use children property for descendant records

const store = new Store({
    tree: true,
    data : [
        { id : 1, name : 'ABBA', country : 'Sweden', children: [
            { id: 2, name: 'Agnetha' },
            { id: 3, name: 'Bjorn' },
            { id: 4, name: 'Benny' },
            { id: 5, name: 'Anni-Frid' }
        ]},
    ]
});

// retrieve record by id
let benny = store.getById(4);

Optionally a tree store can consume a flat dataset with nodes that have a parentId property. By configuring the store with tree : true and transformFlatData : true, the flat data is transformed into tree data:

const store = new Store({
    tree              : true,
    transformFlatData : true,
    data              : [
        { id : 1, name : 'ABBA', country : 'Sweden' },
        { id : 2, name : 'Agnetha', parentId : 1 },
        { id : 3, name : 'Bjorn', parentId : 1 },
        { id : 4, name : 'Benny', parentId : 1 },
        { id : 5, name : 'Anni-Frid', parentId : 1 }
    ]
});

Retrieving and consuming JSON

For both flat stores or tree stores it is possible to retrieve the data of all records in JSON format:

const jsonString = store.json;

// or

const jsonArray = store.toJSON();

To plug the JSON data back in later:

store.data = JSON.parse(jsonString);

// or

store.data = jsonArray;

Lazy loading

A store can be configured with lazyLoad set to true. This will make the store request records when they are needed, rather than the complete dataset at once. The request is intercepted by implementing the requestData function. Each request will be made up of 1 chunk before and after the requested index (which gives a total of 2 chunks). The chunk size can be configured in the lazyLoad config.

There is a guide for implementing lazy loading in Grid.

Paging

A Store can be paged remotely by setting the remotePaging config to true. For a non-AjaxStore, data will be requested by the Store by calling the implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.

const store = new Store({
   remotePaging : true,
   requestData({ page, pageSize }){
      const start = (page - 1) * pageSize;
      const data = allRecords.splice(start, start + pageSize);

      return {
         data,
         total : allRecords.length
      }
   }
})

Remote sorting

A Store can be sorted remotely by setting the remoteSort config to true. This makes it possible to use the built-in sorting features of the Store and corresponding UI functionality, without using local data. For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.

const store = new Store({
   remoteSort   : true,
   remotePaging : true,
   requestData({ sorters, page, pageSize }){
      const sortedRecords = [...allRecords];
      sorters?.forEach(sorter => sortedRecords.sort((a,b) => {
         const { field, ascending } = sorter;

         if (!ascending) {
             ([b, a] = [a, b]);
         }

         return a[field] > b[field] ? 1 : (a[field] < b[field] ? -1 : 0)
      });

      const start = (page - 1) * pageSize;
      const data = sortedRecords.splice(start, start + pageSize);

      return {
         data,
         total : allRecords.length
      }
   }
})

For AjaxStore, data will be loaded via the configured readUrl.

Remote filtering

A Store can be filtered remotely by setting the remoteFilter config to true. This makes it possible to use the built-in filtering features of the Store and corresponding UI functionality, without using local data.

For a non-AjaxStore, data will be requested by the Store by calling the implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.

const store = new Store({
   remoteFilter : true,
   remoteSort   : true,
   remotePaging : true,
   requestData({ filters, sorters, page, pageSize }){
      let filteredRecords = [...allRecords];

      filters?.forEach(filter => {
         const { field, operator, value, caseSensitive } = filter;

         if(operator === '='){
             filteredRecords = filteredRecords.filter(r => r[field] === value);
         }
         else {
             /// ... implement other filter operators
         }
      });

      sorters?.forEach(sorter => filteredRecords.sort((a,b) => {
         const { field, ascending } = sorter;

         if (!ascending) {
             ([b, a] = [a, b]);
         }

         return a[field] > b[field] ? 1 : (a[field] < b[field] ? -1 : 0)
      }));

      const start = (page - 1) * pageSize;
      const data = filteredRecords.splice(start, start + pageSize);

      return {
         data,
         total : filteredRecords.length
      }
   }
})

For AjaxStore, data will be loaded via the configured readUrl.

Getting record count

To get the number of "visible" records in the store (records that would be shown when using the Store as the data source for a Grid or similar), use the count property. This will return the number of records in the store after filtering and grouping has been applied, including the generated group headers and footers but excluding any records inside collapsed parents or group headers:

const visibleRecords = store.count;

To get other counts, such as the total number of data records in the store including those collapsed away and filtered out, use the more flexible getCount method:

// Include records that have been filtered out,
// as well as any records inside collapsed groups or tree nodes.
const records = store.getCount({
    collapsed   : true,
    filteredOut : true
});

// Including group headers + summary records
const records = store.getCount({
    headersFooters : true
});

// All records, including group headers and filtered out records
const allRecords = store.getCount({
    all : true
});

Sharing stores

You cannot directly share a Store between widgets, but the data in a Store can be shared. There are two different approaches depending on your needs, sharing data and chaining stores:

Shared data

To create 2 widgets that share data, you can create 2 separate stores and pass records of the first store as the dataset of the second store.

let combo1 = new Combo({
    appendTo : document.body,
    store    : new Store({
        data : [
            { id : 1, name : 'ABBA', country : 'Sweden' },
            { id : 2, name : 'Beatles', country : 'UK' }
        ]
    }),
    valueField   : 'id',
    displayField : 'name'
});

let combo2 = new Combo({
    appendTo : document.body,
    store    : new Store({
        data : combo1.store.records
    }),
    valueField   : 'id',
    displayField : 'name'
});

combo1.store.first.name = 'foo';
combo2.store.first.name; // "foo"

Chained stores

Another more powerful option to share data between widgets is to create chained stores. The easiest way to create a chained store is to call chain function.

let combo1 = new Combo({
    appendTo : document.body,
    store    : new Store({
        data : [
            { id : 1, name : 'ABBA', country : 'Sweden' },
            { id : 2, name : 'Beatles', country : 'UK' }
        ]
    }),
    valueField   : 'id',
    displayField : 'name'
});

let combo2 = new Combo({
    appendTo     : document.body,
    store        : combo1.store.chain(),
    valueField   : 'id',
    displayField : 'name'
});

combo1.store.first.name = 'foo';
combo2.store.first.name; // "foo"

A chained store can optionally be created with a filtering function, to only contain a subset of the records from the main store. In addition, the chained store will reflect record removals/additions to the master store, something the shared data approach will not.

Non-homogeneous data structures

You can use different Model classes to represent the records in the store by overriding the createRecord method:

const store = new Store ({
    modelClass : Gate,
    readUrl    : 'data/the-airport.json',
    autoLoad   : true,
    // The default model is a Gate (see above) and in this createRecord method, we can decide at runtime based
    // on the data which model class to use. This is useful when your record types aren't homogenous.
    createRecord(data) {
        let modelClass = this.modelClass;
        if (data.type === 'terminal') {
            modelClass = Terminal;
        }
        return new modelClass(data, this);
    }
},

Configs

56

Common

Commit changes automatically

autoLoad: Boolean

For a non-AjaxStore, the autoLoad config will only take effect if the store is configured as lazyLoad, remoteSort, remoteFilter or remotePaging. In these cases, it will immediately after creation, perform a request by calling the requestData function.

Raw data to load initially.

Expects an array of JavaScript objects, with properties matching store's fields (defined on its model or in the fields config).

const store = new Store({
    data : [
        { id : 1, name : 'Linda', city : 'NY' },
        { id : 2, name : 'Olivia', city : 'Paris' },
        ...
    ]
});

An array of field definitions used to create a Model (modelClass) subclass. Optional. If the Model already has fields defined, these fields will extend those.

const store = new Store({
    fields : ['name', 'city', 'company'],
    data   : [
        { id : 1, name : 'Mark', city : 'London', company : 'Cool inc' },
        ...
    ]
});

See Model for more info on defining fields, changing data source and mapping fields to nested objects.

Note that pre-created record instances supplied to the store are kept as is and thus these fields will not apply to them.

Initial groupers, specify to have store grouped automatically after initially setting data

id: String | NumberAlso a property

Store's unique identifier. When set the store is added to a store map accessible through Store.getStore(id).

lazyLoad: Boolean | ObjectAlso a property

If set to true, or a config object, this makes the store load new records when needed. When a record that is not already loaded is requested, the requestData function is called. Please read the guide to learn more on how to configure lazy loading.

LazyLoading is currently not supported in Calendar, Gantt, TaskBoard.

ParameterTypeDescription
lazyLoadObject

Lazy load config

lazyLoad.chunkSizeNumber

The number of records to be loaded before and after the requested index.

Class used to represent records in the store, should be a subclass of Model. Only applies when supplying data to the store (load, add), any supplied record instances are kept as is.

class MyModel extends Model {
    static get fields() {
        return [
            'name',
            'city',
            'company'
        ]
    }
}

const store = new Store({
    modelClass : MyModel,
    data : [
        { id : 1, name : 'Mark', city : 'London', company : 'Cool inc' },
        ...
    ]
});
requestData: function

In a non-AjaxStore, configured with lazyLoad, remoteSort, remoteFilter or remotePaging, the function provided here is called when the Store needs new data, which will happen:

When implementing this, it is expected that what is returned is an object with a data property containing the records requested. What is requested will be specified in the params object, which will differ depending on the source of the request.

For lazyLoad, the params object will contain a startIndex and a count param. It is expected for the implementation of this function to provide a data property containing the number of records specified in the count param starting from the specified startIndex.

class MyStore extends Store {
   async requestData({startIndex, count}){
      const response = await getData(startIndex, count);
      return {
         data : response.records,
         total : response.totalRecordCount
      }
   }
}

For remotePaging, the params object will contain a page and a pageSize param. It is expected for the implementation of this function to provide a data property containing the number of records specified in the pageSize param starting from the specified page.

class MyStore extends Store {
   requestData({page, pageSize}){
      const start = (page - 1) * pageSize;
      const data = allRecords.splice(start, start + pageSize);

      return {
         data,
         total : allRecords.length
      }
   }
}

For lazyLoad it is recommended, and for remotePaging it is required, to include a total property which reflects the total amount of records available to load. If the total property is omitted (when lazyLoad), certain features and functions are disabled:

  • The component (Grid for example) is not aware of the total number of records, which will make the scrollbar's thumb change size and position when new records are loaded.
  • The store don't know when to stop requesting new records. The total property will be set to the index of the last record loaded after requestData returns with fewer records than requested.

If remoteSort is active, the params object will contain a sorters param, containing a number of sorter objects.The sorter objects will look like this:

{
    "field": "name",
    "ascending": true
}

If remoteFilter is active, the params object will contain a filters param, containing a number of filters objects. The filter objects will look like this:

{
    "field": "country",
    "operator": "=",
    "value": "sweden",
    "caseSensitive": false
}

The Base implementation of this function does nothing, you need to create your own subclass with an implementation.

Configuration parameter to pass a function to be used as requestData in non-AjaxStore.

ParameterTypeDescription
paramsLazyLoadRequestParams | PagingRequestParams

Object containing info of which records is requested

Initial sorters, format is:

{ sorters : [{ field: 'name', ascending: false }, ...] }
// or
{ sorters : ['name', ...] }

Configure with true to sync loaded data instead of replacing existing with a new dataset.

By default (or when configured with false) assigning to store.data replaces the entire dataset with a new one, creating all new records:

store.data = [ { id : 1, name : 'Saitama' } ];

const first = store.first;

store.data = [ { id : 1, name : 'One-Punch man' } ];

// store.first !== first;

When configured with true the new dataset is instead synced against the old, figuring out what was added, removed and updated:

store.data = [ { id : 1, name : 'Saitama' } ];

const first = store.first;

store.data = [ { id : 1, name : 'One-Punch man' } ];

// store.first === first;

After the sync, any configured sorters, groupers and filters will be reapplied.

Threshold

The sync operation has a configurable threshold, above which the operation will be treated as a batch/refresh and only trigger a single refresh event. If threshold is not reached, individual events will be triggered (single add, remove and possible multiple update). To enable the threshold, supply a config object with a threshold property instead of true:

const store = new Store({
    syncDataOnLoad : {
        threshold : '20%'
    }
});

threshold accepts numbers or strings. A numeric threshold means number of affected records, while a string is used as a percentage of the whole dataset (appending % is optional). By default no threshold is used.

Missing fields

The value of any field not supplied in the new dataset is by default kept as is (if record is not removed by the sync). This behaviour is configurable, by setting keepMissingValues : false in a config object it will reset any unspecified field back to their default values:

const store = new Store({
    syncDataOnLoad : {
        keepMissingValues : false
    }
});

Considering the following sync operation:

// Existing data
{ id : 1, name : 'Saitama', powerLevel : 100 }
// Sync data
{ id : 1, name : 'One-Punch Man' }

The result would by default (or when explicitly configured with true) be:

{ id : 1, name : 'One-Punch Man', powerLevel : 100 }

If configured with keepMissingValues : false it would instead be:

{ id : 1, name : 'One-Punch Man' }
Never enable syncDataOnLoad on a chained store, it will create an infinite loop when it is populated from the main store (the main store can use the setting)
listenersEvents

Advanced

allowNoId: Boolean= true

Specify false to prevent loading records without ids, a good practice to enforce when syncing with a backend.

By default, Store allows loading records without ids, in which case a generated id will be assigned.

Specifies target to filter and sort after applying changeset:

  • 'changes' - apply sort and filter to changeset only (see more below)
  • 'none' - do not apply sort and filter

changes behavior

If the store has filters in effect when the changeset is applied, the following rules will determine how the filtered values are affected:

  • Among added records, only those that match the filter will be included in the filtered set
  • Among updated records, those that did not previously match the filter but now do will be added to the filtered set, and those that did match but no longer do will also remain in the filtered set. This means that new records may appear in the filtered set as a result of applyChanges, but records will not disappear until filters are re-applied.

Does not apply if the store is remotely filtered.

Set to false to not record transaction during applyChangeset call

To have all groups initially loaded start collapsed, configure this as true.

Note that this only affects the initial load of the store. Subsequent reloads maintain current group state where possible.

Reference to STM manager

A Collection, or Collection config object to use to contain this Store's constituent records.

Store class to use when creating the store when it is a part of a CrudManager.

crudManager : {
     eventStore {
         storeClass : MyEventStore
     }
}
useLocaleSort: Boolean | String | Object= falseStoreSort

Use localeCompare() when sorting, which lets the browser sort in a locale specific order. Set to true, a locale string or a locale config to enable.

Enabling this has big negative impact on sorting performance. For more info on localeCompare(), see MDN.

Examples:

const store = new Store({
    // Swedish sorting
    useLocaleSort : 'sv-SE'
});

const store = new Store({
    // Swedish sorting with custom casing order
    useLocaleSort : {
        locale    : 'sv-SE',
        caseFirst : 'upper'
    }
});

Can also be configured on a per-sorter basis:

store.sort({ field: 'name', useLocaleSort : 'sv-SE' });
useRawData: Boolean | Object

Retools the loaded data objects instead of making shallow copies of them. This increases performance but pollutes the incoming data.

This setting is off by default, but is turned on automatically unless explicitly configured when data is loaded using an AjaxStore (configured with a readUrl) or a CrudManager (configured to load data remotely).

// No duplicate id checking, no type conversions
new Store({ useRawData : true });

Also allows disabling certain steps in data loading, to further improved performance. Either accepts an object with the params described below or true which enables disableDuplicateIdCheck.

new Store({
  // No type conversions only
  useRawData : {
    disableTypeConversion : true
  }
});

Note that if the first object in the incoming data is determined to be un-extensible (~immutable), the entire incoming dataset will be cloned.

Also note that since incoming data objects gets polluted with this setting on, reusing the same data objects elsewhere might lead to unexpected behavior.

When binding to data in frameworks with this setting enabled, the same principles as for framework state applies - an object in the incoming data must be replaced instead of mutated for a change to be detected. See for example React's explanation here

ParameterTypeDescription
disableDuplicateIdCheckBoolean

Data must not contain duplicate ids, check is bypassed.

disableDefaultValueBoolean

Default values will not be applied to record fields.

disableTypeConversionBoolean

No type conversions will be performed on record data. Incoming data must be in the correct format expected by each field, for example dates must be Date objects.

Chained store

Array of field names that should trigger filtering of chained store when the fields are updated.

Only applies to chained stores

Function used to filter records in the masterStore into a chained store. If not provided, all records from the masterStore will be included in the chained store. Return true to include the passed record, or a false to exclude it.

Only applies to chained stores

ParameterTypeDescription
recordModel
Returns: Boolean
chainFilters: Boolean= falseStoreChained

If true, chained stores will apply filters from the master store. Filters flagged with ignoreForChain will be ignored.

Only applies to chained stores

Method names calls to which shouldn't be relayed to master store.

Only applies to chained stores

Method names calls to which should be relayed to master store.

Only applies to chained stores

If true, collapsed records in original tree will be excluded from the chained store.

Only applies to chained stores, and not when chaining using chainTree()

Set to true to prevent including links (when grouping by array field)

Only applies to chained stores

Master store that a chained store gets its records from.

Only applies to chained stores

syncOrder: Boolean= falseStoreChained

If true, changing the order of records in a flat chained store (for example by using the RowReorder feature in a Grid-based widget) will also change the order of records in the master store.

Note that this config does not apply to chained tree stores (created using chainTree). Chained tree stores always sync the order of their records with the master store.

Example usage:

store.chain(record => record.percent < 10, null, {
  syncOrder : true
});

The predictability of the outcome depends on the order of the records in both stores, and if the subset of records in the chained store is contiguous. For example, if the master store has records A B C D E, and the chained store has E C A, it will be difficult for users to predict the outcome of moving E to between C A.

syncSort: Boolean= trueStoreChained

If true, chained stores will be sorted when the master store is sorted. Note that this replaces any existing sorters defined on the chained store.

Only applies to chained stores

Filtering

Specify one or more CollectionFilter config objects to apply initially.

For example:

 // Configure the store to filter in clients over the age of 30
 new Store({
     ...,
     filters : [{
         property : 'age',
         value    : 30,
         operator : '>'
     }],
     ...
 })

or:

 // Configure the store to filter based on a complex operation
 new Store({
     ...,
     filters : [{
         filterBy(record) {
             // Return true or false for filtering in or out
             return shouldClientBeVisible(record);
         }
     }],
     ...
 })

Specify true to reapply filters when a record is added to or moved within the store. This includes tree node operations like indent/outdent in Gantt, or any move operation that changes a node's parent.

Specify true to reapply filters when a record is updated in the store. You can also provide an array of field names, to only re-filter when certain data fields are updated.

ParameterTypeDescription
reapplyFilterOnUpdate.fieldsString[]

Specify true to reapply sorting when a record is updated in the store. You can also provide an array of field names, to only trigger sort when certain data fields are updated.

If the app processes many records or many record fields in a loop or similar, be sure to temporarily disable this setting. Otherwise, each change will trigger a sort, which will make the processing slow

ParameterTypeDescription
reapplySortersOnUpdate.fieldsString[]

Fields that reapply sorting when updated

Set this to true to activate remote filtering in this Store. This makes it possible to use the built-in filtering features of the Store and corresponding UI functionality, without using local data.

For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.

For AjaxStore, data will be loaded via the configured readUrl.

Other

When set to true, restores the expanded states of tree nodes when reloading data.

Enable sparse index handling. When enabled, the store's model will be augmented with a sparseIndex field (unless it already exists) which will be automatically managed by the store. When adding or inserting records into the store, sparse indexes will be generated for those records. When moving records, their sparse index will be updated with a fractional number. They will be used to sort records when no other sorter is defined on the store.

Sparse indexes are a tree-defining property. They will also be used to determine the order of records when persisting the store's data. When using sparse indexes in a tree store, the store's parentId will also be made persistent to allow reconstruction of the tree structure when loading data.

When using sparse indexes, the other tree-defining properties parentIndex and orderedParentIndex will no longer be persistent. Their values will still be updated when items are added, removed, or re-ordered, but they won't be marked as dirty and won't be included when persisting the store's data. If it is necessary to persist these fields, use hierarchyModificationDataToWrite.

Verify that loaded data does not contain any generated ids. If it does, a warning is logged on console.

Set this to false to disable the check and give a very minor performance boost.

Paging

The name of the parameter to use when requesting pages of data using the zero based index of the required page's starting record.

When the Store is paged by configuring remotePaging, this value will be included in the load requests.

Note: Setting pageSize at runtime will automatically reload the page.

The name of the parameter to use when requesting pages of data, representing the configured pageSize value.

The name of the parameter to use when requesting pages of data using the one based page number required.

Set this to true to activate remote paging in this Store. Makes it possible to use the loadPage, nextPage, and previousPage functions. Or add the PagingToolbar to control what page to load.

For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.

Records

createRecord: function

Creates a model instance, used internally when data is set/added. Provide this method for your own custom conversion from data to record.

ParameterTypeDescription
data*

Json data

skipExposeBoolean

Supply true when batch setting to not expose properties multiple times

Returns: Model

Remote

The name of the parameter to use to pass any filters when loading data remotely.

Note: When this is set, filters must be defined using a field name, an operator and a value to compare, not a comparison function.

Sorting

Specify true to sort this store after records are added.

Set this to true to activate remote sorting in this Store. This makes it possible to use the built-in sorting features of the Store and corresponding UI functionality, without using local data.

For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.

For AjaxStore, data will be loaded via the configured readUrl.

The name of the parameter to use to pass any sorters when loading data remotely.

Note: When this is set, sorters must be defined using a field name and an ascending flag, not a sort function.

Tree

autoTree: Boolean= true

Automatically detect from set data if used as tree store or flat store. If tree is explicitly set to false, then this value will be overruled and no tree detection performed.

Set to true to fire a 'remove' event when moving a node (to mimic the behavior of versions < 6.0).

Set to true to on load transform a flat dataset with raw objects containing parentId into the format expected for tree data.

Example input format:

[
  { id : 1, name : 'Parent' },
  { id : 2, name : 'Child', parentId : 1 }
]

Will be transformed into:

[
  {
    id       : 1,
    name     : 'Parent',
    children : [
      { id : 2, name : 'Child', parentId : 1 }
    ]
  }
]
tree: Boolean

true to act as a tree store.

Misc

Properties

75

Common

id: String | NumberreadonlyAlso a config

Store's unique identifier.

lazyLoad: Boolean | ObjectAlso a config

If set to true, or a config object, this makes the store load new records when needed. When a record that is not already loaded is requested, the requestData function is called. Please read the guide to learn more on how to configure lazy loading.

LazyLoading is currently not supported in Calendar, Gantt, TaskBoard.

ParameterTypeDescription
lazyLoadObject

Lazy load config

lazyLoad.chunkSizeNumber

The number of records to be loaded before and after the requested index.

Advanced

Specifies target to filter and sort after applying changeset:

  • 'changes' - apply sort and filter to changeset only (see more below)
  • 'none' - do not apply sort and filter

changes behavior

If the store has filters in effect when the changeset is applied, the following rules will determine how the filtered values are affected:

  • Among added records, only those that match the filter will be included in the filtered set
  • Among updated records, those that did not previously match the filter but now do will be added to the filtered set, and those that did match but no longer do will also remain in the filtered set. This means that new records may appear in the filtered set as a result of applyChanges, but records will not disappear until filters are re-applied.

Does not apply if the store is remotely filtered.

Set to false to not record transaction during applyChangeset call

isChained: BooleanreadonlyStoreChained

Is this a chained store?

A special Symbol signalizing treeify method that the current record grouping should be stopped.

const newRoot = workerStore.treeify([
    // group workers by company
    worker => {
        // if the worker is unemployed we don't put it in a group
        // we just show such record on the root level
        if (!worker.company) {
            return Store.StopBranch
        }

        return worker.company;
    }
]);

Class hierarchy

isStore: Boolean= truereadonly
Identifies an object as an instance of Store class, or subclass thereof.
isStore: Boolean= truereadonlystatic
Identifies an object as an instance of Store class, or subclass thereof.
isStoreChained: Boolean= truereadonlyStoreChained
Identifies an object as an instance of StoreChained class, or subclass thereof.
isStoreChained: Boolean= truereadonlystaticStoreChained
Identifies an object as an instance of StoreChained class, or subclass thereof.
isStoreChanges: Boolean= truereadonlyStoreChanges
Identifies an object as an instance of StoreChanges class, or subclass thereof.
isStoreChanges: Boolean= truereadonlystaticStoreChanges
Identifies an object as an instance of StoreChanges class, or subclass thereof.
isStoreCRUD: Boolean= truereadonlyStoreCRUD
Identifies an object as an instance of StoreCRUD class, or subclass thereof.
isStoreCRUD: Boolean= truereadonlystaticStoreCRUD
Identifies an object as an instance of StoreCRUD class, or subclass thereof.
isStoreFilter: Boolean= truereadonlyStoreFilter
Identifies an object as an instance of StoreFilter class, or subclass thereof.
isStoreFilter: Boolean= truereadonlystaticStoreFilter
Identifies an object as an instance of StoreFilter class, or subclass thereof.
isStoreGroup: Boolean= truereadonlyStoreGroup
Identifies an object as an instance of StoreGroup class, or subclass thereof.
isStoreGroup: Boolean= truereadonlystaticStoreGroup
Identifies an object as an instance of StoreGroup class, or subclass thereof.
isStorePaging: Boolean= truereadonlyStorePaging
Identifies an object as an instance of StorePaging class, or subclass thereof.
isStorePaging: Boolean= truereadonlystaticStorePaging
Identifies an object as an instance of StorePaging class, or subclass thereof.
isStoreRelation: Boolean= truereadonlyStoreRelation
Identifies an object as an instance of StoreRelation class, or subclass thereof.
isStoreRelation: Boolean= truereadonlystaticStoreRelation
Identifies an object as an instance of StoreRelation class, or subclass thereof.
isStoreSearch: Boolean= truereadonlyStoreSearch
Identifies an object as an instance of StoreSearch class, or subclass thereof.
isStoreSearch: Boolean= truereadonlystaticStoreSearch
Identifies an object as an instance of StoreSearch class, or subclass thereof.
isStoreSort: Boolean= truereadonlyStoreSort
Identifies an object as an instance of StoreSort class, or subclass thereof.
isStoreSort: Boolean= truereadonlystaticStoreSort
Identifies an object as an instance of StoreSort class, or subclass thereof.
isStoreSparseIndex: Boolean= truereadonlyStoreSparseIndex
Identifies an object as an instance of StoreSparseIndex class, or subclass thereof.
isStoreSparseIndex: Boolean= truereadonlystaticStoreSparseIndex
Identifies an object as an instance of StoreSparseIndex class, or subclass thereof.
isStoreState: Boolean= truereadonlyStoreState
Identifies an object as an instance of StoreState class, or subclass thereof.
isStoreState: Boolean= truereadonlystaticStoreState
Identifies an object as an instance of StoreState class, or subclass thereof.
isStoreStm: Boolean= truereadonlyStoreStm
Identifies an object as an instance of StoreStm class, or subclass thereof.
isStoreStm: Boolean= truereadonlystaticStoreStm
Identifies an object as an instance of StoreStm class, or subclass thereof.
isStoreSum: Boolean= truereadonlyStoreSum
Identifies an object as an instance of StoreSum class, or subclass thereof.
isStoreSum: Boolean= truereadonlystaticStoreSum
Identifies an object as an instance of StoreSum class, or subclass thereof.
isStoreSync: Boolean= truereadonlyStoreSync
Identifies an object as an instance of StoreSync class, or subclass thereof.
isStoreSync: Boolean= truereadonlystaticStoreSync
Identifies an object as an instance of StoreSync class, or subclass thereof.
isStoreTree: Boolean= truereadonlyStoreTree
Identifies an object as an instance of StoreTree class, or subclass thereof.
isStoreTree: Boolean= truereadonlystaticStoreTree
Identifies an object as an instance of StoreTree class, or subclass thereof.
isEventsEvents

Filtering

Specify true to reapply sorting when a record is updated in the store. You can also provide an array of field names, to only trigger sort when certain data fields are updated.

If the app processes many records or many record fields in a loop or similar, be sure to temporarily disable this setting. Otherwise, each change will trigger a sort, which will make the processing slow

ParameterTypeDescription
reapplySortersOnUpdate.fieldsString[]

Fields that reapply sorting when updated

Other

currentPage: NumberreadonlyStorePaging

If the store is paged, yields the current page number.

formattedJSON: Stringreadonly

Pretty printed version of json

Returns all the group header records

json: String

Retrieve or set the data of all records as a JSON string

const store = new Store({
    data : [
        { id : 1, name : 'Superman' },
        { id : 2, name : 'Batman' }
    ]
});

const jsonString = store.json;

//jsonString:
'[{"id":1,"name":"Superman"},{"id":2,"name":"Batman"}]
stores: Store[]static

Get all registered stores

Verify that loaded data does not contain any generated ids. If it does, a warning is logged on console.

Set this to false to disable the check and give a very minor performance boost.

Paging

isPaged: BooleanreadonlyStorePaging

Yields true if this Store is loaded page by page. See the remotePaging config.

lastPage: NumberreadonlyStorePaging

If the store is paged, yields the highest page number in the dataset as calculated from the 'total' returned in the last page data block loaded.

When the Store is paged by configuring remotePaging, this value will be included in the load requests.

Note: Setting pageSize at runtime will automatically reload the page.

Records

allRecords: Model[]readonly

Returns all locally available records from the store, ignoring any filters and including grouping headers / footers.

Setting autoCommit to true automatically commits changes to records.

changes: ObjectreadonlyStoreCRUD

Get uncommitted changes as an object of added/modified/removed arrays of records.

// Format:
{
     added: [], // array of Core.data.Model
     modified: [], // array of Core.data.Model
     removed: [] // array of Core.data.Model
}
ParameterTypeDescription
changes.addedModel[]

Records that have been added

changes.modifiedModel[]

Records that have changes to persistable fields

changes.removedModel[]

Records that have been removed

count: Numberreadonly

Record count, including records added for group headers etc., excluding collapsed or filtered away records. That is, count is the "visible record count", if the store is used in a Grid or other component that visualize the records.

Consider the following dataset loaded into a Store:

[
  { id : 1, name : 'Linda', city : 'NY' },
  { id : 2, name : 'Olivia', city : 'NY' },
  { id : 3, name : 'John', city : 'Stockholm' }
]

// count === 3

Grouping by city yields the following records in the Store (pseudocode):

store.group('city');

[
  { name : 'Group NY', groupHeader : true, expanded : true },
  { id : 1, name : 'Linda', city : 'NY' },
  { id : 2, name : 'Olivia', city : 'NY' },
  { name : 'Group Stockholm', groupHeader : true },
  { id : 3, name : 'John', city : 'Stockholm', expanded : true }
]

// count === 5

Collapsing the Stockholm group yields the following records in the Store (pseudocode):

store.collapse(store.getAt(3));

[
  { name : 'Group NY', groupHeader : true, expanded : true },
  { id : 1, name : 'Linda', city : 'NY' },
  { id : 2, name : 'Olivia', city : 'NY' },
  { name : 'Group Stockholm', groupHeader : true, expanded : false }
]

// count === 4

Applying a filter further affects the count (pseudocode):

store.filter('name', 'Linda');

[
  { name : 'Group NY', groupHeader : true, expanded : true },
  { id : 1, name : 'Linda', city : 'NY' }
]

// count === 2

If you need a different value for count in your app, for example ignoring filters, or including collapsed away records, please use the more flexible getCount function instead.

If the store is configured with lazyLoad, this number is based on the total amount of records specified in the response given to the requestData function.

Sets data in the store.

Expects an array of JavaScript objects, with properties matching store's fields (defined on its model or in the fields config).

Called on initialization if data is in the config, otherwise call it yourself after for example using fetch to get remote data:

store.data = [
    { id : 1, name : 'Linda', city : 'NY' },
    { id : 2, name : 'Olivia', city : 'Paris' },
    ...
];

Can also be used to get an array of the current raw data objects from all records in the store (ignoring filtering and grouping):

console.log(store.data);
// [
//     { id : 1, name : 'Linda', city : 'NY' },
//     { id : 2, name : 'Olivia', city : 'Paris' },
//     ...
// ]

You should not modify the objects in the array, neither the store nor the record will be aware of the changes.

first: Modelreadonly

Get the first record locally available in the store.

hasChanges: BooleanreadonlyStoreCRUD

Boolean flag, indicating whether the store has any data changes (its changes accessor returns a non-empty object). Cheaper than changes accessor itself, because it does not clone some internal data structures.

last: Modelreadonly

Get the last record locally available in the store.

Class used to represent records. Defaults to class Model.

records: Model[]readonly

Returns all locally available "visible" records. Note: The returned value may not be mutated!

totalCount: Number

Yields the complete dataset size, ignoring filtering and grouping. If the store is paged, it returns the total value provided in the page load request response, or manually set.

Sort, group & filter

Currently applied filters. A collection of CollectionFilter instances.

Currently used groupers. To set groupers when remote sorting is enabled by sortParamName you should use setGroupers instead to be able to wait for the operation to finish.

isFiltered: BooleanreadonlyStoreFilter

Check if store is filtered

isGrouped: BooleanreadonlyStoreGroup

Is store currently grouped?

isSorted: BooleanreadonlyStoreSort

Is store sorted?

Currently applied sorters

Tree

isTree: BooleanreadonlyStoreTree

true if this Store is configured to handle tree data (with tree : true) or if this is a chained store and the master store is a tree store.

Returns all leaf records in a tree store

rootNode: Modelreadonly

The invisible root node of this tree.

Lifecycle

configBase

Misc

Functions

98

Chained store

Creates a chained store, a new Store instance that contains a subset of the records from current store. Which records is determined by a filtering function, which is reapplied when data in the base store changes.

// Chain all records
const all = store.chain();

// Or a subset using a filter function
const oldies = store.chain(record => record.age > 50);

If you want to chain a tree store, consider using chainTree instead. It will create a new tree store with links to the records in this store. This will let you expand/collapse and filter nodes in the chained store without affecting the original store.

If this store is a tree store, then the resulting chained store will be a tree store sharing the same root node, but only child nodes which pass the chainedFilterFn will be considered when iterating the tree through the methods such as traverse or forEach.

ParameterTypeDescription
chainedFilterFnfunction

An optional filter function called for every record to determine if it should be included (return true / false). Leave it out to include all records.

chainedFieldsString[]

Array of fields that trigger filtering when they are updated

configStoreConfig

Additional chained store configuration. See Store#configs

Returns: Store

Creates a chained tree store, a new Store instance that contains a subset of the records from current store. Which records is determined by a filtering function, which is reapplied when data in the base store changes.

// Chain all nodes
const fullTree = store.chainTree();
// Or a subset
const oldies = store.chainTree(record => record.age > 50);

The resulting chained store will be a tree store with its own root node, under which all children are links to the nodes in this store. This allows for expanding/collapsing and filtering nodes in the chained store without affecting the original store.

ParameterTypeDescription
chainedFilterFnfunction

An optional filter function called for every leaf record to determine if it should be included (return true / false). Leave it out to include all records.

chainedFieldsString[]

Array of fields that trigger filtering when they are updated

configStoreConfig

Additional chained store configuration. See Store#configs

Returns: Store

Updates records available in a chained store by filtering the master store records using chainedFilterFn

CRUD

Add records to store.

ParameterTypeDescription
recordsModel | Model[] | Object | Object[]

Array of records/data or a single record/data to add to store

silentBoolean

Specify true to suppress events

Returns: Model[] -

Added records

Applies a set of changes (presumable from a backend) expressed as an object matching the format outputted by the changes property: { added : [], modified/updated : [], removed : [] }

added is expected to be an array of raw data objects consumable by the stores model class for records to add to the store (see example snippet below).

modified (or updated for compatibility with Schedulers CrudManager) is expected to have the same format as added, but should always include the id of the record to update.

Records that have been created locally and gets assigned a proper id by the backend are expected to also pass a phantomId field (name of the field is configurable using the phantomIdField arg, more info on phantom ids below), to match it with the current id of a local record (id will contain the new id).

Note that it is also possible to pass this phantomId -> id mapping in the added array. When encountering a record in that array that already exists in the local store, it will be treated the same way as a record in the modified array.

removed is expected to be an array of objects with the { id : xx } shape. Any matches on an id in the store will be removed, those and any non-matches will also be cleared from the change tracking of the store.

If the store has filters in effect when the changeset is applied, the following rules will determine how the filtered values are affected:

  • Among added records, only those that match the filter will be included in the filtered set
  • Among updated records, those that did not previously match the filter but now do will be added to the filtered set, and those that did match but no longer do will also remain in the filtered set. This means that new records may appear in the filtered set as a result of applyChanges, but records will not disappear until filters are re-applied.

As an example, consider a store with the following initial state and some operations performed on it:

// Load some data
store.data = [
    { id : 1, name : 'Minerva' },
    { id : 2, name : 'Mars' },
    { id : 3, name : 'Jupiter' }
];
// Add a new record. It gets assigned a generated id,
// for example, 'generated56'
store.add({ name : 'Artemis' });
// Remove Jupiter
store.remove(3);

After syncing those operations to a custom backend (however, you chose to solve it in your application), we might get the following response (see "Transforming a response to the correct format" below if your backend responds in another format):

const serverResponse = {
    added : [
        // Added by the backend, will be added locally
        { id : 5, name : 'Demeter' }
    ],

    updated : [
        // Will change the name of Minerva -> Athena
        { id : 1, name : 'Athena' },
        // Will set proper id 4 for Artemis
        { $PhantomId : 'generated56', id : 4 }
    ],

    removed : [
        // Confirmed remove of Jupiter
        { id : 3 },
        // Removed by the backend, Mars will be removed locally
        { id : 2 }
    ]
};

If that response is then passed to this function:

store.applyChangeset(serverResponse);

The result will be the following data in the store:

[
    { id : 1, name : 'Athena' }, // Changed name
    { id : 4, name : 'Artemis' }, // Got a proper id
    { id : 5, name : 'Demeter' } // Added by the backend
]

Phantom ids

When a record is created locally, it is always assigned a generated id. That id is called a phantom id (note that it is assigned to the normal id field). When passing the new record to the backend, the id is sent with it. When the backend inserts the record into the database, it (normally) gets a proper id assigned. That id then needs to be passed back in the response, to update the local record with the correct id. Making sure that future updates match the correct row in the database.

For example, a newly created record should be passed similar to this to the backend (pseudo format, up to the application/backend to decide):

{
    "added" : {
        "id" : "generated79",
        "name" : "Hercules",
        ...
    }
}

For the backend response to be applicable for this function, it should then respond with:

{
    "updated" : {
        {
            "$PhantomId" : "generated79",
            "id" : 465
        }
    }
}

(Or, as stated above, it can also be passed in the "added" array. Whichever suits your backend best).

This function will then change the id of the local record using the phantom id generated79 to 465.

Transforming a response to the correct format

This function optionally accepts a transformFn, a function that will be called with the changes. It is expected to return a changeset in the format described above ({ added : [], updated : [], removed : [] }), which then will be used to apply the changes.

Consider the following "non-standard" (made-up) changeset:

const changes = {
    // Database ids for records previously added locally
    assignedIds : {
        'phantom1' : 10,
        'phantom2' : 15
    },
    // Ids records removed by the backend
    removed : [11, 27],
    // Modified records, keyed by id
    altered : {
        12 : { name : 'Changed' }
    },
    // New records, keyed by id
    inserted : {
        20  : { name : 'New' }
    }
}

Since it does not match the expected format, it has to be transformed:

store.applyChangeset(changes, ({ assignedIds, inserted, altered, removed }) => ({
   // Convert inserted to [{ id : 20, name : 'New' }]
   added : Object.entries(inserted).map(([id, data] => ({ id, ...data }),
   updated : [
       // Convert assignedIds to [{ $PhantomId : 'phantom1', id : 10 }, ...]
      ...Object.entries(assignedIds).map(([phantomId, id])) => ({ $PhantomId : phantomId, id }),
      // Convert altered to [{ id : 12, name : 'Changed' }]
      ...Object.entries(modified).map(([id, data] => ({ id, ...data })
   ],
   // Convert removed to [{ id : 11 }, ...]
   removed : removed.map(id => ({ id }))
}));

The transform function above would output:

{
    added : [
        {  id : 20, name : 'New' }
    ],
    updated : [
        { $PhantomId : 'phantom1', id : 10 },
        { $PhantomId : 'phantom2', id : 15 },
        {  id : 12, name : 'Changed' }
    ],
    removed : [
       { id : 11 },
       { id : 12 }
    ]
}

And that format can then be applied.

Preventing automatic commit of applied changes

By default, the clearChanges parameter is set to true, which automatically commits applied changes to the store. Setting this parameter to false prevents the automatic commit, keeping the store in a dirty state.

For example, the following will apply changes without committing them:

const changes = {
    added : [
        {  id : 20, name : 'New' }
    ],
    updated : [
        { id : 10, name : 'Fiona' },
    ],
    removed : [
       { id : 11 }
    ]
};

// Apply these changes using the applyChangeset method
store.applyChangeset(changes, null, '$PhantomId', false);
ParameterTypeDescription
changesObject

Changeset to apply to the store, see specification above

transformFnfunction

Optional function used to preprocess a changeset in a different format, should return an object with the format expected by this function (see above)

phantomIdFieldString

Field used by the backend when communicating a record being assigned a proper id instead of a phantom id (see above)

clearChangesBoolean

Set to false to not commit the applied changes on the store, keeping it dirty

Applies changes from another store to this store. Useful if cloning records in one store to display in a grid in a popup etc. to reflect back changes.

ParameterTypeDescription
otherStoreStore

Commits changes, per default only returns changes and resets tracking.

ParameterTypeDescription
silentBoolean

Specify true to suppress events

Returns: Object -

Changes, see changes

Insert records into the store.

ParameterTypeDescription
indexNumber

Index to insert at

recordsModel | Model[] | Object | Object[]

Array of records/data or a single record/data to insert to store

silentBoolean

Specify true to suppress events

Returns: Model[] -

Inserted records

Loads a page of data from the implemented requestData function.

ParameterTypeDescription
pageNumber

The one based page number to load.

paramsObject

A hash of parameters to append to the request event and requestData call

Returns: Promise -

A Promise which will be resolved when the request completes

Moves a record, or block of records to another location.

ParameterTypeDescription
recordsModel | Model[]

The record(s) to move.

beforeRecordModel

the record to insert the first record(s) before.

If this store is paged, and is not already at the lastPage then this will load the next page of data.

Returns: Promise -

A promise which is resolved when the request completes and has been processed.

If this store is paged, and is not already at the first page then this will load the previous page of data.

Returns: Promise -

A promise which is resolved when the request completes and has been processed.

Removes a record from this store. Fires a single remove event passing the removed records.

ParameterTypeDescription
recordsString | String[] | Number | Number[] | Model | Model[]

Record/array of records (or record ids) to remove

silentBoolean

Specify true to suppress events/autoCommit

Returns: Model[] -

Removed records

Removes all records from the store.

If called on a lazy-loaded store, it removes all the loaded records. And if a backend is configured, then those deletions will also be synced with the backend.

ParameterTypeDescription
silentBoolean

Specify true to suppress events

Returns: Boolean -

true unless the action was prevented, in which case it returns false

Reverts all changes in the store (adds removed records back, and removes newly added records).

Iteration

Equivalent to Array.every(). Returns true if every call of the provided function on each record yields a truthy value.

ParameterTypeDescription
fnfunction
fn.recordfunction

The record to test.

thisObjObject

The this reference to call the function with. Defaults to this Store.

ignoreFiltersBoolean

Pass true to iterate all records including filtered out ones.

Returns: Array

Equivalent to Array.flatMap(). Creates a new array by spreading the results of calling a provided function on every record

ParameterTypeDescription
fnfunction

A function returning an array of items to be spread into the new array, or a single item to include in it

thisObjObject

The this reference to call the function with. Defaults to this Store

Returns: Array -

The new array

Iterates over all available records in store. Omits group header and footer records if this store is grouped. Does not request new records when store is configured with lazyLoad.

ParameterTypeDescription
fnfunction

A function that is called for each record. Returning false from that function cancels iteration. It is called with the following arguments:

fn.recordModel

Current record

fn.indexNumber

Current index

thisObjObject

this reference for the function

optionsObject | Boolean

A boolean for includeFilteredOutRecords, or detailed options for exclude/include records

options.includeFilteredOutRecordsBoolean

true to also include filtered out records

options.includeCollapsedGroupRecordsBoolean

true to also include records from collapsed groups of grouped stores

Equivalent to Array.map(). Creates a new array with the results of calling a provided function on every record

ParameterTypeDescription
fnfunction
thisObjObject

The this reference to call the function with. Defaults to this Store

Returns: Array

Equivalent to Array.reduce(). Applies a function against an accumulator and each record (from left to right) to reduce it to a single value.

ParameterTypeDescription
fnfunction
initialValue*
thisObjObject

The this reference to call the function with. Defaults to this Store

Returns: *

Other

Stops this store from firing events until endBatch is called. Multiple calls to beginBatch stack up, and will require an equal number of endBatch calls to resume events.

Upon call of endBatch, a refresh event is triggered to allow UIs to update themselves based upon the new state of the store.

This is extremely useful when making a large number of changes to a store. It is important not to trigger too many UI updates for performance reasons. Batching the changes ensures that UIs attached to this store are only updated once at the end of the updates.

Ends event suspension started by beginBatch. Multiple calls to beginBatch stack up, and will require an equal number of endBatch calls to resume events.

Upon call of endBatch, a refresh event with action: batch is triggered to allow UIs to update themselves based upon the new state of the store.

This is extremely useful when making a large number of changes to a store. It is important not to trigger too many UI updates for performance reasons. Batching the changes ensures that UIs attached to this store are only updated once at the end of the updates.

getStorestatic

Creates a new Store instance, or retrieves an existing one.

A Store config object may contain a type property to identify a specific Store subclass to create. If type is not specified, a base Store instance will be created.

Get a store by passing in the id of an existing store:

// Get a store by id
const store = Store.getStore('myStoreId');

Create a store from an array of data objects:

const store = Store.getStore([
    { id : 1, name : 'Linda', city : 'NY' },
    { id : 2, name : 'Olivia', city : 'Paris' },
    ...
]);

Create a store from a config object using a type property to identify a specific Store subclass to create:

const store = Store.getStore({
    type       : 'tree',
    modelClass : MyModel,
    data       : [
        { id : 1, name : 'Linda', city : 'NY' },
        { id : 2, name : 'Olivia', city : 'Paris' },
        ...
    ]
});
ParameterTypeDescription
idString | Number | StoreConfig | Object[]

The id of the store to retrieve, or an array of objects from which to create the contents of a new Store.

storeClassfunction

The default Store class to instantiate.

Returns: Store -

The newly created Store, or an existing Store if id matched an existing Store.

Responds to mutations of the underlying storage Collection

ParameterTypeDescription
eventObject

Retrieve the data of all (unfiltered) records as an array of JSON objects.

const store = new Store({
    data : [
        { id : 1, name : 'Superman' },
        { id : 2, name : 'Batman' }
    ]
});

const jsonArray = store.toJSON();

//jsonArray:
[{id:1,name:"Superman"},{id:2,name:"Batman"}]
Returns: Object[]
onEvents
relayAllEvents
triggerEvents
unEvents

Records

Creates a model instance, used internally when data is set/added. Override this in a subclass to do your own custom conversion from data to record.

ParameterTypeDescription
dataObject

Json data

skipExposeBoolean

Supply true when batch setting to not expose properties multiple times

Returns: Model

Get the record at the specified index.

ParameterTypeDescription
indexNumber

Index for the record

Returns: Model -

Record at the specified index

Get a locally available record by id. Find the record even if filtered out, part of collapsed group or collapsed node

ParameterTypeDescription
idModel | String | Number

Id of record to return.

Returns: Model -

A record with the specified id

Get a record by internalId.

ParameterTypeDescription
internalIdNumber

The internalId of the record to return

Returns: Model -

A record with the specified internalId

Counts the number of records in the store. Allows passing an options object to control which records are counted. For example:

store.getCount({ filteredOut : true });
store.getCount({ headersFooters : true, collapsed : true });

Consider the following dataset loaded into a Store:

[
  { id : 1, name : 'Linda', city : 'NY' },
  { id : 2, name : 'Olivia', city : 'NY' },
  { id : 3, name : 'John', city : 'Stockholm' }
]

No grouping or filtering is applied, thus all records are accessible ("visible"). Passing the different options below would yield the following results:

Option Count Description
filteredOut 0 No records are filtered out
headersFooters 0 No group headers have been generated
collapsed 0 No groups are collapsed
visibleData 3 All data records are "visible"
all 3 All options combined

Grouping by city yields the following records in the Store (pseudocode):

store.group('city');

[
  { name : 'Group NY', groupHeader : true, expanded : true },
  { id : 1, name : 'Linda', city : 'NY' },
  { id : 2, name : 'Olivia', city : 'NY' },
  { name : 'Group Stockholm', groupHeader : true },
  { id : 3, name : 'John', city : 'Stockholm', expanded : true }
]

Passing the different options below would yield the following results:

Option Count Description
filteredOut 0 No records are filtered out
headersFooters 2 Group headers have been generated
collapsed 0 No groups are collapsed
visibleData 3 All data records are "visible"
all 5 All options combined

Collapsing the Stockholm group yields the following records in the Store (pseudocode):

store.collapse(store.getAt(3));

[
  { name : 'Group NY', groupHeader : true, expanded : true },
  { id : 1, name : 'Linda', city : 'NY' },
  { id : 2, name : 'Olivia', city : 'NY' },
  { name : 'Group Stockholm', groupHeader : true, expanded : false }
]

Passing the different options below would yield the following results:

Option Count Description
filteredOut 0 No records are filtered out
headersFooters 2 Group headers have been generated
collapsed 1 A group with one record is collapsed
visibleData 2 Not all data records are "visible"
all 5 All options combined

Applying a filter further affects the counts (pseudocode):

store.filter('name', 'Linda');

[
  { name : 'Group NY', groupHeader : true, expanded : true },
  { id : 1, name : 'Linda', city : 'NY' }
]

Passing the different options below would yield the following results:

Option Count Description
filteredOut 2 Records are filtered out
headersFooters 2 Group headers have been generated*
collapsed 1 A group with one record is collapsed
visibleData 1 Not all data records are "visible"
all 5 All options combined

* Note that also passing filteredOut would include filtered out group headers in the count.

ParameterTypeDescription
optionsBoolean | Object

Count processed (true) or real records (false), or pass an object with options to control the count. Note that the Boolean signature is deprecated and will be removed in a future version.

options.filteredOutBoolean

Count records that are filtered out

options.headersFootersBoolean

Count generated group headers and footers (not applicable for tree data)

options.collapsedBoolean

Count records that are collapsed away, either belonging to a collapsed group, or by belonging to a collapsed branch in a tree

options.visibleDataBoolean

Count data records that are not filtered out or collapsed away

options.allBoolean

Convenience option to count all records (all options as true)

Returns: Number -

Record count

Creates an array of records from this store from the start to the end - 1

ParameterTypeDescription
startNumber

The index of the first record to return

endNumber

The index after the last record to return (start + length)

Returns: Model[] -

The requested records.

Checks if the specified record is contained in the store

ParameterTypeDescription
recordOrIdModel | String | Number

Record, or id of record

Returns: Boolean

Returns the index of the specified record/id, or -1 if not found.

ParameterTypeDescription
recordOrIdModel | String | Number

Record, or id of record to return the index of.

visibleRecordsBoolean

Pass true to find the visible index. as opposed to the dataset index. This omits group header records.

allExceptFilteredOutRecordsBoolean

For trees, when true this searches all except filtered out records in the flattened tree, similar to a flat store.

Returns: Number -

Index for the record/id, or -1 if not found.

Checks if a record is available, in the sense that it is not filtered out, hidden in a collapsed group or in a collapsed parent node of a tree store.

ParameterTypeDescription
recordOrIdModel | String | Number

Record to check

Returns: Boolean

Resumes automatic commits upon store changes. Will trigger commit if the internal counter is 0.

Suspends automatic commits upon store changes. Can be called multiple times (it uses an internal counter).

Search

Finds the first record for which the specified function returns true

ParameterTypeDescription
fnfunction

Comparison function, called with record as parameter

searchAllRecordsBoolean

True to ignore any applied filters when searching

Returns: Model -

Record or undefined if none found

store.find(record => record.color === 'blue');

Find occurrences of the specified value in the specified field on all locally available records in the store

ParameterTypeDescription
fieldString

The record field to search in

value*

Value to search for

distinctBoolean

True to only return distinct matches, no duplicates

searchAllRecordsBoolean

True to ignore any applied filters when searching

Returns: StoreSearchResult[] -

Array of hits, in the format { index: x, data: record }

Finds the first record for which the specified field has the specified value

ParameterTypeDescription
fieldNameString

Field name

value*

Value to find

searchAllRecordsBoolean

True to ignore any applied filters when searching

Returns: Model -

Record or undefined if none found

Searches the Store records using the passed function.

ParameterTypeDescription
fnfunction

A function that is called for each record. Return true to indicate a match

searchAllRecordsBoolean

True to ignore any applied filters when searching

Returns: Model[] -

An array of the matching Records

Returns true if the supplied function returns true for any record in the store

ParameterTypeDescription
fnfunction

A function that should return true to indicate a match

searchAllRecordsBoolean

True to ignore any applied filters when searching

Returns: Boolean -
store.some(record => record.age > 95); // true if any record has age > 95

Sort, group & filter

Adds a single filter to the filters collection. By default, filters are reevaluated and a Store change event fired.

If the silent parameter is passed as true, multiple filters can be added without causing data changes.

When the filters are as required, call filter with no parameters to apply the filters to the store.

ParameterTypeDescription
newFilterCollectionFilterConfig | function

A filter config, or a function to use for filtering.

silentBoolean

Pass true to not refilter the store immediately. Such as when adding multiple filters.

Returns: Promise | CollectionFilter -

If filterParamName is set on store, this method returns Collection filter inside a Promise which is resolved after data is loaded from remote server, otherwise it returns null

Add a sorting level (a sorter).

ParameterTypeDescription
fieldString | Sorter[] | Sorter | function

Field to sort by. Can also be an array of sorters, or a sorting function, or a sorter config.

ascendingBoolean

Sort order (used only if field specified as string)

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Removes all filters from the store. Filters that are marked as internal will not be removed.

ParameterTypeDescription
silentBoolean

Pass true to not refilter the store immediately.

Returns: Promise | null -

If filterParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Removes all groupers, turning store grouping off.

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Removes all sorters, turning store sorting off.

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Creates a function used with Array#sort when sorting the store. Override to use your own custom sorting logic.

ParameterTypeDescription
sortersSorter[]

An array of sorter config objects

Returns: function

Filters the store by adding the specified filter(s) to the existing filters collection applied to this Store. If a filter has an id specified, or a property specified, it will search for corresponding filter(s) in the existing filters first and replace it with a new filter. It will not remove other filters applied to the store!

To add a new filter:

// Filter using simple object
store.filter({
    property : 'age',
    operator : '>',
    value    : 90
});

// Filter using function
store.filter(r => r.age < 90);

// Filter using a named filter as a function
store.filter({
    id : 'my-filter',
    filterBy : record => record.score > 10
});

To remove a specific filter, but keep other filters applied

// Remove by filter `id` or `property`. Filter `id` defaults to the `property-operator` value.
store.removeFilter('age');
store.removeFilter('my-filter');

To replace all existing filters with a new filter

// Remove all filters and filter using simple object
store.filter({
    filters : {
        property : 'age',
        operator : '<',
        value    : 90
    },
    replace : true
});

// Remove all filters and filter using function
store.filter({
    filters : r => r.age > 90,
    replace : true
});

// Remove all filters and filter using a named filter as a function
store.filter({
    filters : {
        id : 'my-filter',
        filterBy : record => record.score > 10
    },
    replace : true
});

Basically filters replacing is an equivalent of having two sequenced calls: clearFilters and filter.

Call without arguments to reapply filters.

// Re-filter the store
store.filter();
ParameterTypeDescription
newFiltersObject | CollectionFilterConfig | CollectionFilterConfig[] | function

A filter config, or an array of filter configs, or a function to use for filtering, or a special object like: { replace : true, filters : newFilters }

newFilters.replaceBoolean

A flag, indicating whether or not the previous filters should be removed.

newFilters.silentBoolean

Set as true to not fire events. UI will not be informed about the changes.

newFilters.filtersCollectionFilterConfig | CollectionFilterConfig[] | function

If newFilters is an object and replace property is defined in the newFilters, it means that special object is used and real filter configuration must be nested down to this filters property. It can be: A filter config, or an array of filter configs, or a function to use for filtering.

Returns: Promise | null -

If filterParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null value

Adds a function used to filter the store. Alias for calling filter(fn). Return true from the function to include record in filtered set

store.filterBy(record => record.age > 25 && record.name.startsWith('A'));
ParameterTypeDescription
fnfunction

Function used to test records

Returns: Promise | null -

If filterParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Returns all records in the group with specified groupValue.

ParameterTypeDescription
groupValue*
Returns: Model[] -

Records in specified group or null if store not grouped

Get all group titles.

Returns: String[] -

Group titles

Group records, either by replacing current sorters or by adding to them. A grouper can specify a custom sorting function which will be called with arguments (recordA, recordB). Works in the same way as a standard array sorter, except that returning null triggers the stores normal sorting routine. Grouped store must always be sorted by the same field.

To clear groupers and stop grouping, use clearGroupers method.

// simple grouper
store.group('city');

// grouper as object, descending order
store.group({ field : 'city', ascending : false });

// using custom sorting function
store.group({
    field : 'city',
    fn : (recordA, recordB) => {
        // apply custom logic, for example:
        return recordA.city.length < recordB.city.length ? -1 : 1;
    }
});

// Stop grouping
store.clearGroupers();
ParameterTypeDescription
fieldString | Object

Field to group by. Can also be a config containing a field to group by and a custom sorting function called fn.

field.fieldString

Field to group by

field.fnfunction

Custom sorting function

field.ascendingBoolean

Sort order of the group titles

ascendingBoolean

Sort order of the group titles

addBoolean

Add a grouper (true) or use only this grouper (false)

performSortBoolean

Trigger sort directly, which does the actual grouping

silentBoolean

Set as true to not fire events

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Check if a record belongs to a certain group (only for the first grouping level)

ParameterTypeDescription
recordModel

The Record

groupValue*

The group value

Returns: Boolean -

True if the record belongs to the group, otherwise false

Removes the passed filter, or the filter by the passed ID from the filters collection. By default, filters are reevaluated and a Store change event fired.

If the silent parameter is passed as true, multiple filters can be removed without causing data changes.

When the filters are as required, call filter with no parameters to apply the filters to the store.

// Only view top priority events
myEventStore.filter({
    id       : 'priorityFilter',
    property : 'priority',
    value    : 1,
    operator : '='
});

// That individual filter can be removed like this
myEventStore.removeFilter('priorityFilter');

// Add named filter as a function
store.filter({
    id : 'my filter',
    filterBy : record => record.score > 10
});

// Remove named filter function
store.removeFilter('my filter');
ParameterTypeDescription
idOrInstanceString | CollectionFilter

Filter to remove, or ID of the filter to remove. By default, filters are reevaluated and a change event fired.

silentBoolean

Pass true to not refilter the store immediately. Such as when removing multiple filters.

Returns: Promise | CollectionFilter -

If filterParamName is set on store, this method returns Collection filter inside a Promise which is resolved after data is loaded from remote server, otherwise it returns null

Remove a sorting level (a sorter)

ParameterTypeDescription
fieldString | function

Stop sorting by this field (or sorter function)

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Set groupers.

ParameterTypeDescription
groupersGrouper[]

Array of groupers to apply to store

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Sort records, either by replacing current sorters or by adding to them. A sorter can specify a custom sorting function which will be called with arguments (recordA, recordB). Works in the same way as a standard array sorter, except that returning null triggers the stores normal sorting routine.

// single sorter
store.sort('age');

// single sorter as object, descending order
store.sort({ field : 'age', ascending : false });

// multiple sorters
store.sort(['age', 'name']);

// using custom sorting function
store.sort((recordA, recordB) => {
    // apply custom logic, for example:
    return recordA.name.length < recordB.name.length ? -1 : 1;
});

// using locale specific sort (slow)
store.sort({ field : 'name', useLocaleSort : 'sv-SE' });
ParameterTypeDescription
fieldString | Sorter[] | Sorter | function

Field to sort by. Can also be an array of sorter config objects, or a sorting function, or a sorter config.

ascendingBoolean

Sort order. Applicable when the field is a string (if not specified and already sorted by the field, reverts direction), or an object and ascending property is not specified for the object. true by default. Not applicable when field is a function. ascending is always true in this case.

addBoolean

If true, adds a sorter to the sorters collection. Not applicable when field is an array. In this case always replaces active sorters.

silentBoolean

Set as true to not fire events. UI will not be informed about the changes.

Returns: Promise | null -

If sortParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null

Sum

Returns the average value for the specified field. Defaults to look through all locally available records in store

ParameterTypeDescription
fieldString

Field to calculate average value for

recordsModel[]

Records to process, uses all records if unspecified

Returns: Number

Returns sum by adding value of specified field for records in the group with the specified groupValue.

ParameterTypeDescription
groupValue*

The group to summarize

fieldString

Field to summarize by

Returns: Number -

Sum or null if store not grouped

Returns max value for the specified field, can be used with Date or Number values. Defaults to look through all locally available records in store

ParameterTypeDescription
fieldString

Field to find max value for

recordsModel[]

Records to process, uses all records if unspecified

Returns: Number | Date

Returns min value for the specified field, can be used with Date or Number values. Defaults to look through all locally available records in store

ParameterTypeDescription
fieldString

Field to find min value for

recordsModel[]

Records to process, uses all records if unspecified

Returns: Number | Date

Returns sum calculated by adding value of specified field for specified records. Defaults to using all locally available records in store

ParameterTypeDescription
fieldString

Field to summarize by

recordsModel[]

Records to summarize, uses all records if unspecified.

Returns: Number

Traverse

Finds the next record locally available.

ParameterTypeDescription
recordOrIdModel | String | Number

Current record or its id

wrapBoolean

Wrap at start/end or stop there

skipSpecialRowsBoolean

True to not return specialRows like group headers

Returns: Model -

Next record or null if current is the last one

Finds the previous record locally available.

ParameterTypeDescription
recordOrIdModel | String | Number

Current record or its id

wrapBoolean

Wrap at start/end or stop there

skipSpecialRowsBoolean

True to not return specialRows like group headers

Returns: Model -

Previous record or null if current is the last one

Traverse all tree nodes (only applicable for Tree Store)

ParameterTypeDescription
fnfunction

The function to call on visiting each node.

topNodeModel

The top node to start the traverse at.

skipTopNodeBoolean

Pass true to not call fn on the top node, but proceed directly to its children.

optionsObject | Boolean

A boolean for includeFilteredOutRecords, or detailed options for exclude/include records

options.includeFilteredOutRecordsBoolean

True to also include filtered out records

options.includeCollapsedGroupRecordsBoolean

True to also include records from collapsed groups of grouped store

options.useOrderedTreeBoolean

True to traverse unsorted/unfiltered tree

Traverse all tree nodes while the passed fn returns true

ParameterTypeDescription
fnfunction

The function to call on visiting each node. Returning false from it stops the traverse.

topNodeModel

The top node to start the traverse at.

skipTopNodeBoolean

Pass true to not call fn on the top node, but proceed directly to its children.

optionsObject

An options object to exclude/include records

options.includeFilteredOutRecordsBoolean

True to also include filtered out records

options.includeCollapsedGroupRecordsBoolean

True to also include records from collapsed groups of grouped store

Tree

Returns the children of the passed branch node which this store owns. By default, this is the entire children array.

If this store isChained, then this returns only the subset of children which are filtered into this store by the chainedFilterFn.

ParameterTypeDescription
parentModel

The node to return the children of.

Returns: Model[]

Increase the indentation level of one or more nodes in the tree

ParameterTypeDescription
nodesModel | Model[]

The nodes to indent.

Loads children for a parent node that uses load on demand (when expanding it). Base implementation does nothing, either use AjaxStore which implements it, create your own subclass with an implementation or listen for toggleNode and insert records when you have them available.

ParameterTypeDescription
parentRecordModel
Returns: Promise -

A Promise which will be resolved if the load succeeds, and rejected if the load is vetoed by a beforeLoadChildren handler, or if an exception is detected. The resolved function is passed the event object passed to any event handlers. The rejected function is passed the exception event if an exception occurred, or false if the load was vetoed by a beforeLoadChildren handler.

Decrease the indentation level of one or more nodes in the tree

ParameterTypeDescription
nodesModel | Model[]

The nodes to outdent.

Collapse an expanded record or expand a collapsed. Optionally forcing a certain state.

ParameterTypeDescription
idOrRecordString | Number | Model

Record (the record itself) or id of a record to toggle

collapseBoolean

Force collapse (true) or expand (false)

Values

Returns an array of distinct values from all locally available records for the specified field.

store.getDistinctValues('age'); // Returns an array of the unique age values
ParameterTypeDescription
fieldString

Field to extract values for

includeFilteredOutRecordsBoolean

True to ignore any applied filters

includeCountsBoolean

When true, returns array of [ value, count ] with counts of occurrences

Returns: Array -

Array of values

Counts how many times the specified value appears locally in the store

ParameterTypeDescription
fieldString

Field to look in

value*

Value to look for

Returns: Number -

Found count

Configuration

applyDefaultsstaticBase

Events

Lifecycle

destroystaticBase

Misc

initClassstaticBase
isOfTypeNamestaticBase
mixinstaticBase

Events

32

Fired after adding/inserting record(s). If the record was added to a parent, the isChild flag is set on the event. If it was inserted, event contains index

// Adding a listener using the "on" method
store.on('add', ({ source, records, allRecords, parent, index, oldIndex, isChild, isExpand, isMove }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

Added records. In case of tree store, if branch is added, only branch root is returned

allRecordsModel[]

Flat list of all added records. In case of tree store, if branch is added, all new records are returned, not only branch root

parentModel

If due to an appendChild call, this is the parent node added to.

indexNumber

Insertion point in the store's Collection.

oldIndexNumber

Not used for tree stores. The index of the first record moved.

isChildBoolean

Flag which is set to true if the records are added to a parent record

isExpandBoolean

Flag which is set to true if records are added to the store by expanding parent

isMoveObject

An object keyed by the ids of the records which were moved from another position in the store, or from another parent node in the store. The ids of moved records will be property names with a value true.

Fired when a temporary record with the isCreating property set has been confirmed as a part of this store by having its isCreating property cleared.

// Adding a listener using the "on" method
store.on('addConfirmed', ({ source, record }) => {

});
ParameterTypeDescription
sourceStore

This Store.

recordModel

The record confirmed as added.

Fired after any remote request has finished whether successfully or unsuccessfully.

// Adding a listener using the "on" method
store.on('afterRequest', ({ exception, action, exceptionType, response, json, params }) => {

});
ParameterTypeDescription
exceptionBoolean

true. Only present if the request triggered an exception.

actioncreate | read | update | delete | readPage

Action that has finished, 'create', 'read', 'update', 'delete' or 'readPage'

exceptionTypenetwork | failure

The type of failure, 'network' or 'server'. Only present if the request triggered an exception.

responseResponse

The Response object

jsonObject

The decoded response object if there was no 'network' exception.

paramsObject

An object containing key/value pairs that were passed on the request query string

Fired before records are added to this store by the add or insert. In a tree store, also fired by appendChild and insertChild. The add or insert may be vetoed by returning false from a handler.

// Adding a listener using the "on" method
store.on('beforeAdd', ({ source, records, parent }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

The records which are to be added

parentModel

The parent node when using a tree store

Fired before committing changes. Return false from handler to abort commit

// Adding a listener using the "on" method
store.on('beforeCommit', ({ source, changes }) => {

});
ParameterTypeDescription
sourceStore

This Store

changesObject

Modification data

Fired before filtering

// Adding a listener using the "on" method
store.on('beforeFilter', ({ source, filters }) => {

});
ParameterTypeDescription
sourceStore

This Store

filtersCollection

Filters to be applied to this Store

Fired before nodes in the tree are indented. Return false from a listener to prevent the indent.

// Adding a listener using the "on" method
store.on('beforeIndent', ({ source, records }) => {

});
ParameterTypeDescription
sourceStore

The

recordsModel[]

The nodes to indent.

When the store is paged, this is fired before loading a page and is cancelable

// Adding a listener using the "on" method
store.on('beforeLoadPage', ({ source, action, url, params }) => {

});
ParameterTypeDescription
sourceStore

This Store

actionString

(AjaxStore only) The read action being performed: 'readPage'

urlString

(AjaxStore only) The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base readUrl configured for this Store.

paramsObject

An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request.

Fired before nodes in the tree are outdented. Return false from a listener to prevent the outdent.

// Adding a listener using the "on" method
store.on('beforeOutdent', ({ source, records }) => {

});
ParameterTypeDescription
sourceStore

This store

recordsModel[]

Nodes to be outdented

Fired before records are removed from this store by the remove or removeAll. Also fired when removing a child record in a tree store using removeChild. The remove may be vetoed by returning false from a handler.

// Adding a listener using the "on" method
store.on('beforeRemove', ({ source, records, parent, isMove, removingAll }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

The records which are to be removed.

parentModel

The record from which children are being removed when using a tree store. Only provided when removing a single node.

isMoveBoolean

This flag is true if the child node is being removed by appendChild to be moved within the same tree.

removingAllBoolean

This flag is true if the operation is removing the store's entire data set.

Fired before any remote request is initiated.

// Adding a listener using the "on" method
store.on('beforeRequest', ({ source, url, params, body, action }) => {

});
ParameterTypeDescription
sourceStore

This Store

urlString

The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base urls configured for this Store.

paramsObject

An object containing key/value pairs that are passed on the request query string

bodyObject

The body of the request to be posted to the server.

actioncreate | read | update | delete | readPage

Action that is making the request, 'create', 'read', 'update', 'delete' or 'readPage'

Fired before sorting

// Adding a listener using the "on" method
store.on('beforeSort', ({ source, sorters, records }) => {

});
ParameterTypeDescription
sourceStore

This Store

sortersSorter[]

Sorter configs

recordsModel[]

Records to sort

Fired before record is modified in this store. Modification may be vetoed by returning false from a handler.

// Adding a listener using the "on" method
store.on('beforeUpdate', ({ source, record, changes }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordModel

Modified record

changesObject

Modification data

Data in the store was changed. This is a catch-all event which is fired for all changes which take place to the store's data.

This includes mutation of individual records, adding and removal of records, as well as setting a new data payload using the data property, sorting, filtering, and calling removeAll.

Simple databound widgets may use to the change event to refresh their UI without having to add multiple listeners to the update, add, remove, refresh and removeAll events.

A more complex databound widget such as a grid may use the more granular events to perform less destructive updates more appropriate to each type of change. The properties will depend upon the value of the action property.

// Adding a listener using the "on" method
store.on('change', ({ source, action, record, records, changes }) => {

});
ParameterTypeDescription
sourceStore

This Store.

actionremove | removeAll | add | clearchanges | filter | update | dataset | replace

Name of action which triggered the change. May be one of the options listed above

recordModel

Changed record, for actions that affects exactly one record ('update')

recordsModel[]

Changed records, passed for all actions except 'removeAll'

changesObject

Passed for the 'update' action, info on which record fields changed

Fired after committing changes

// Adding a listener using the "on" method
store.on('commit', ({ source, changes }) => {

});
ParameterTypeDescription
sourceStore

This Store

changesObject

Modification data

Fired after applying filters to the store

// Adding a listener using the "on" method
store.on('filter', ({ source, filters, removed, added, records }) => {

});
ParameterTypeDescription
sourceStore

This Store

filtersCollection

Filters used by this Store

removedModel[]

The records which were filtered out by the action.

addedModel[]

The records which were filtered back in by the action.

recordsModel[]

Filtered records

Fired when grouping changes

// Adding a listener using the "on" method
store.on('group', ({ source, groupers, records }) => {

});
ParameterTypeDescription
sourceStore

This Store

groupersGrouper[]

Applied groupers

recordsModel[]

Grouped records

Fired when the id of a record has changed

// Adding a listener using the "on" method
store.on('idChange', ({ source, record, oldValue, value }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordModel

Modified record

oldValueString | Number

Old id

valueString | Number

New id

Fired after tasks in the tree are indented

// Adding a listener using the "on" method
store.on('indent', ({ source, records }) => {

});
ParameterTypeDescription
sourceStore

The store

recordsModel[]

Nodes that were indented

When the store is paged, this is fired when a page is loaded.

// Adding a listener using the "on" method
store.on('loadPage', ({ source, params }) => {

});
ParameterTypeDescription
sourceStore

This Store

paramsObject

An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request.

Fired when a block of records has been moved within this Store

// Adding a listener using the "on" method
store.on('move', ({ source, records, from, to, newParent, oldParents }) => {

});
ParameterTypeDescription
sourceStore

This Store move API now accepts an array of records to move).

recordsModel[]

The moved records.

fromNumber

The index from which the record was removed (applicable only for flat store).

toNumber

The index at which the record was inserted (applicable only for flat store).

newParentModel

The new parent record for the dragged records (applicable only for tree stores)

oldParentsModel[]

The old parent records for the dragged records (applicable only for move operations in tree stores)

Fired after tasks in the tree are outdented

// Adding a listener using the "on" method
store.on('outdent', ({ source, records }) => {

});
ParameterTypeDescription
sourceStore

The store

recordsModel[]

Nodes that were outdented

Data in the store has completely changed, such as by a filter, or sort or load operation.

// Adding a listener using the "on" method
store.on('refresh', ({ source, batch, action }) => {

});
ParameterTypeDescription
sourceStore

This Store.

batchBoolean

Flag set to true when the refresh is triggered by ending a batch

actiondataset | sort | clearchanges | filter | create | update | delete | group

Name of action which triggered the change. May be one of the options listed above.

Fired when one or more records are removed

// Adding a listener using the "on" method
store.on('remove', ({ source, records, allRecords, parent, index, isChild, isCollapse, isMove }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

Array of removed records. In case of tree store, if branch is removed, only branch root is returned

allRecordsModel[]

Flat array of all removed records. In case of tree store, if branch is removed, all removed records are returned, not only branch root

parentModel

If due to a removeChild call, this is the parent node removed from. Only applicable when removing a single tree node.

indexNumber

Visible index at which record was removed. In case the record was removed from a collapsed branch, -1 is returned. For tree store, this is only provided when removing a single node.

isChildBoolean

Flag which is set to true if the record was removed from a parent record

isCollapseBoolean

Flag which is set to true if records were removed from the store by collapsing parent

isMoveBoolean

Passed as true if the remove was part of a move operation within this Store.

Fired after removing all records

// Adding a listener using the "on" method
store.on('removeAll', ({ source }) => {

});
ParameterTypeDescription
sourceStore

This Store

This event only fires in a non-AjaxStore, configured with remoteSort, remoteFilter or remotePaging, when the Store requests more or new data.

The event will contain same params as described in the requestData function. This event can be listened to if you want to receive notifications about the Store's data requests, but not directly want to return the requested data. For example, when you got the Store's data bound to a data source with the help of an external library/framegrunt docswork.

// Adding a listener using the "on" method
store.on('requestData', ({  }) => {

});

Fired when the root node is set

// Adding a listener using the "on" method
store.on('rootChange', ({ source, oldRoot, rootNode }) => {

});
ParameterTypeDescription
sourceStore

This Store

oldRootModel

The old root node.

rootNodeModel

The new root node.

Fired after sorting

// Adding a listener using the "on" method
store.on('sort', ({ source, sorters, records }) => {

});
ParameterTypeDescription
sourceStore

This Store

sortersSorter[]

Sorter configs

recordsModel[]

Sorted records

Fired when a record is modified

// Adding a listener using the "on" method
store.on('update', ({ source, record, changes }) => {

});
ParameterTypeDescription
sourceStore

This Store

recordModel

Modified record

changesObject

Modification data

catchAllEvents
destroyEvents

Event handlers

32

Called after adding/inserting record(s). If the record was added to a parent, the isChild flag is set on the event. If it was inserted, event contains index

new Store({
    onAdd({ source, records, allRecords, parent, index, oldIndex, isChild, isExpand, isMove }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

Added records. In case of tree store, if branch is added, only branch root is returned

allRecordsModel[]

Flat list of all added records. In case of tree store, if branch is added, all new records are returned, not only branch root

parentModel

If due to an appendChild call, this is the parent node added to.

indexNumber

Insertion point in the store's Collection.

oldIndexNumber

Not used for tree stores. The index of the first record moved.

isChildBoolean

Flag which is set to true if the records are added to a parent record

isExpandBoolean

Flag which is set to true if records are added to the store by expanding parent

isMoveObject

An object keyed by the ids of the records which were moved from another position in the store, or from another parent node in the store. The ids of moved records will be property names with a value true.

Called when a temporary record with the isCreating property set has been confirmed as a part of this store by having its isCreating property cleared.

new Store({
    onAddConfirmed({ source, record }) {

    }
});
ParameterTypeDescription
sourceStore

This Store.

recordModel

The record confirmed as added.

Called after any remote request has finished whether successfully or unsuccessfully.

new Store({
    onAfterRequest({ exception, action, exceptionType, response, json, params }) {

    }
});
ParameterTypeDescription
exceptionBoolean

true. Only present if the request triggered an exception.

actioncreate | read | update | delete | readPage

Action that has finished, 'create', 'read', 'update', 'delete' or 'readPage'

exceptionTypenetwork | failure

The type of failure, 'network' or 'server'. Only present if the request triggered an exception.

responseResponse

The Response object

jsonObject

The decoded response object if there was no 'network' exception.

paramsObject

An object containing key/value pairs that were passed on the request query string

Called before records are added to this store by the add or insert. In a tree store, also called by appendChild and insertChild. The add or insert may be vetoed by returning false from a handler.

new Store({
    onBeforeAdd({ source, records, parent }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

The records which are to be added

parentModel

The parent node when using a tree store

Called before committing changes. Return false from handler to abort commit

new Store({
    onBeforeCommit({ source, changes }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

changesObject

Modification data

Called before filtering

new Store({
    onBeforeFilter({ source, filters }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

filtersCollection

Filters to be applied to this Store

Called before nodes in the tree are indented. Return false from a listener to prevent the indent.

new Store({
    onBeforeIndent({ source, records }) {

    }
});
ParameterTypeDescription
sourceStore

The

recordsModel[]

The nodes to indent.

When the store is paged, this is called before loading a page and is cancelable

new Store({
    onBeforeLoadPage({ source, action, url, params }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

actionString

(AjaxStore only) The read action being performed: 'readPage'

urlString

(AjaxStore only) The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base readUrl configured for this Store.

paramsObject

An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request.

Called before nodes in the tree are outdented. Return false from a listener to prevent the outdent.

new Store({
    onBeforeOutdent({ source, records }) {

    }
});
ParameterTypeDescription
sourceStore

This store

recordsModel[]

Nodes to be outdented

Called before records are removed from this store by the remove or removeAll. Also called when removing a child record in a tree store using removeChild. The remove may be vetoed by returning false from a handler.

new Store({
    onBeforeRemove({ source, records, parent, isMove, removingAll }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

The records which are to be removed.

parentModel

The record from which children are being removed when using a tree store. Only provided when removing a single node.

isMoveBoolean

This flag is true if the child node is being removed by appendChild to be moved within the same tree.

removingAllBoolean

This flag is true if the operation is removing the store's entire data set.

Called before any remote request is initiated.

new Store({
    onBeforeRequest({ source, url, params, body, action }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

urlString

The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base urls configured for this Store.

paramsObject

An object containing key/value pairs that are passed on the request query string

bodyObject

The body of the request to be posted to the server.

actioncreate | read | update | delete | readPage

Action that is making the request, 'create', 'read', 'update', 'delete' or 'readPage'

Called before sorting

new Store({
    onBeforeSort({ source, sorters, records }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

sortersSorter[]

Sorter configs

recordsModel[]

Records to sort

Called before record is modified in this store. Modification may be vetoed by returning false from a handler.

new Store({
    onBeforeUpdate({ source, record, changes }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordModel

Modified record

changesObject

Modification data

Data in the store was changed. This is a catch-all event which is called for all changes which take place to the store's data.

This includes mutation of individual records, adding and removal of records, as well as setting a new data payload using the data property, sorting, filtering, and calling removeAll.

Simple databound widgets may use to the change event to refresh their UI without having to add multiple listeners to the update, add, remove, refresh and removeAll events.

A more complex databound widget such as a grid may use the more granular events to perform less destructive updates more appropriate to each type of change. The properties will depend upon the value of the action property.

new Store({
    onChange({ source, action, record, records, changes }) {

    }
});
ParameterTypeDescription
sourceStore

This Store.

actionremove | removeAll | add | clearchanges | filter | update | dataset | replace

Name of action which triggered the change. May be one of the options listed above

recordModel

Changed record, for actions that affects exactly one record ('update')

recordsModel[]

Changed records, passed for all actions except 'removeAll'

changesObject

Passed for the 'update' action, info on which record fields changed

Called after committing changes

new Store({
    onCommit({ source, changes }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

changesObject

Modification data

Called after applying filters to the store

new Store({
    onFilter({ source, filters, removed, added, records }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

filtersCollection

Filters used by this Store

removedModel[]

The records which were filtered out by the action.

addedModel[]

The records which were filtered back in by the action.

recordsModel[]

Filtered records

Called when grouping changes

new Store({
    onGroup({ source, groupers, records }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

groupersGrouper[]

Applied groupers

recordsModel[]

Grouped records

Called when the id of a record has changed

new Store({
    onIdChange({ source, record, oldValue, value }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordModel

Modified record

oldValueString | Number

Old id

valueString | Number

New id

Called after tasks in the tree are indented

new Store({
    onIndent({ source, records }) {

    }
});
ParameterTypeDescription
sourceStore

The store

recordsModel[]

Nodes that were indented

When the store is paged, this is called when a page is loaded.

new Store({
    onLoadPage({ source, params }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

paramsObject

An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request.

Called when a block of records has been moved within this Store

new Store({
    onMove({ source, records, from, to, newParent, oldParents }) {

    }
});
ParameterTypeDescription
sourceStore

This Store move API now accepts an array of records to move).

recordsModel[]

The moved records.

fromNumber

The index from which the record was removed (applicable only for flat store).

toNumber

The index at which the record was inserted (applicable only for flat store).

newParentModel

The new parent record for the dragged records (applicable only for tree stores)

oldParentsModel[]

The old parent records for the dragged records (applicable only for move operations in tree stores)

Called after tasks in the tree are outdented

new Store({
    onOutdent({ source, records }) {

    }
});
ParameterTypeDescription
sourceStore

The store

recordsModel[]

Nodes that were outdented

Data in the store has completely changed, such as by a filter, or sort or load operation.

new Store({
    onRefresh({ source, batch, action }) {

    }
});
ParameterTypeDescription
sourceStore

This Store.

batchBoolean

Flag set to true when the refresh is triggered by ending a batch

actiondataset | sort | clearchanges | filter | create | update | delete | group

Name of action which triggered the change. May be one of the options listed above.

Called when one or more records are removed

new Store({
    onRemove({ source, records, allRecords, parent, index, isChild, isCollapse, isMove }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordsModel[]

Array of removed records. In case of tree store, if branch is removed, only branch root is returned

allRecordsModel[]

Flat array of all removed records. In case of tree store, if branch is removed, all removed records are returned, not only branch root

parentModel

If due to a removeChild call, this is the parent node removed from. Only applicable when removing a single tree node.

indexNumber

Visible index at which record was removed. In case the record was removed from a collapsed branch, -1 is returned. For tree store, this is only provided when removing a single node.

isChildBoolean

Flag which is set to true if the record was removed from a parent record

isCollapseBoolean

Flag which is set to true if records were removed from the store by collapsing parent

isMoveBoolean

Passed as true if the remove was part of a move operation within this Store.

Called after removing all records

new Store({
    onRemoveAll({ source }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

This event only called in a non-AjaxStore, configured with remoteSort, remoteFilter or remotePaging, when the Store requests more or new data.

The event will contain same params as described in the requestData function. This event can be listened to if you want to receive notifications about the Store's data requests, but not directly want to return the requested data. For example, when you got the Store's data bound to a data source with the help of an external library/framegrunt docswork.

new Store({
    onRequestData({  }) {

    }
});

Called when the root node is set

new Store({
    onRootChange({ source, oldRoot, rootNode }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

oldRootModel

The old root node.

rootNodeModel

The new root node.

Called after sorting

new Store({
    onSort({ source, sorters, records }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

sortersSorter[]

Sorter configs

recordsModel[]

Sorted records

Called when a record is modified

new Store({
    onUpdate({ source, record, changes }) {

    }
});
ParameterTypeDescription
sourceStore

This Store

recordModel

Modified record

changesObject

Modification data

onDestroyEvents

Typedefs

8

An object containing details about the received data used for lazy and paged loading

ParameterTypeDescription
dataObject[]

The data being received

totalNumber

The total number of records available

An immutable object representing a store grouper.

ParameterTypeDescription
fieldString

Field name

ascendingBoolean

true to group ascending, false to group descending

An object containing details about the requested data

ParameterTypeDescription
startIndexNumber

The index of the first record being requested

countNumber

The number of records being requested

sortersSorter[]

If remoteSort is active, this will contain a number of sorter objects

filtersCollectionFilterConfig[]

If remoteFilter is active, this will contain a number of filters objects

startDateDate

The startDate of the requested date range (only if applicable)

endDateDate

The endDate of the requested date range (only if applicable)

parentIdString | Number

The parentId for which to load children (only if tree store)

resourceIdsString[] | Number[]

If this store is part of a Scheduler or a Gantt, and is a store dependent on the ResourceStore, such as the EventStore, and the ResourceStore is configured as a tree store, this value of this property is the IDs of the Resources for which to load related data. startIndex and count will not be used in these cases.

An object containing details about the requested data

ParameterTypeDescription
pageNumber

The page number being requested

pageSizeNumber

The number of records being requested

sortersSorter[]

If remoteSort is active, this will contain a number of sorter objects

filtersCollectionFilterConfig[]

If remoteFilter is active, this will contain a number

An immutable object representing a store sorter.

ParameterTypeDescription
fieldString

Field name

fnfunction

A custom sorting function, to be used instead of the "field"

ascendingBoolean

true to sort ascending, false to sort descending

Format returned by Store#findByField().

ParameterTypeDescription
indexNumber

Index of the record in the store

dataModel

The record

Options available when supplying a config object to the syncDataOnLoad config.

ParameterTypeDescription
keepMissingValuesBoolean

How to handle values for missing fields, see syncDataOnLoad

thresholdString | Number

Threshold above which events are batched, see syncDataOnLoad