From 4620d0c7ebabe43fe1d082a04cc270040753e1ea Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Thu, 28 Oct 2021 14:00:47 -0400 Subject: [PATCH] demo: update to latest version 3.3.0 --- README.md | 1 + bootstrap4-demo-with-locales/README.md | 1 + bootstrap4-demo-with-locales/package.json | 13 +- .../src/app/app-routing.module.ts | 2 + .../src/app/app.component.html | 5 + .../src/app/app.module.ts | 2 + .../grid-composite-editor.component.ts | 1 - .../grid-custom-tooltip.component.html | 25 + .../grid-custom-tooltip.component.scss | 58 +++ .../examples/grid-custom-tooltip.component.ts | 484 ++++++++++++++++++ .../src/app/examples/grid-range.component.ts | 2 +- .../app/examples/grid-rowmove.component.ts | 3 +- bootstrap4-demo-with-translate/README.md | 1 + bootstrap4-demo-with-translate/package.json | 13 +- .../src/app/app-routing.module.ts | 2 + .../src/app/app.component.html | 5 + .../src/app/app.module.ts | 2 + .../grid-composite-editor.component.ts | 1 - .../grid-custom-tooltip.component.html | 25 + .../grid-custom-tooltip.component.scss | 58 +++ .../examples/grid-custom-tooltip.component.ts | 484 ++++++++++++++++++ .../src/app/examples/grid-range.component.ts | 2 +- .../app/examples/grid-rowmove.component.ts | 3 +- bootstrap5-demo-with-translate/README.md | 1 + bootstrap5-demo-with-translate/package.json | 13 +- .../src/app/app-routing.module.ts | 2 + .../src/app/app.component.html | 5 + .../src/app/app.module.ts | 2 + .../grid-composite-editor.component.ts | 1 - .../grid-custom-tooltip.component.html | 25 + .../grid-custom-tooltip.component.scss | 58 +++ .../examples/grid-custom-tooltip.component.ts | 484 ++++++++++++++++++ .../src/app/examples/grid-range.component.ts | 2 +- .../app/examples/grid-rowmove.component.ts | 3 +- 34 files changed, 1762 insertions(+), 27 deletions(-) create mode 100644 bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.html create mode 100644 bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.scss create mode 100644 bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.ts create mode 100644 bootstrap4-demo-with-translate/src/app/examples/grid-custom-tooltip.component.html create mode 100644 bootstrap4-demo-with-translate/src/app/examples/grid-custom-tooltip.component.scss create mode 100644 bootstrap4-demo-with-translate/src/app/examples/grid-custom-tooltip.component.ts create mode 100644 bootstrap5-demo-with-translate/src/app/examples/grid-custom-tooltip.component.html create mode 100644 bootstrap5-demo-with-translate/src/app/examples/grid-custom-tooltip.component.scss create mode 100644 bootstrap5-demo-with-translate/src/app/examples/grid-custom-tooltip.component.ts diff --git a/README.md b/README.md index f18d8b82..0f9f8a41 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Again the following dependencies are totally **OPTIONAL** | Package Name | Version | Description | | ------------ | ------- | ----------- | | [@slickgrid-universal/composite-editor-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/composite-editor-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/composite-editor-component.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/composite-editor-component) | Composite Editor Modal Component | +| [@slickgrid-universal/custom-tooltip-plugin](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/custom-tooltip-plugin) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/custom-tooltip-plugin.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/custom-tooltip-plugin) | Composite Editor Modal Component | | [@slickgrid-universal/excel-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/excel-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/excel-export.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/excel-export) | Export to Excel Service (xls/xlsx) | | [@slickgrid-universal/text-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/text-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/text-export.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/text-export) | Export to Text File Service (csv/txt) | | [@slickgrid-universal/graphql](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/graphql) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/graphql.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/graphql) | GraphQL Query Service (support Filter/Sort/Pagination) | diff --git a/bootstrap4-demo-with-locales/README.md b/bootstrap4-demo-with-locales/README.md index 6eeb74ff..95e0f2e8 100644 --- a/bootstrap4-demo-with-locales/README.md +++ b/bootstrap4-demo-with-locales/README.md @@ -9,6 +9,7 @@ Again the following dependencies are totally **OPTIONAL** | Package Name | Version | Description | | ------------ | ------- | ----------- | | [@slickgrid-universal/composite-editor-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/composite-editor-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/composite-editor-component.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/composite-editor-component) | Composite Editor Modal Component | +| [@slickgrid-universal/custom-tooltip-plugin](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/custom-tooltip-plugin) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/custom-tooltip-plugin.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/custom-tooltip-plugin) | Composite Editor Modal Component | | [@slickgrid-universal/excel-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/excel-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/excel-export.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/excel-export) | Export to Excel Service (xls/xlsx) | | [@slickgrid-universal/text-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/text-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/text-export.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/text-export) | Export to Text File Service (csv/txt) | | [@slickgrid-universal/graphql](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/graphql) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/graphql.svg?color=forest)](https://www.npmjs.com/package/@slickgrid-universal/graphql) | GraphQL Query Service (support Filter/Sort/Pagination) | diff --git a/bootstrap4-demo-with-locales/package.json b/bootstrap4-demo-with-locales/package.json index 26b93703..7aead04b 100644 --- a/bootstrap4-demo-with-locales/package.json +++ b/bootstrap4-demo-with-locales/package.json @@ -22,12 +22,13 @@ "@angular/platform-browser-dynamic": "^12.2.7", "@angular/router": "^12.2.7", "@ng-select/ng-select": "^7.3.0", - "@slickgrid-universal/composite-editor-component": "^0.18.0", - "@slickgrid-universal/excel-export": "^0.18.0", - "@slickgrid-universal/graphql": "^0.18.0", - "@slickgrid-universal/odata": "^0.18.0", - "@slickgrid-universal/text-export": "^0.18.0", - "angular-slickgrid": "^3.2.0", + "@slickgrid-universal/composite-editor-component": "^0.19.0", + "@slickgrid-universal/custom-tooltip-plugin": "^0.19.0", + "@slickgrid-universal/excel-export": "^0.19.0", + "@slickgrid-universal/graphql": "^0.19.0", + "@slickgrid-universal/odata": "^0.19.0", + "@slickgrid-universal/text-export": "^0.19.0", + "angular-slickgrid": "^3.3.0", "bootstrap": "^4.6.0", "custom-event-polyfill": "^1.0.7", "font-awesome": "^4.7.0", diff --git a/bootstrap4-demo-with-locales/src/app/app-routing.module.ts b/bootstrap4-demo-with-locales/src/app/app-routing.module.ts index 2c7a667e..694a097c 100644 --- a/bootstrap4-demo-with-locales/src/app/app-routing.module.ts +++ b/bootstrap4-demo-with-locales/src/app/app-routing.module.ts @@ -8,6 +8,7 @@ import { GridClientSideComponent } from './examples/grid-clientside.component'; import { GridColspanComponent } from './examples/grid-colspan.component'; import { GridCompositeEditorComponent } from './examples/grid-composite-editor.component'; import { GridContextMenuComponent } from './examples/grid-contextmenu.component'; +import { GridCustomTooltipComponent } from './examples/grid-custom-tooltip.component'; import { GridDraggableGroupingComponent } from './examples/grid-draggrouping.component'; import { GridEditorComponent } from './examples/grid-editor.component'; import { GridFormatterComponent } from './examples/grid-formatter.component'; @@ -42,6 +43,7 @@ const routes: Routes = [ { path: 'colspan', component: GridColspanComponent }, { path: 'composite-editor', component: GridCompositeEditorComponent }, { path: 'context', component: GridContextMenuComponent }, + { path: 'custom-tooltip', component: GridCustomTooltipComponent }, { path: 'editor', component: GridEditorComponent }, { path: 'formatter', component: GridFormatterComponent }, { path: 'frozen', component: GridFrozenComponent }, diff --git a/bootstrap4-demo-with-locales/src/app/app.component.html b/bootstrap4-demo-with-locales/src/app/app.component.html index 1241fc5f..d0841150 100644 --- a/bootstrap4-demo-with-locales/src/app/app.component.html +++ b/bootstrap4-demo-with-locales/src/app/app.component.html @@ -135,6 +135,11 @@ 31- Resize by Cell Content + diff --git a/bootstrap4-demo-with-locales/src/app/app.module.ts b/bootstrap4-demo-with-locales/src/app/app.module.ts index 7d8eb0fe..add2c72a 100644 --- a/bootstrap4-demo-with-locales/src/app/app.module.ts +++ b/bootstrap4-demo-with-locales/src/app/app.module.ts @@ -18,6 +18,7 @@ import { GridClientSideComponent } from './examples/grid-clientside.component'; import { GridColspanComponent } from './examples/grid-colspan.component'; import { GridCompositeEditorComponent } from './examples/grid-composite-editor.component'; import { GridContextMenuComponent } from './examples/grid-contextmenu.component'; +import { GridCustomTooltipComponent } from './examples/grid-custom-tooltip.component'; import { GridDraggableGroupingComponent } from './examples/grid-draggrouping.component'; import { GridEditorComponent } from './examples/grid-editor.component'; import { GridFormatterComponent } from './examples/grid-formatter.component'; @@ -71,6 +72,7 @@ import 'flatpickr/dist/l10n/fr'; GridColspanComponent, GridCompositeEditorComponent, GridContextMenuComponent, + GridCustomTooltipComponent, GridEditorComponent, GridDraggableGroupingComponent, GridFormatterComponent, diff --git a/bootstrap4-demo-with-locales/src/app/examples/grid-composite-editor.component.ts b/bootstrap4-demo-with-locales/src/app/examples/grid-composite-editor.component.ts index b506d748..49f1f3bd 100644 --- a/bootstrap4-demo-with-locales/src/app/examples/grid-composite-editor.component.ts +++ b/bootstrap4-demo-with-locales/src/app/examples/grid-composite-editor.component.ts @@ -23,7 +23,6 @@ import { SlickNamespace, SortComparers, } from 'angular-slickgrid'; -import './grid-composite-editor.component.scss'; const NB_ITEMS = 500; const URL_COUNTRIES_COLLECTION = 'assets/data/countries.json'; diff --git a/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.html b/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.html new file mode 100644 index 00000000..79d5a939 --- /dev/null +++ b/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.html @@ -0,0 +1,25 @@ +
+

+ {{title}} + + + code + + +

+
+ +
+ + +
+ + + +
diff --git a/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.scss b/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.scss new file mode 100644 index 00000000..217c8d75 --- /dev/null +++ b/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.scss @@ -0,0 +1,58 @@ +@import '@slickgrid-universal/common/dist/styles/sass/slickgrid-theme-bootstrap.scss'; + +// -- +// Custom Tooltips CSS Variables (or SASS equivalent) +// ---------------------------------------------------- +// :root { +// --slick-tooltip-background-color: #363636; +// --slick-tooltip-border-color: #252525; +// --slick-tooltip-border: 2px solid #252525; +// --slick-tooltip-color: #ffffff; + +// --slick-tooltip-arrow-color: var(--slick-tooltip-border-color); +// --slick-tooltip-arrow-size: 10px; +// --slick-tooltip-arrow-side-margin: 15px; +// } + +.header-tooltip-title { + font-weight: bold; + font-size: 14px; +} +.headerrow-tooltip-title { + color: #AD0041; + font-style: italic; + font-size: 13px; + font-weight: bold; +} + +// it's preferable to use CSS Variables (or SASS) but if you want to change colors of your tooltip for 1 column in particular you can do it this way +// e.g. change css of 5th column 4 (zero index: l4) +.l4 .header-tooltip-title, +.l4 .headerrow-tooltip-title { + color: #ffffff; +} +.l4.slick-custom-tooltip { + color: #ffffff; + background-color: #363636; + border: 2px solid #252525; +} +.l4.slick-custom-tooltip.arrow-down::after, +.l4.slick-custom-tooltip.arrow-up::after { + border-width: 10px; // arrow size +} +.l4.slick-custom-tooltip.arrow-down::after { + border-top-color: #252525; // arrow down color +} +.l4.slick-custom-tooltip.arrow-up::after { + top: -20px; // arrow size * 2 + border-bottom-color: #252525; // arrow up color +} +.l4.slick-custom-tooltip.arrow-left-align::after { + margin-left: 15px; +} +.l4.slick-custom-tooltip.arrow-right-align::after { + margin-left: calc(100% - 20px - 15px); // 20px is (arrow size * 2), 15px is your extra side margin +} +.l6.slick-custom-tooltip.arrow-left-align::after { + margin-left: 4px; +} \ No newline at end of file diff --git a/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.ts b/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.ts new file mode 100644 index 00000000..ae6e237e --- /dev/null +++ b/bootstrap4-demo-with-locales/src/app/examples/grid-custom-tooltip.component.ts @@ -0,0 +1,484 @@ +import { Component, OnInit, ViewEncapsulation, } from '@angular/core'; +import { SlickCustomTooltip } from '@slickgrid-universal/custom-tooltip-plugin'; +import { ExcelExportService } from '@slickgrid-universal/excel-export'; +import { + AngularGridInstance, + Column, + EditCommand, + Editors, + FieldType, + Filters, + Formatter, + Formatters, + GridOption, + MenuCommandItemCallbackArgs, + OperatorType, + SlickGrid, +} from 'angular-slickgrid'; + +const NB_ITEMS = 500; + +@Component({ + templateUrl: './grid-custom-tooltip.component.html', + styleUrls: ['./grid-custom-tooltip.component.scss'], + encapsulation: ViewEncapsulation.None, +}) +export class GridCustomTooltipComponent implements OnInit { + title = 'Example 32: Regular & Custom Tooltips'; + subTitle = ` + This demo shows how to create Regular & Custom Tooltips (Wiki docs) +
+ + `; + angularGrid!: AngularGridInstance; + columnDefinitions!: Column[]; + editCommandQueue: EditCommand[] = []; + gridOptions!: GridOption; + dataset!: any[]; + serverApiDelay = 500; + + constructor() { } + + ngOnInit(): void { + this.initializeGrid(); + + // mock a dataset + this.dataset = this.loadData(NB_ITEMS); + } + + angularGridReady(angularGrid: AngularGridInstance) { + this.angularGrid = angularGrid; + } + + initializeGrid() { + this.columnDefinitions = [ + { + id: 'title', name: 'Title', field: 'title', sortable: true, type: FieldType.string, + editor: { + model: Editors.longText, + required: true, + alwaysSaveOnEnterKey: true, + minLength: 5, + maxLength: 255, + }, + filterable: true, + customTooltip: { + position: 'right-align', // defaults to "auto" + // you can use the Custom Tooltip in 2 ways (synchronous or asynchronous) + // example 1 (sync): + // formatter: this.tooltipTaskFormatter, + + // example 2 (async): + // when using async, the `formatter` will contain the loading spinner + // you will need to provide an `asyncPost` function returning a Promise and also `asyncPostFormatter` formatter to display the result once the Promise resolves + formatter: () => `
loading...
`, + asyncProcess: () => new Promise(resolve => { + setTimeout(() => resolve({ ratio: Math.random() * 10 / 10, lifespan: Math.random() * 100 }), this.serverApiDelay); + }), + asyncPostFormatter: this.tooltipTaskAsyncFormatter as Formatter, + + // optional conditional usability callback + // usabilityOverride: (args) => !!(args.dataContext?.id % 2) // show it only every second row + }, + }, + { + id: 'duration', name: 'Duration', field: 'duration', sortable: true, filterable: true, + editor: { + model: Editors.float, + // required: true, + decimal: 2, + valueStep: 1, + maxValue: 10000, + alwaysSaveOnEnterKey: true, + }, + formatter: (row, cell, value) => value > 1 ? `${value} days` : `${value} day`, + type: FieldType.number, + }, + { + id: 'desc', name: `Description`, field: 'description', width: 100, filterable: true, + editor: { + model: Editors.longText, + required: true, + alwaysSaveOnEnterKey: true, + minLength: 5, + maxLength: 255, + }, + formatter: (row: number, cell: number, value: any, column: Column, dataContext) => `${value || ''}`, + // define tooltip options here OR for the entire grid via the grid options (cell tooltip options will have precedence over grid options) + customTooltip: { + useRegularTooltip: true, // note regular tooltip will try to find a "title" attribute in the cell formatter (it won't work without a cell formatter) + }, + }, + { + id: 'desc2', name: `Description 2`, field: 'description', width: 100, filterable: true, + editor: { + model: Editors.longText, + required: true, + alwaysSaveOnEnterKey: true, + minLength: 5, + maxLength: 255, + }, + formatter: (row: number, cell: number, value: any, column: Column, dataContext) => `${value || ''}`, + // define tooltip options here OR for the entire grid via the grid options (cell tooltip options will have precedence over grid options) + customTooltip: { + useRegularTooltip: true, // note regular tooltip will try to find a "title" attribute in the cell formatter (it won't work without a cell formatter) + useRegularTooltipFromFormatterOnly: true, + // renderRegularTooltipAsHtml: true, // defaults to false, regular "title" tooltip won't be rendered as html unless specified via this flag (also "\r\n" will be replaced by
) + // maxWidth: 75, + // maxHeight: 30, + }, + }, + { + id: 'cost', name: 'Cost', field: 'cost', + width: 90, + sortable: true, + filterable: true, + // filter: { model: Filters.compoundInput }, + // formatter: Formatters.dollar, + formatter: Formatters.multiple, + // params: { formatters: [Formatters.dollar, (row, cell, value) => `${value || ''}`] }, + params: { formatters: [Formatters.dollar, (_row: number, _cell: number, value: any) => `${value || ''}`] }, + customTooltip: { + useRegularTooltip: true, + useRegularTooltipFromFormatterOnly: true, + }, + type: FieldType.number, + }, + { + id: 'percentComplete', name: '% Complete', field: 'percentComplete', type: FieldType.number, + editor: { + model: Editors.slider, + minValue: 0, + maxValue: 100, + // params: { hideSliderNumber: true }, + }, + formatter: Formatters.percentCompleteBar, + sortable: true, filterable: true, + filter: { model: Filters.slider, operator: '>=' }, + customTooltip: { useRegularTooltip: true, }, + }, + { + id: 'start', name: 'Start', field: 'start', sortable: true, + // formatter: Formatters.dateIso, + type: FieldType.date, outputType: FieldType.dateIso, + filterable: true, filter: { model: Filters.compoundDate }, + formatter: Formatters.dateIso, + editor: { model: Editors.date }, + // we can delay a tooltip via the async process + customTooltip: { + // 1- loading formatter + formatter: () => ``, // return empty so it won't show any pre-tooltip + + // 2- delay the opening by a simple Promise and `setTimeout` + asyncProcess: () => new Promise(resolve => { + setTimeout(() => resolve({}), this.serverApiDelay); // delayed by half a second + }), + asyncPostFormatter: this.tooltipFormatter.bind(this) as Formatter, + }, + }, + { + id: 'finish', name: 'Finish', field: 'finish', sortable: true, + editor: { model: Editors.date, editorOptions: { minDate: 'today' }, }, + // formatter: Formatters.dateIso, + type: FieldType.date, outputType: FieldType.dateIso, + formatter: Formatters.dateIso, + filterable: true, filter: { model: Filters.dateRange }, + // you could disable the custom/regular tooltip via either of the following 2 options + disableTooltip: true, + // customTooltip: { + // usabilityOverride: (args) => false, + // }, + }, + { + id: 'effortDriven', name: 'Effort Driven', field: 'effortDriven', + width: 80, minWidth: 20, maxWidth: 100, + cssClass: 'cell-effort-driven', + sortable: true, + filterable: true, + filter: { + collection: [{ value: '', label: '' }, { value: true, label: 'True' }, { value: false, label: 'False' }], + model: Filters.singleSelect + }, + exportWithFormatter: false, + formatter: Formatters.checkmarkMaterial, + }, + { + id: 'prerequisites', name: 'Prerequisites', field: 'prerequisites', filterable: true, + formatter: (_row, _cell, value) => { + if (value && Array.isArray(value)) { + const values = value.map((val) => `Task ${val}`).join(', '); + return `${values}`; + } + return ''; + }, + customTooltip: { + useRegularTooltip: true, + maxWidth: 500, + }, + exportWithFormatter: true, + sanitizeDataExport: true, + minWidth: 100, + sortable: true, + type: FieldType.string, + editor: { + // OR 1- use "fetch client", they are both supported + // collectionAsync: fetch(URL_SAMPLE_COLLECTION_DATA), + + // OR 2- use a Promise + collectionAsync: new Promise((resolve) => { + setTimeout(() => { + resolve(Array.from(Array(this.dataset.length).keys()).map(k => ({ value: k, label: k, prefix: 'Task', suffix: 'days' }))); + }, 500); + }), + customStructure: { + label: 'label', + value: 'value', + labelPrefix: 'prefix', + }, + collectionOptions: { + separatorBetweenTextLabels: ' ' + }, + model: Editors.multipleSelect, + }, + filter: { + // collectionAsync: fetch(URL_SAMPLE_COLLECTION_DATA), + collectionAsync: new Promise((resolve) => { + setTimeout(() => { + resolve(Array.from(Array(this.dataset.length).keys()).map(k => ({ value: k, label: `Task ${k}` }))); + }); + }), + customStructure: { + label: 'label', + value: 'value', + labelPrefix: 'prefix', + }, + collectionOptions: { + separatorBetweenTextLabels: ' ' + }, + model: Filters.multipleSelect, + operator: OperatorType.inContains, + }, + }, + { + id: 'action', name: 'Action', field: 'action', width: 70, minWidth: 70, maxWidth: 70, + formatter: () => `
`, + excludeFromExport: true, + cellMenu: { + hideCloseButton: false, + width: 175, + commandTitle: 'Commands', + commandItems: [ + // array of command item objects, you can also use the "positionOrder" that will be used to sort the items in the list + { + command: 'command2', title: 'Command 2', positionOrder: 62, + // you can use the "action" callback and/or use "onCallback" callback from the grid options, they both have the same arguments + action: (_e, args) => { + console.log(args.dataContext, args.column); + // action callback.. do something + }, + // only enable command when the task is not completed + itemUsabilityOverride: (args) => { + return !args.dataContext.completed; + } + }, + { command: 'command1', title: 'Command 1', cssClass: 'orange', positionOrder: 61 }, + { + command: 'delete-row', title: 'Delete Row', positionOrder: 64, + iconCssClass: 'mdi mdi-close', cssClass: 'red', textCssClass: 'bold', + // only show command to 'Delete Row' when the task is not completed + itemVisibilityOverride: (args) => { + return !args.dataContext.completed; + } + }, + // you can pass divider as a string or an object with a boolean (if sorting by position, then use the object) + // note you should use the "divider" string only when items array is already sorted and positionOrder are not specified + { divider: true, command: '', positionOrder: 63 }, + // 'divider', + { + command: 'help', + title: 'Help', + iconCssClass: 'mdi mdi-help-circle-outline', + positionOrder: 66, + }, + { command: 'something', title: 'Disabled Command', disabled: true, positionOrder: 67, } + ], + } + }, + ]; + + this.gridOptions = { + autoEdit: true, // true single click (false for double-click) + autoCommitEdit: true, + editable: true, + autoResize: { + container: '#demo-container', + }, + enableAutoSizeColumns: true, + enableAutoResize: true, + enableCellNavigation: true, + enableExcelExport: true, + excelExportOptions: { + exportWithFormatter: true + }, + // Custom Tooltip options can be defined in a Column or Grid Options or a mixed of both (first options found wins) + registerExternalResources: [new SlickCustomTooltip(), new ExcelExportService()], + customTooltip: { + formatter: this.tooltipFormatter.bind(this) as Formatter, + headerFormatter: this.headerFormatter, + headerRowFormatter: this.headerRowFormatter, + usabilityOverride: (args) => (args.cell !== 0 && args?.column?.id !== 'action'), // don't show on first/last columns + // hideArrow: true, // defaults to False + }, + presets: { + filters: [{ columnId: 'prerequisites', searchTerms: [1, 3, 5, 7, 9, 12, 15, 18, 21, 25, 28, 29, 30, 32, 34] }], + }, + rowHeight: 33, + enableFiltering: true, + rowSelectionOptions: { + // True (Single Selection), False (Multiple Selections) + selectActiveRow: false + }, + showCustomFooter: true, + enableCheckboxSelector: true, + enableRowSelection: true, + checkboxSelector: { + hideInFilterHeaderRow: false, + hideInColumnTitleRow: true, + }, + editCommandHandler: (_item: any, _column: Column, editCommand: EditCommand) => { + this.editCommandQueue.push(editCommand); + editCommand.execute(); + }, + // when using the cellMenu, you can change some of the default options and all use some of the callback methods + enableCellMenu: true, + cellMenu: { + // all the Cell Menu callback methods (except the action callback) + // are available under the grid options as shown below + onCommand: (e, args) => this.executeCommand(e, args), + onOptionSelected: (_e, args) => { + // change "Completed" property with new option selected from the Cell Menu + const dataContext = args && args.dataContext; + if (dataContext && dataContext.hasOwnProperty('completed')) { + dataContext.completed = args.item.option; + this.angularGrid.gridService.updateItem(dataContext); + } + }, + }, + }; + } + + loadData(itemCount: number): any[] { + // mock a dataset + // mock data + const tmpArray = []; + for (let i = 0; i < itemCount; i++) { + const randomYear = 2000 + Math.floor(Math.random() * 10); + const randomFinishYear = (new Date().getFullYear() - 3) + Math.floor(Math.random() * 10); // use only years not lower than 3 years ago + const randomMonth = Math.floor(Math.random() * 11); + const randomDay = Math.floor((Math.random() * 29)); + const randomFinish = new Date(randomFinishYear, (randomMonth + 1), randomDay); + + tmpArray[i] = { + id: i, + title: 'Task ' + i, + duration: Math.round(Math.random() * 100), + description: `This is a sample task description.\nIt can be multiline\r\rAnother line...`, + percentComplete: Math.floor(Math.random() * (100 - 5 + 1) + 5), + start: new Date(randomYear, randomMonth, randomDay), + finish: randomFinish < new Date() ? '' : randomFinish, // make sure the random date is earlier than today + cost: (i % 33 === 0) ? null : Math.round(Math.random() * 10000) / 100, + effortDriven: (i % 5 === 0), + prerequisites: (i % 2 === 0) && i !== 0 && i < 50 ? [i, i - 1] : [], + }; + } + + return tmpArray; + } + + executeCommand(_e: Event, args: MenuCommandItemCallbackArgs) { + // const columnDef = args.column; + const command = args.command; + const dataContext = args.dataContext; + + switch (command) { + case 'command1': + alert('Command 1'); + break; + case 'command2': + alert('Command 2'); + break; + case 'help': + alert('Please help!'); + break; + case 'delete-row': + if (confirm(`Do you really want to delete row (${(args.row || 0) + 1}) with "${dataContext.title}"`)) { + this.angularGrid?.gridService.deleteItemById(dataContext.id); + } + break; + } + } + + headerFormatter(row: number, cell: number, value: any, column: Column) { + const tooltipTitle = 'Custom Tooltip - Header'; + return `
${tooltipTitle}
+
Column:
${column.name}
`; + } + + headerRowFormatter(row: number, cell: number, value: any, column: Column) { + const tooltipTitle = 'Custom Tooltip - Header Row (filter)'; + return `
${tooltipTitle}
+
Column:
${column.field}
`; + } + + tooltipFormatter(row: number, cell: number, value: any, column: Column, dataContext: any, grid: SlickGrid) { + const tooltipTitle = 'Custom Tooltip'; + const effortDrivenHtml = Formatters.checkmarkMaterial(row, cell, dataContext.effortDriven, column, dataContext, grid); + + return `
${tooltipTitle}
+
Id:
${dataContext.id}
+
Title:
${dataContext.title}
+
Effort Driven:
${effortDrivenHtml}
+
Completion:
${this.loadCompletionIcons(dataContext.percentComplete)}
+ `; + } + + tooltipTaskAsyncFormatter(row: number, cell: number, value: any, column: Column, dataContext: any, grid: SlickGrid) { + const tooltipTitle = `Task ${dataContext.id} - (async tooltip)`; + + // use a 2nd Formatter to get the percent completion + // any properties provided from the `asyncPost` will end up in the `__params` property (unless a different prop name is provided via `asyncParamsPropName`) + const completionBar = Formatters.percentCompleteBarWithText(row, cell, dataContext.percentComplete, column, dataContext, grid); + const out = `
${tooltipTitle}
+
Completion:
${completionBar}
+
Lifespan:
${dataContext.__params.lifespan.toFixed(2)}
+
Ratio:
${dataContext.__params.ratio.toFixed(2)}
+ `; + return out; + } + + loadCompletionIcons(percentComplete: number) { + let output = ''; + let iconCount = 0; + if (percentComplete > 5 && percentComplete < 25) { + iconCount = 1; + } else if (percentComplete >= 25 && percentComplete < 50) { + iconCount = 2; + } else if (percentComplete >= 50 && percentComplete < 75) { + iconCount = 3; + } else if (percentComplete >= 75 && percentComplete < 100) { + iconCount = 4; + } else if (percentComplete === 100) { + iconCount = 5; + } + for (let i = 0; i < iconCount; i++) { + const iconColor = iconCount === 5 ? 'text-success' : iconCount >= 3 ? 'text-warning' : 'text-secondary'; + output += ``; + } + return output; + } +} diff --git a/bootstrap4-demo-with-locales/src/app/examples/grid-range.component.ts b/bootstrap4-demo-with-locales/src/app/examples/grid-range.component.ts index e4b52373..a24b5a92 100644 --- a/bootstrap4-demo-with-locales/src/app/examples/grid-range.component.ts +++ b/bootstrap4-demo-with-locales/src/app/examples/grid-range.component.ts @@ -36,7 +36,7 @@ export class GridRangeComponent implements OnInit { This demo shows how to use Filters with Range of Search Values (Wiki docs)