diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.html b/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.html index d05bce9eb..cf00b3742 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.html +++ b/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.html @@ -3,6 +3,7 @@
- + diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.ts b/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.ts index b989fe6e0..4a1c37f28 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/aurelia-slickgrid.ts @@ -1,3 +1,4 @@ +import { GridStateChange } from './models/gridStateChange.interface'; // import 3rd party vendor libs import 'slickgrid/lib/jquery-ui-1.11.3'; import 'slickgrid/lib/jquery.event.drag-2.3.0'; @@ -30,7 +31,9 @@ import { Column, FormElementType, GraphqlResult, - GridOption + GridOption, + GridStateType, + Pagination, } from './models/index'; import { ControlAndPluginService, @@ -49,6 +52,7 @@ import * as $ from 'jquery'; // using external non-typed js libraries declare var Slick: any; +const aureliaEventPrefix = 'asg'; const eventPrefix = 'sg'; // Aurelia doesn't support well TypeScript @autoinject in a Plugin so we'll do it the old fashion way @@ -56,6 +60,7 @@ const eventPrefix = 'sg'; export class AureliaSlickgridCustomElement { private _dataset: any[]; private _eventHandler: any = new Slick.EventHandler(); + gridStateSubscriber: Subscription; gridHeightString: string; gridWidthString: string; localeChangedSubscriber: Subscription; @@ -158,11 +163,13 @@ export class AureliaSlickgridCustomElement { this.dataview = []; this._eventHandler.unsubscribeAll(); this.controlAndPluginService.dispose(); - this.gridEventService.dispose(); this.filterService.dispose(); + this.gridEventService.dispose(); + this.gridStateService.dispose(); this.resizer.dispose(); this.sortService.dispose(); this.grid.destroy(); + this.gridStateSubscriber.dispose(); this.localeChangedSubscriber.dispose(); this.ea.publish('onAfterGridDestroyed', true); this.elm.dispatchEvent(new CustomEvent(`${eventPrefix}-on-after-grid-destroyed`, { @@ -258,6 +265,7 @@ export class AureliaSlickgridCustomElement { } } + // expose all Slick Grid Events through dispatch for (const prop in grid) { if (grid.hasOwnProperty(prop) && prop.startsWith('on')) { this._eventHandler.subscribe(grid[prop], (e: any, args: any) => { @@ -272,6 +280,7 @@ export class AureliaSlickgridCustomElement { } } + // expose all Slick DataView Events through dispatch for (const prop in dataView) { if (dataView.hasOwnProperty(prop) && prop.startsWith('on')) { this._eventHandler.subscribe(dataView[prop], (e: any, args: any) => { @@ -286,6 +295,14 @@ export class AureliaSlickgridCustomElement { } } + // expose GridState Service changes event through dispatch + this.gridStateSubscriber = this.ea.subscribe('gridStateService:changed', (gridStateChange: GridStateChange) => { + this.elm.dispatchEvent(new CustomEvent(`${aureliaEventPrefix}-on-grid-state-service-changed`, { + bubbles: true, + detail: gridStateChange + })); + }); + // on cell click, mainly used with the columnDef.action callback this.gridEventService.attachOnCellChange(grid, this.gridOptions, dataView); this.gridEventService.attachOnClick(grid, this.gridOptions, dataView); @@ -381,6 +398,13 @@ export class AureliaSlickgridCustomElement { return $.extend(true, {}, GlobalGridOptions, this.gridOptions); } + paginationChanged(pagination: Pagination) { + this.ea.publish('gridStateService:changed', { + change: { newValues: pagination, type: GridStateType.pagination }, + gridState: this.gridStateService.getCurrentGridState() + }); + } + /** * When dataset changes, we need to refresh the entire grid UI & possibly resize it as well * @param dataset diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/formatters/collectionFormatter.ts b/aurelia-slickgrid/src/aurelia-slickgrid/formatters/collectionFormatter.ts index 1548b32a3..e2b073513 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/formatters/collectionFormatter.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/formatters/collectionFormatter.ts @@ -21,7 +21,7 @@ export const collectionFormatter: Formatter = (row: number, cell: number, value: value.map((v: any) => findOrDefault(collection, (c: any) => c[valueName] === v)[labelName]), columnDef, dataContext); - } + } return findOrDefault(collection, (c: any) => c[valueName] === value)[labelName] || ''; }; diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/models/gridState.interface.ts b/aurelia-slickgrid/src/aurelia-slickgrid/models/gridState.interface.ts index 8c33d7a4b..014ecc6b3 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/models/gridState.interface.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/models/gridState.interface.ts @@ -1,5 +1,4 @@ -import { CurrentSorter } from './currentSorter.interface'; -import { CurrentFilter } from './currentFilter.interface'; +import { CurrentFilter, CurrentSorter } from './../models/index'; export interface GridState { /** Filters (and their state, columnId, searchTerm(s)) that are currently applied in the grid */ diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/models/gridStateChange.interface.ts b/aurelia-slickgrid/src/aurelia-slickgrid/models/gridStateChange.interface.ts new file mode 100644 index 000000000..ca2e9c3d7 --- /dev/null +++ b/aurelia-slickgrid/src/aurelia-slickgrid/models/gridStateChange.interface.ts @@ -0,0 +1,12 @@ +import { CurrentFilter, CurrentSorter, GridState, GridStateType, Pagination } from './../models/index'; + +export interface GridStateChange { + /** Changes that were triggered */ + change?: { + newValues: CurrentFilter[] | CurrentSorter[] | Pagination; + type: GridStateType; + }; + + /** Current grid state */ + gridState?: GridState; +} diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/models/gridStateType.enum.ts b/aurelia-slickgrid/src/aurelia-slickgrid/models/gridStateType.enum.ts new file mode 100644 index 000000000..ba1983765 --- /dev/null +++ b/aurelia-slickgrid/src/aurelia-slickgrid/models/gridStateType.enum.ts @@ -0,0 +1,5 @@ +export enum GridStateType { + filter = 'filter', + pagination = 'pagination', + sorter = 'sorter' +} diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/models/index.ts b/aurelia-slickgrid/src/aurelia-slickgrid/models/index.ts index 6816dec5e..3af8e3ff8 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/models/index.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/models/index.ts @@ -36,9 +36,11 @@ export * from './graphqlPaginationOption.interface'; export * from './graphqlResult.interface'; export * from './graphqlServiceOption.interface'; export * from './graphqlSortingOption.interface'; -export * from './gridState.interface'; export * from './gridMenu.interface'; export * from './gridOption.interface'; +export * from './gridState.interface'; +export * from './gridStateChange.interface'; +export * from './gridStateType.enum'; export * from './headerButton.interface'; export * from './headerButtonItem.interface'; export * from './headerButtonOnCommandArgs.interface'; diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/services/filter.service.ts b/aurelia-slickgrid/src/aurelia-slickgrid/services/filter.service.ts index 517227b79..d66898eb6 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/services/filter.service.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/services/filter.service.ts @@ -21,19 +21,18 @@ import * as $ from 'jquery'; // using external non-typed js libraries declare var Slick: any; -@inject(FilterFactory) +@inject(EventAggregator, FilterFactory) export class FilterService { private _eventHandler = new Slick.EventHandler(); - private _subscriber: SlickEvent = new Slick.Event(); + private _slickSubscriber: SlickEvent; private _filters: any[] = []; private _columnFilters: ColumnFilters = {}; private _dataView: any; private _grid: any; private _gridOptions: GridOption; private _onFilterChangedOptions: any; - onFilterChanged = new EventAggregator(); - constructor(private filterFactory: FilterFactory) { } + constructor(private ea: EventAggregator, private filterFactory: FilterFactory) { } init(grid: any, gridOptions: GridOption, columnDefinitions: Column[]): void { this._grid = grid; @@ -47,10 +46,10 @@ export class FilterService { */ attachBackendOnFilter(grid: any, options: GridOption) { this._filters = []; - this.emitFilterChangedBy('remote'); + this._slickSubscriber = new Slick.Event(); - this._subscriber = new Slick.Event(); - this._subscriber.subscribe(this.attachBackendOnFilterSubscribe); + // subscribe to the SlickGrid event and call the backend execution + this._slickSubscriber.subscribe(this.attachBackendOnFilterSubscribe.bind(this)); // subscribe to SlickGrid onHeaderRowCellRendered event to create filter template this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: Event, args: any) => { @@ -77,6 +76,9 @@ export class FilterService { // call the service to get a query back const query = await backendApi.service.onFilterChanged(event, args); + // emit an onFilterChanged event + this.emitFilterChanged('remote'); + // await for the Promise to resolve the data const processResult = await backendApi.process(query); @@ -91,6 +93,34 @@ export class FilterService { } } + /** + * Attach a local filter hook to the grid + * @param grid SlickGrid Grid object + * @param gridOptions Grid Options object + * @param dataView + */ + attachLocalOnFilter(grid: any, options: GridOption, dataView: any) { + this._filters = []; + this._dataView = dataView; + this._slickSubscriber = new Slick.Event(); + + dataView.setFilterArgs({ columnFilters: this._columnFilters, grid: this._grid }); + dataView.setFilter(this.customLocalFilter.bind(this, dataView)); + + this._slickSubscriber.subscribe((e: any, args: any) => { + const columnId = args.columnId; + if (columnId != null) { + dataView.refresh(); + } + this.emitFilterChanged('local'); + }); + + // subscribe to SlickGrid onHeaderRowCellRendered event to create filter template + this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: Event, args: any) => { + this.addFilterTemplateToHeaderRow(args); + }); + } + /** Clear the search filters (below the column titles) */ clearFilters() { this._filters.forEach((filter, index) => { @@ -116,34 +146,6 @@ export class FilterService { } } - /** - * Attach a local filter hook to the grid - * @param grid SlickGrid Grid object - * @param gridOptions Grid Options object - * @param dataView - */ - attachLocalOnFilter(grid: any, options: GridOption, dataView: any) { - this._dataView = dataView; - this._filters = []; - this.emitFilterChangedBy('local'); - - dataView.setFilterArgs({ columnFilters: this._columnFilters, grid: this._grid }); - dataView.setFilter(this.customLocalFilter.bind(this, dataView)); - - this._subscriber = new Slick.Event(); - this._subscriber.subscribe((e: any, args: any) => { - const columnId = args.columnId; - if (columnId != null) { - dataView.refresh(); - } - }); - - // subscribe to SlickGrid onHeaderRowCellRendered event to create filter template - this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: Event, args: any) => { - this.addFilterTemplateToHeaderRow(args); - }); - } - customLocalFilter(dataView: any, item: any, args: any) { for (const columnId of Object.keys(args.columnFilters)) { const columnFilter = args.columnFilters[columnId]; @@ -236,8 +238,8 @@ export class FilterService { this._eventHandler.unsubscribeAll(); // unsubscribe local event - if (this._subscriber && typeof this._subscriber.unsubscribe === 'function') { - this._subscriber.unsubscribe(); + if (this._slickSubscriber && typeof this._slickSubscriber.unsubscribe === 'function') { + this._slickSubscriber.unsubscribe(); } } @@ -302,7 +304,7 @@ export class FilterService { }; } - this.triggerEvent(this._subscriber, { + this.triggerEvent(this._slickSubscriber, { columnId, columnDef: args.columnDef || null, columnFilters: this._columnFilters, @@ -378,12 +380,21 @@ export class FilterService { } /** - * A simple function that is attached to the subscriber and emit a change when the sort is called. + * A simple function that will be called to emit a change when a filter changes. * Other services, like Pagination, can then subscribe to it. - * @param {string} sender + * @param sender */ - emitFilterChangedBy(sender: string) { - this._subscriber.subscribe(() => this.onFilterChanged.publish('filterService:changed', `onFilterChanged by ${sender}`)); + emitFilterChanged(sender: 'local' | 'remote') { + if (sender === 'remote' && this._gridOptions && this._gridOptions.backendServiceApi) { + let currentFilters: CurrentFilter[] = []; + const backendService = this._gridOptions.backendServiceApi.service; + if (backendService && backendService.getCurrentFilters) { + currentFilters = backendService.getCurrentFilters() as CurrentFilter[]; + } + this.ea.publish('filterService:filterChanged', currentFilters); + } else if (sender === 'local') { + this.ea.publish('filterService:filterChanged', this.getCurrentLocalFilters()); + } } /** diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/services/gridState.service.ts b/aurelia-slickgrid/src/aurelia-slickgrid/services/gridState.service.ts index 8ee1adb65..574ebec2b 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/services/gridState.service.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/services/gridState.service.ts @@ -1,20 +1,28 @@ +import { inject } from 'aurelia-framework'; import { CurrentFilter, CurrentPagination, CurrentSorter, GridOption, - GridState + GridState, + GridStateType, } from './../models/index'; import { FilterService, SortService } from './../services/index'; +import { EventAggregator, Subscription } from 'aurelia-event-aggregator'; import * as $ from 'jquery'; +@inject(EventAggregator) export class GridStateService { private _grid: any; private _gridOptions: GridOption; private _preset: GridState; private filterService: FilterService; + private _filterSubcription: Subscription; + private _sorterSubcription: Subscription; private sortService: SortService; + constructor(private ea: EventAggregator) { } + /** * Initialize the Export Service * @param grid @@ -26,6 +34,19 @@ export class GridStateService { this.filterService = filterService; this.sortService = sortService; this._gridOptions = (grid && grid.getOptions) ? grid.getOptions() : {}; + + // Subscribe to Event Emitter of Filter & Sort changed, go back to page 1 when that happen + this._filterSubcription = this.ea.subscribe('filterService:filterChanged', (currentFilters: CurrentFilter[]) => { + this.ea.publish('gridStateService:changed', { change: { newValues: currentFilters, type: GridStateType.filter }, gridState: this.getCurrentGridState() }); + }); + this._sorterSubcription = this.ea.subscribe('sortService:sortChanged', (currentSorters: CurrentSorter[]) => { + this.ea.publish('gridStateService:changed', { change: { newValues: currentSorters, type: GridStateType.sorter }, gridState: this.getCurrentGridState() }); + }); + } + + dispose() { + this._filterSubcription.dispose(); + this._sorterSubcription.dispose(); } /** diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/services/sort.service.ts b/aurelia-slickgrid/src/aurelia-slickgrid/services/sort.service.ts index b5c227f55..61a1d64c0 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/services/sort.service.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/services/sort.service.ts @@ -1,3 +1,4 @@ +import { inject } from 'aurelia-framework'; import { EventAggregator } from 'aurelia-event-aggregator'; import { Column, FieldType, GridOption, SlickEvent, SortChanged, SortDirection, CurrentSorter, CellArgs, SortDirectionString } from './../models/index'; import { Sorters } from './../sorters/index'; @@ -5,11 +6,15 @@ import { Sorters } from './../sorters/index'; // using external non-typed js libraries declare var Slick: any; +@inject(EventAggregator) export class SortService { private _currentLocalSorters: CurrentSorter[] = []; private _eventHandler: any = new Slick.EventHandler(); - private _subscriber: SlickEvent = new Slick.Event(); - onSortChanged = new EventAggregator(); + private _grid: any; + private _gridOptions: GridOption; + private _slickSubscriber: SlickEvent = new Slick.Event(); + + constructor(private ea: EventAggregator) { } /** * Attach a backend sort (single/multi) hook to the grid @@ -17,11 +22,12 @@ export class SortService { * @param gridOptions Grid Options object */ attachBackendOnSort(grid: any, gridOptions: GridOption) { - this._subscriber = grid.onSort; - this.emitSortChangedBy('remote'); + this._grid = grid; + this._gridOptions = gridOptions; + this._slickSubscriber = grid.onSort; - this._subscriber = new Slick.Event(); - this._subscriber.subscribe(this.attachBackendOnSortSubscribe); + // subscribe to the SlickGrid event and call the backend execution + this._slickSubscriber.subscribe(this.attachBackendOnSortSubscribe.bind(this)); } async attachBackendOnSortSubscribe(event: Event, args: any) { @@ -38,6 +44,7 @@ export class SortService { backendApi.preProcess(); } const query = backendApi.service.onSortChanged(event, args); + this.emitSortChanged('remote'); // await for the Promise to resolve the data const processResult = await backendApi.process(query); @@ -60,11 +67,11 @@ export class SortService { * @param dataView */ attachLocalOnSort(grid: any, gridOptions: GridOption, dataView: any, columnDefinitions: Column[]) { - this._subscriber = grid.onSort; - this.emitSortChangedBy('local'); + this._grid = grid; + this._gridOptions = gridOptions; + this._slickSubscriber = grid.onSort; - this._subscriber = new Slick.Event(); - this._subscriber.subscribe((e: any, args: any) => { + this._slickSubscriber.subscribe((e: any, args: any) => { // multiSort and singleSort are not exactly the same, but we want to structure it the same for the (for loop) after // also to avoid having to rewrite the for loop in the sort, we will make the singleSort an array of 1 object const sortColumns = (args.multiColumnSort) ? args.sortCols : new Array({ sortAsc: args.sortAsc, sortCol: args.sortCol }); @@ -83,6 +90,7 @@ export class SortService { } this.onLocalSortChanged(grid, gridOptions, dataView, sortColumns); + this.emitSortChanged('local'); }); this._eventHandler.subscribe(dataView.onRowCountChanged, (e: Event, args: any) => { @@ -181,8 +189,8 @@ export class SortService { dispose() { // unsubscribe local event - if (this._subscriber && typeof this._subscriber.unsubscribe === 'function') { - this._subscriber.unsubscribe(); + if (this._slickSubscriber && typeof this._slickSubscriber.unsubscribe === 'function') { + this._slickSubscriber.unsubscribe(); } // unsubscribe all SlickGrid events @@ -190,11 +198,20 @@ export class SortService { } /** - * A simple function that is attached to the subscriber and emit a change when the sort is called. + * A simple function that will be called to emit a change when a sort changes. * Other services, like Pagination, can then subscribe to it. * @param sender */ - emitSortChangedBy(sender: string) { - this._subscriber.subscribe(() => this.onSortChanged.publish('sortService:changed', `onSortChanged by ${sender}`)); + emitSortChanged(sender: 'local' | 'remote') { + if (sender === 'remote' && this._gridOptions && this._gridOptions.backendServiceApi) { + let currentSorters: CurrentSorter[] = []; + const backendService = this._gridOptions.backendServiceApi.service; + if (backendService && backendService.getCurrentSorters) { + currentSorters = backendService.getCurrentSorters() as CurrentSorter[]; + } + this.ea.publish('sortService:sortChanged', currentSorters); + } else if (sender === 'local') { + this.ea.publish('sortService:sortChanged', this.getCurrentLocalSorters()); + } } } diff --git a/aurelia-slickgrid/src/aurelia-slickgrid/slick-pagination.ts b/aurelia-slickgrid/src/aurelia-slickgrid/slick-pagination.ts index e19a91afe..b572ec6d6 100644 --- a/aurelia-slickgrid/src/aurelia-slickgrid/slick-pagination.ts +++ b/aurelia-slickgrid/src/aurelia-slickgrid/slick-pagination.ts @@ -1,13 +1,15 @@ import { bindable, inject } from 'aurelia-framework'; -import { Subscription } from 'aurelia-event-aggregator'; +import { Subscription, EventAggregator } from 'aurelia-event-aggregator'; import { GridOption } from './models/index'; import { FilterService } from './services/filter.service'; import { SortService } from './services/sort.service'; -@inject(FilterService, SortService) +const aureliaEventPrefix = 'asg'; + +@inject(Element, EventAggregator, FilterService, SortService) export class SlickPaginationCustomElement { - private _filterSubcription: Subscription; - private _sorterSubcription: Subscription; + private _filterSubscriber: Subscription; + private _sorterSubscriber: Subscription; @bindable() grid: any; @bindable() gridPaginationOptions: GridOption; private _gridPaginationOptions: GridOption; @@ -22,7 +24,7 @@ export class SlickPaginationCustomElement { paginationCallback: () => void; paginationPageSizes = [25, 75, 100]; - constructor(private filterService: FilterService, private sortService: SortService) { + constructor(private elm: Element, private ea: EventAggregator, private filterService: FilterService, private sortService: SortService) { this.filterService = filterService; this.sortService = sortService; } @@ -34,10 +36,10 @@ export class SlickPaginationCustomElement { } // Subscribe to Event Emitter of Filter & Sort changed, go back to page 1 when that happen - this._filterSubcription = this.filterService.onFilterChanged.subscribe('filterService:changed', (data: string) => { + this._filterSubscriber = this.ea.subscribe('filterService:filterChanged', (data: string) => { this.refreshPagination(true); }); - this._sorterSubcription = this.sortService.onSortChanged.subscribe('sortService:changed', (data: string) => { + this._sorterSubscriber = this.ea.subscribe('sortService:sortChanged', (data: string) => { this.refreshPagination(true); }); } @@ -85,11 +87,11 @@ export class SlickPaginationCustomElement { } dispose() { - if (this._filterSubcription) { - this._filterSubcription.dispose(); + if (this._filterSubscriber) { + this._filterSubscriber.dispose(); } - if (this._sorterSubcription) { - this._sorterSubcription.dispose(); + if (this._sorterSubscriber) { + this._sorterSubscriber.dispose(); } } @@ -171,6 +173,17 @@ export class SlickPaginationCustomElement { } else { throw new Error('Pagination with a backend service requires "BackendServiceApi" to be defined in your grid options'); } + + // dispatch the changes to the parent component + this.elm.dispatchEvent(new CustomEvent(`${aureliaEventPrefix}-on-pagination-changed`, { + bubbles: true, + detail: { + pageNumber: this.pageNumber, + pageSizes: this.paginationPageSizes, + pageSize: this.itemsPerPage, + totalItems: this.totalItems + } + })); } recalculateFromToIndexes() { diff --git a/aurelia-slickgrid/src/examples/slickgrid/example4.html b/aurelia-slickgrid/src/examples/slickgrid/example4.html index b0c9733cd..62ba94a64 100644 --- a/aurelia-slickgrid/src/examples/slickgrid/example4.html +++ b/aurelia-slickgrid/src/examples/slickgrid/example4.html @@ -3,6 +3,6 @@

