Skip to content

Commit

Permalink
feat(sort): add a Clear Sorting function and grid menu command (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding authored Apr 4, 2018
1 parent e4fa6b4 commit f709dc7
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 36 deletions.
1 change: 1 addition & 0 deletions aurelia-slickgrid/assets/i18n/en/aurelia-slickgrid.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"ALL_SELECTED": "All Selected",
"CLEAR_ALL_FILTERS": "Clear All Filters",
"CLEAR_ALL_SORTING": "Clear All Sorting",
"COLUMNS": "Columns",
"COMMANDS": "Commands",
"CONTAINS": "Contains",
Expand Down
1 change: 1 addition & 0 deletions aurelia-slickgrid/assets/i18n/fr/aurelia-slickgrid.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"ALL_SELECTED": "Tout sélectionnés",
"CLEAR_ALL_FILTERS": "Effacer tous les filtres",
"CLEAR_ALL_SORTING": "Effacer tous les tris",
"COLUMNS": "Colonnes",
"COMMANDS": "Commandes",
"CONTAINS": "Contient",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export class AureliaSlickgridCustomElement {

// attach external sorting (backend) when available or default onSort (dataView)
if (gridOptions.enableSorting) {
(gridOptions.backendServiceApi || gridOptions.onBackendEventApi) ? this.sortService.attachBackendOnSort(grid, gridOptions) : this.sortService.attachLocalOnSort(grid, gridOptions, this.dataview, this.columnDefinitions);
(gridOptions.backendServiceApi || gridOptions.onBackendEventApi) ? this.sortService.attachBackendOnSort(grid, dataView) : this.sortService.attachLocalOnSort(grid, dataView);
}

// attach external filter (backend) when available or default onFilter (dataView)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,16 @@ export const GlobalGridOptions: GridOption = {
hideForceFitButton: false,
hideSyncResizeButton: true,
iconCssClass: 'fa fa-bars',
iconClearAllFiltersCommand: 'fa fa-filter text-danger',
iconClearAllSortingCommand: 'fa fa-unsorted text-danger',
iconExportCsvCommand: 'fa fa-download',
iconExportTextDelimitedCommand: 'fa fa-download',
iconRefreshDatasetCommand: 'fa fa-refresh',
iconToggleFilterCommand: 'fa fa-random',
menuWidth: 16,
resizeOnShowHeaderRow: false,
showClearAllFiltersCommand: true,
showClearAllSortingCommand: true,
showExportCsvCommand: true,
showRefreshDatasetCommand: true,
showToggleFilterCommand: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ export interface BackendService {
onPaginationChanged: (event: Event | undefined, args: PaginationChangedArgs) => string;

/** Execute when any of the sorters changed */
onSortChanged: (event: Event, args: SortChangedArgs) => string;
onSortChanged: (event: Event | null, args: SortChangedArgs) => string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ export interface GridMenu {
/** Defaults to False, which will resize the Header Row and remove the width of the Grid Menu icon from it's total width. */
resizeOnShowHeaderRow?: boolean;

/** Defaults to True, which will show the "Clear All Filter" command in the Grid Menu (Grid Option "enableFiltering: true" has to be enabled) */
/** Defaults to True, which will show the "Clear All Filters" command in the Grid Menu (Grid Option "enableFiltering: true" has to be enabled) */
showClearAllFiltersCommand?: boolean;

/** Defaults to True, which will show the "Clear All Sorting" command in the Grid Menu (Grid Option "enableSorting: true" has to be enabled) */
showClearAllSortingCommand?: boolean;

/** Defaults to True, which will show the "Export to CSV" command in the Grid Menu (Grid Option "enableExport: true" has to be enabled) */
showExportCsvCommand?: boolean;

Expand All @@ -49,6 +52,24 @@ export interface GridMenu {
/** Defaults to True, which will show the "Toggle Filter Row" command in the Grid Menu (Grid Option "enableFiltering: true" has to be enabled) */
showToggleFilterCommand?: boolean;

/** icon for the "Clear All Filters" command */
iconClearAllFiltersCommand?: string;

/** icon for the "Clear All Sorting" command */
iconClearAllSortingCommand?: string;

/** icon for the "Export to CSV" command */
iconExportCsvCommand?: string;

/** icon for the "Export to Text Delimited" command */
iconExportTextDelimitedCommand?: string;

/** icon for the "Refresh Dataset" command */
iconRefreshDatasetCommand?: string;

/** icon for the "Toggle Filter Row" command */
iconToggleFilterCommand?: string;

/** Defaults to "Synchronous resize" which is 1 of the last 2 checkbox title shown at the end of the picker list */
syncResizeTitle?: string;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { inject } from 'aurelia-framework';
import { I18N } from 'aurelia-i18n';
import { ExportService } from './export.service';
import { FilterService } from './filter.service';
import {
CellArgs,
CustomGridMenu,
Expand All @@ -15,12 +13,15 @@ import {
HeaderMenuOnBeforeMenuShowArgs,
FileType
} from './../models/index';
import { ExportService } from './export.service';
import { FilterService } from './filter.service';
import { SortService } from './sort.service';
import * as $ from 'jquery';

// using external non-typed js libraries
declare var Slick: any;

@inject(ExportService, FilterService, I18N)
@inject(ExportService, FilterService, I18N, SortService)
export class ControlAndPluginService {
private _dataView: any;
private _grid: any;
Expand All @@ -37,7 +38,12 @@ export class ControlAndPluginService {
gridMenuControl: any;
rowSelectionPlugin: any;

constructor(private exportService: ExportService, private filterService: FilterService, private i18n: I18N) { }
constructor(
private exportService: ExportService,
private filterService: FilterService,
private i18n: I18N,
private sortService: SortService
) { }

/**
* Attach/Create different Controls or Plugins after the Grid is created
Expand Down Expand Up @@ -246,7 +252,7 @@ export class ControlAndPluginService {
if (options && options.gridMenu && options.gridMenu.showClearAllFiltersCommand && options.gridMenu.customItems && options.gridMenu.customItems.filter((item: CustomGridMenu) => item.command === 'clear-filter').length === 0) {
options.gridMenu.customItems.push(
{
iconCssClass: 'fa fa-filter text-danger',
iconCssClass: options.gridMenu.iconClearAllFiltersCommand || 'fa fa-filter text-danger',
title: options.enableTranslate ? this.i18n.tr('CLEAR_ALL_FILTERS') : 'Clear All Filters',
disabled: false,
command: 'clear-filter',
Expand All @@ -258,11 +264,11 @@ export class ControlAndPluginService {
if (options && options.gridMenu && options.gridMenu.showToggleFilterCommand && options.gridMenu.customItems && options.gridMenu.customItems.filter((item: CustomGridMenu) => item.command === 'toggle-filter').length === 0) {
options.gridMenu.customItems.push(
{
iconCssClass: 'fa fa-random',
iconCssClass: options.gridMenu.iconToggleFilterCommand || 'fa fa-random',
title: options.enableTranslate ? this.i18n.tr('TOGGLE_FILTER_ROW') : 'Toggle Filter Row',
disabled: false,
command: 'toggle-filter',
positionOrder: 51
positionOrder: 52
}
);
}
Expand All @@ -271,38 +277,52 @@ export class ControlAndPluginService {
if (options && options.gridMenu && options.gridMenu.showRefreshDatasetCommand && backendApi && options.gridMenu.customItems && options.gridMenu.customItems.filter((item: CustomGridMenu) => item.command === 'refresh-dataset').length === 0) {
options.gridMenu.customItems.push(
{
iconCssClass: 'fa fa-refresh',
iconCssClass: options.gridMenu.iconRefreshDatasetCommand || 'fa fa-refresh',
title: options.enableTranslate ? this.i18n.tr('REFRESH_DATASET') : 'Refresh Dataset',
disabled: false,
command: 'refresh-dataset',
positionOrder: 54
}
);
}
}

if (options.enableSorting) {
// show grid menu: clear all sorting
if (options && options.gridMenu && options.gridMenu.showClearAllSortingCommand && options.gridMenu.customItems && options.gridMenu.customItems.filter((item: CustomGridMenu) => item.command === 'clear-sorting').length === 0) {
options.gridMenu.customItems.push(
{
iconCssClass: options.gridMenu.iconClearAllSortingCommand || 'fa fa-unsorted text-danger',
title: options.enableTranslate ? this.i18n.tr('CLEAR_ALL_SORTING') : 'Clear All Sorting',
disabled: false,
command: 'clear-sorting',
positionOrder: 51
}
);
}
}

// show grid menu: export to file
if (options && options.enableExport && options.gridMenu && options.gridMenu.showExportCsvCommand && options.gridMenu.customItems && options.gridMenu.customItems.filter((item: CustomGridMenu) => item.command === 'export-csv').length === 0) {
options.gridMenu.customItems.push(
{
iconCssClass: 'fa fa-download',
iconCssClass: options.gridMenu.iconExportCsvCommand || 'fa fa-download',
title: options.enableTranslate ? this.i18n.tr('EXPORT_TO_CSV') : 'Export in CSV format',
disabled: false,
command: 'export-csv',
positionOrder: 52
positionOrder: 53
}
);
}
// show grid menu: export to text file as tab delimited
if (options && options.enableExport && options.gridMenu && options.gridMenu.showExportTextDelimitedCommand && options.gridMenu.customItems && options.gridMenu.customItems.filter((item: CustomGridMenu) => item.command === 'export-text-delimited').length === 0) {
options.gridMenu.customItems.push(
{
iconCssClass: 'fa fa-download',
iconCssClass: options.gridMenu.iconExportTextDelimitedCommand || 'fa fa-download',
title: options.enableTranslate ? this.i18n.tr('EXPORT_TO_TAB_DELIMITED') : 'Export in Text format (Tab delimited)',
disabled: false,
command: 'export-text-delimited',
positionOrder: 53
positionOrder: 54
}
);
}
Expand All @@ -316,6 +336,10 @@ export class ControlAndPluginService {
this.filterService.clearFilters();
this._dataView.refresh();
break;
case 'clear-sorting':
this.sortService.clearSorting();
this._dataView.refresh();
break;
case 'export-csv':
this.exportService.exportToFile({
delimiter: DelimiterType.comma,
Expand Down
67 changes: 54 additions & 13 deletions aurelia-slickgrid/src/aurelia-slickgrid/services/sort.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ declare var Slick: any;
export class SortService {
private _currentLocalSorters: CurrentSorter[] = [];
private _eventHandler: any = new Slick.EventHandler();
private _dataView: any;
private _grid: any;
private _gridOptions: GridOption;
private _isBackendGrid = false;
private _slickSubscriber: SlickEvent = new Slick.Event();

constructor(private ea: EventAggregator) { }
Expand All @@ -33,18 +35,22 @@ export class SortService {
* @param grid SlickGrid Grid object
* @param gridOptions Grid Options object
*/
attachBackendOnSort(grid: any, gridOptions: GridOption) {
attachBackendOnSort(grid: any, dataView: any) {
this._isBackendGrid = true;
this._grid = grid;
this._gridOptions = gridOptions;
this._dataView = dataView;
if (grid) {
this._gridOptions = grid.getOptions();
}
this._slickSubscriber = grid.onSort;

// subscribe to the SlickGrid event and call the backend execution
this._slickSubscriber.subscribe(this.attachBackendOnSortSubscribe.bind(this));
this._slickSubscriber.subscribe(this.onBackendSortChanged.bind(this));
}

async attachBackendOnSortSubscribe(event: Event, args: any) {
async onBackendSortChanged(event: Event | null, args: any) {
if (!args || !args.grid) {
throw new Error('Something went wrong when trying to attach the "attachBackendOnSortSubscribe(event, args)" function, it seems that "args" is not populated correctly');
throw new Error('Something went wrong when trying to attach the "onBackendSortChanged(event, args)" function, it seems that "args" is not populated correctly');
}
const gridOptions: GridOption = args.grid.getOptions() || {};
const backendApi = gridOptions.backendServiceApi || gridOptions.onBackendEventApi;
Expand Down Expand Up @@ -78,9 +84,16 @@ export class SortService {
* @param gridOptions Grid Options object
* @param dataView
*/
attachLocalOnSort(grid: any, gridOptions: GridOption, dataView: any, columnDefinitions: Column[]) {
attachLocalOnSort(grid: any, dataView: any) {
this._isBackendGrid = false;
this._grid = grid;
this._gridOptions = gridOptions;
this._dataView = dataView;
let columnDefinitions: Column[] = [];

if (grid) {
this._gridOptions = grid.getOptions();
columnDefinitions = grid.getColumns();
}
this._slickSubscriber = grid.onSort;

this._slickSubscriber.subscribe((e: any, args: any) => {
Expand All @@ -101,16 +114,44 @@ export class SortService {
});
}

this.onLocalSortChanged(grid, gridOptions, dataView, sortColumns);
this.onLocalSortChanged(grid, this._gridOptions, dataView, sortColumns);
this.emitSortChanged('local');
});

this._eventHandler.subscribe(dataView.onRowCountChanged, (e: Event, args: any) => {
// load any presets if there are any
if (args.current > 0) {
this.loadLocalPresets(grid, gridOptions, dataView, columnDefinitions);
if (dataView && dataView.onRowCountChanged) {
this._eventHandler.subscribe(dataView.onRowCountChanged, (e: Event, args: any) => {
// load any presets if there are any
if (args.current > 0) {
this.loadLocalPresets(grid, this._gridOptions, dataView, columnDefinitions);
}
});
}
}

/**
* Clear Sorting
* - 1st, remove the SlickGrid sort icons (this setSortColumns function call really does only that)
* - 2nd, we also need to trigger a sort change
* - for a backend grid, we will trigger a backend sort changed with an empty sort columns array
* - however for a local grid, we need to pass a sort column and so we will sort by the 1st column
*/
clearSorting() {
if (this._grid && this._gridOptions && this._dataView) {
// remove any sort icons (this setSortColumns function call really does only that)
this._grid.setSortColumns([]);

// we also need to trigger a sort change
// for a backend grid, we will trigger a backend sort changed with an empty sort columns array
// however for a local grid, we need to pass a sort column and so we will sort by the 1st column
if (this._isBackendGrid) {
this.onBackendSortChanged(null, { grid: this._grid, sortCols: [] });
} else {
const columnDefinitions = this._grid.getColumns() as Column[];
if (columnDefinitions && Array.isArray(columnDefinitions)) {
this.onLocalSortChanged(this._grid, this._gridOptions, this._dataView, new Array({ sortAsc: true, sortCol: columnDefinitions[0] }));
}
}
});
}
}

getCurrentLocalSorters(): CurrentSorter[] {
Expand Down
18 changes: 14 additions & 4 deletions aurelia-slickgrid/src/examples/slickgrid/example9.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { autoinject, bindable } from 'aurelia-framework';
import { Column, FieldType, FilterType, FilterService, Formatter, Formatters, GridOption } from '../../aurelia-slickgrid';
import { Column, FieldType, FilterType, FilterService, Formatter, Formatters, GridOption, SortService } from '../../aurelia-slickgrid';

@autoinject()
export class Example9 {
Expand All @@ -22,7 +22,7 @@ export class Example9 {
dataset = [];
visibleColumns;

constructor(private filterService: FilterService) {
constructor(private filterService: FilterService, private sortService: SortService) {
// define the grid options & columns and then create the grid itself
this.defineGrid();
}
Expand Down Expand Up @@ -89,19 +89,26 @@ export class Example9 {
command: 'clear-filter',
positionOrder: 0
},
{
iconCssClass: 'fa fa-unsorted text-danger',
title: 'Clear All Sorting',
disabled: false,
command: 'clear-sorting',
positionOrder: 1
},
{
iconCssClass: 'fa fa-random',
title: 'Toggle Filter Row',
disabled: false,
command: 'toggle-filter',
positionOrder: 1
positionOrder: 2
},
{
iconCssClass: 'fa fa-random',
title: 'Toggle Top Panel',
disabled: false,
command: 'toggle-toppanel',
positionOrder: 2
positionOrder: 3
},
{
iconCssClass: 'fa fa-question-circle',
Expand All @@ -125,6 +132,9 @@ export class Example9 {
} else if (args.command === 'clear-filter') {
this.filterService.clearFilters();
this.dataviewObj.refresh();
} else if (args.command === 'clear-sorting') {
this.sortService.clearSorting();
this.dataviewObj.refresh();
} else {
alert('Command: ' + args.command);
}
Expand Down
Loading

0 comments on commit f709dc7

Please sign in to comment.