${title}

+ grid-options.bind="gridOptions" dataset.bind="dataset" asg-on-grid-state-service-changed.delegate="gridStateChanged($event.detail)"> diff --git a/aurelia-slickgrid/src/examples/slickgrid/example4.ts b/aurelia-slickgrid/src/examples/slickgrid/example4.ts index d6e077d63..3ccc6982a 100644 --- a/aurelia-slickgrid/src/examples/slickgrid/example4.ts +++ b/aurelia-slickgrid/src/examples/slickgrid/example4.ts @@ -152,8 +152,13 @@ export class Example4 { } } + /** Dispatched event of a Grid State Changed event */ + gridStateChanged(gridState) { + console.log('Client sample, Grid State changed:: ', gridState); + } + /** Save current Filters, Sorters in LocaleStorage or DB */ saveCurrentGridState() { - console.log('Client current grid state', this.gridStateService.getCurrentGridState()); + console.log('Client sample, current Grid State:: ', this.gridStateService.getCurrentGridState()); } } diff --git a/aurelia-slickgrid/src/examples/slickgrid/example6.ts b/aurelia-slickgrid/src/examples/slickgrid/example6.ts index 9285a0818..3d0639de6 100644 --- a/aurelia-slickgrid/src/examples/slickgrid/example6.ts +++ b/aurelia-slickgrid/src/examples/slickgrid/example6.ts @@ -1,7 +1,8 @@ +import { Subscription, EventAggregator } from 'aurelia-event-aggregator'; import { autoinject } from 'aurelia-framework'; import { I18N } from 'aurelia-i18n'; import { HttpClient } from 'aurelia-http-client'; -import { Column, FieldType, FilterType, GraphqlResult, GraphqlService, GraphqlServiceOption, GridOption, GridStateService, OperatorType, SortDirection } from '../../aurelia-slickgrid'; +import { Column, FieldType, FilterType, Formatters, GraphqlResult, GraphqlService, GraphqlServiceOption, GridOption, GridStateService, OperatorType, SortDirection } from '../../aurelia-slickgrid'; const defaultPageSize = 20; const GRAPHQL_QUERY_DATASET_NAME = 'users'; @@ -32,22 +33,26 @@ export class Example6 { processing = false; selectedLanguage: string; status = { text: '', class: '' }; + Subscription: Subscription; - constructor(private gridStateService: GridStateService, private http: HttpClient, private graphqlService: GraphqlService, private i18n: I18N) { + constructor(private ea: EventAggregator, private gridStateService: GridStateService, private http: HttpClient, private graphqlService: GraphqlService, private i18n: I18N) { // define the grid options & columns and then create the grid itself this.defineGrid(); this.selectedLanguage = this.i18n.getLocale(); + this.Subscription = this.ea.subscribe('gridStateService:changed', (data) => console.log(data)); } detached() { this.saveCurrentGridState(); + this.Subscription.dispose(); } defineGrid() { this.columnDefinitions = [ - { id: 'name', name: 'Name', field: 'name', headerKey: 'NAME', filterable: true, sortable: true, type: FieldType.string }, + { id: 'users', field: 'user.firstName', fields: ['user.middleName', 'user.lastName'], headerKey: 'NAME', filterable: true, sortable: true, type: FieldType.string }, + { id: 'name', field: 'name', headerKey: 'NAME', filterable: true, sortable: true, type: FieldType.string }, { - id: 'gender', name: 'Gender', field: 'gender', headerKey: 'GENDER', filterable: true, sortable: true, + id: 'gender', field: 'gender', headerKey: 'GENDER', filterable: true, sortable: true, filter: { type: FilterType.singleSelect, collection: [{ value: '', label: '' }, { value: 'male', label: 'male', labelKey: 'MALE' }, { value: 'female', label: 'female', labelKey: 'FEMALE' }], @@ -55,7 +60,7 @@ export class Example6 { } }, { - id: 'company', name: 'Company', field: 'company', headerKey: 'COMPANY', + id: 'company', field: 'company', headerKey: 'COMPANY', sortable: true, filterable: true, filter: { @@ -64,8 +69,8 @@ export class Example6 { searchTerms: ['abc'] } }, - { id: 'billing.address.street', name: 'Billing Address Street', field: 'billing.address.street', headerKey: 'BILLING.ADDRESS.STREET', filterable: true, sortable: true }, - { id: 'billing.address.zip', name: 'Billing Address Zip', field: 'billing.address.zip', headerKey: 'BILLING.ADDRESS.ZIP', filterable: true, sortable: true, type: FieldType.number }, + { id: 'billing.address.street', field: 'billing.address.street', headerKey: 'BILLING.ADDRESS.STREET', filterable: true, sortable: true }, + { id: 'billing.address.zip', field: 'billing.address.zip', headerKey: 'BILLING.ADDRESS.ZIP', filterable: true, sortable: true, type: FieldType.number, formatter: Formatters.multiple, params: { formatters: [Formatters.complexObject, Formatters.translate] } }, ]; this.gridOptions = { @@ -84,7 +89,7 @@ export class Example6 { // you can also type operator as string, e.g.: operator: 'EQ' filters: [ { columnId: 'gender', searchTerm: 'male', operator: OperatorType.equal }, - { columnId: 'name', searchTerm: 'John Doe', operator: OperatorType.contains }, + { columnId: 'users', searchTerm: 'John Doe', operator: OperatorType.contains }, { columnId: 'company', searchTerms: ['xyz'], operator: 'IN' } ], sorters: [ @@ -94,6 +99,7 @@ export class Example6 { ], pagination: { pageNumber: 2, pageSize: 20 } }, + backendServiceApi: { service: this.graphqlService, options: this.getBackendOptions(this.isWithCursor),