### Clone and Run Angular-Slickgrid Demo
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/README.md
Clone the Angular-Slickgrid demos repository, navigate to a specific demo directory, install dependencies, and start the development server.
```sh
git clone https://github.com/ghiscoding/angular-slickgrid-demos
cd bootstrap5-demo-with-translate # or any of the other demos
npm install
npm start
```
--------------------------------
### Regular Installation of ngx-translate
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/localization/Localization-with-ngx-translate.md
Install ngx-translate core and the recommended http-loader. This setup is for regular usage where translations are loaded from external files.
```bash
npm install @ngx-translate/core @ngx-translate/http-loader
## OR with yarn
yarn add @ngx-translate/core @ngx-translate/http-loader
```
--------------------------------
### Install Angular-Slickgrid and Bootstrap
Source: https://context7.com/ghiscoding/angular-slickgrid/llms.txt
Install the Angular-Slickgrid package and optional Bootstrap CSS for styling.
```bash
npm install angular-slickgrid bootstrap # bootstrap is optional
```
--------------------------------
### Angular Component Setup
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/events/Grid-&-DataView-Events.md
Basic setup for an Angular component using Angular-Slickgrid, including event handlers and grid manipulation methods.
```typescript
import { AngularGridInstance, Column, GridOption } from 'angular-slickgrid';
export class MyApp {
angularGrid: AngularGridInstance;
columnDefinitions: Column[];
gridOptions: GridOption;
dataset: any[];
isAutoEdit = true;
gridObj: any;
dataViewObj: any;
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.gridObj = angularGrid.slickGrid;
this.dataViewObj = angularGrid.dataView;
}
/** Change dynamically `autoEdit` grid options */
setAutoEdit(isAutoEdit) {
this.isAutoEdit = isAutoEdit;
this.gridObj.setOptions({ autoEdit: isAutoEdit }); // change the grid option dynamically
return true;
}
collapseAllGroups() {
this.dataviewObj.collapseAllGroups();
}
expandAllGroups() {
this.dataviewObj.expandAllGroups();
}
}
```
--------------------------------
### Install Angular-Slickgrid NPM Package
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/getting-started/quick-start.md
Install the Angular-Slickgrid package and optional Bootstrap dependency using npm.
```bash
npm install --save angular-slickgrid bootstrap # the last dep is optional
```
--------------------------------
### Install Dependencies with Yarn Classic
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/CONTRIBUTING.md
Install project dependencies using Yarn classic. Ensure you have Yarn classic installed.
```sh
# step 1, install with Yarn classic
yarn install
```
--------------------------------
### Install Angular-Slickgrid
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/README.md
Install the Angular-Slickgrid package using npm. This is the first step to integrate the data grid into your Angular application.
```sh
npm install angular-slickgrid
```
--------------------------------
### Run in Development Mode
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/CONTRIBUTING.md
Start the development server to test your code changes. This command also runs tests.
```sh
# step 2, run in dev and test your code change
yarn start
```
--------------------------------
### Basic Grid Component Setup
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/getting-started/quick-start.md
Define column definitions, grid options, and dataset for a basic Angular-Slickgrid component.
```typescript
import { Column, GridOption } from 'angular-slickgrid';
export class GridBasicComponent {
columnDefinitions: Column[] = [];
gridOptions: GridOption = {};
dataset: any[] = [];
constructor() {
this.prepareGrid();
}
prepareGrid() {
this.columnDefinitions = [
{ id: 'title', name: 'Title', field: 'title', sortable: true },
{ id: 'duration', name: 'Duration (days)', field: 'duration', sortable: true },
{ id: '%', name: '% Complete', field: 'percentComplete', sortable: true },
{ id: 'start', name: 'Start', field: 'start' },
{ id: 'finish', name: 'Finish', field: 'finish' },
];
this.gridOptions = {
enableAutoResize: true,
enableSorting: true
};
// fill the dataset with your data (or read it from the DB)
this.dataset = [
{ id: 0, title: 'Task 1', duration: 45, percentComplete: 5, start: '2001-01-01', finish: '2001-01-31' },
{ id: 1, title: 'Task 2', duration: 33, percentComplete: 34, start: '2001-01-11', finish: '2001-02-04' },
];
}
}
```
--------------------------------
### Angular-Slickgrid Component Setup
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/Editors.md
Basic HTML structure for an Angular-Slickgrid component, including event bindings for editor-related actions.
```html
```
--------------------------------
### Context Menu MenuUsabilityOverride Example
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Context-Menu.md
Dynamically control the availability of the entire context menu using `menuUsabilityOverride`. This example restricts the menu to the first 20 rows.
```typescript
contextMenu: {
menuUsabilityOverride: (args) => {
const dataContext = args && args.dataContext;
return (dataContext.id < 21); // say we want to display the menu only from Task 0 to 20
},
}
```
--------------------------------
### Users Demo JSON Result (with Pagination)
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/graphql/GraphQL-JSON-Result.md
Example of a JSON response for a 'users' dataset when pagination is enabled. It includes 'totalCount' and an array of 'nodes'.
```json
{
"data": {
"users": {
"totalCount": 2,
"nodes": [
{
"id": 0,
"firstName": "John",
"lastName": "Doe",
"email": "john@doe.com"
},
{
"id": 1,
"firstName": "Jane",
"lastName": "Doe",
"email": "john@doe.com"
}
]
}
}
}
```
--------------------------------
### Get Tree Data State Example
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/tree-data-grid.md
Demonstrates how to retrieve the current toggled state of the tree data. This is useful for debugging or persisting the tree's expanded/collapsed state.
```typescript
export class Example1 {
angularGrid?: AngularGridInstance;
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
}
getTreeDataState() {
// for example get current Tree Data toggled state
console.log(this.angularGrid.getCurrentToggleState());
}
}
```
--------------------------------
### Minimal ngx-translate Installation
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/localization/Localization-with-ngx-translate.md
Install the ngx-translate core package. This is the minimum required if you intend to use ngx-translate with Angular-Slickgrid.
```typescript
npm install @ngx-translate/core
```
--------------------------------
### Angular-Slickgrid Component Setup
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/filters/autocomplete-filter-kraaden-lib.md
Basic HTML structure for an Angular-Slickgrid component. Ensure the grid options and column definitions are properly bound.
```html
```
--------------------------------
### Basic Grid Setup in Angular
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/README.md
Defines column definitions, dataset, and grid options for a basic Angular-Slickgrid component. Ensure 'OnInit' lifecycle hook is used for initialization.
```typescript
import { type Column, type GridOption } from 'angular-slickgrid';
export class GridComponent implements OnInit {
columnDefinitions: Column[] = [];
gridOptions: GridOption;
dataset: any[] = [];
onInit() {
this.columnDefinitions = [
{ id: 'firstName', name: 'First Name', field: 'firstName', sortable: true },
{ id: 'lastName', name: 'Last Name', field: 'lastName', sortable: true },
{ id: 'age', name: 'Age', field: 'age', type: 'number', sortable: true }
];
this.dataset = [
{ id: 1, firstName: 'John', lastName: 'Doe', age: 20 },
{ id: 2, firstName: 'Jane', lastName: 'Smith', age: 21 }
];
this.gridOptions = { /*...*/ }; // optional grid options
}
}
```
--------------------------------
### Run E2E Tests with Cypress
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/CONTRIBUTING.md
Open the Cypress UI to run end-to-end tests. You can run all specs or select specific examples.
```sh
# step 4, to test the E2E tests with Cypress the E2E tests
yarn cypress:open # open Cypress UI then click on "Run All Specs" or choose dedicated Example to test
```
--------------------------------
### GraphQL FilterBy Example
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/graphql/GraphQL-Filtering.md
Demonstrates how to filter users by first name using the `filterBy` argument with the `StartsWith` operator.
```graphql
users (first: 20, offset: 10, filterBy: [{field: firstName, operator: StartsWith, value: 'John'}]) {
totalCount
nodes {
name
firstName
lastName
gender
}
}
```
--------------------------------
### HTML Container for Resizing
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Grid-Auto-Resize.md
Example of an HTML structure where the grid is placed inside a container that can be resized. The `resize:both; overflow:auto;` styles enable manual resizing of the container.
```html
```
--------------------------------
### Users Demo JSON Result (without Pagination)
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/graphql/GraphQL-JSON-Result.md
Example of a JSON response for a 'users' dataset when pagination is disabled. The 'users' key directly maps to an array of user objects.
```json
{
"data": {
"users": [
{
"id": 0,
"firstName": "John",
"lastName": "Doe",
"email": "john@doe.com"
},
{
"id": 1,
"firstName": "Jane",
"lastName": "Doe",
"email": "john@doe.com"
}
]
}
}
```
--------------------------------
### GraphQL Query with orderBy
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/graphql/GraphQL-Sorting.md
Example of a GraphQL query demonstrating the `orderBy` argument with multiple sorting criteria. The `orderBy` array specifies the field and direction for sorting.
```graphql
users (first: 20, offset: 10, orderBy: [{field: lastName, direction: ASC}, {field: firstName, direction: DESC}]) {
totalCount
nodes {
name
firstName
lastName
gender
}
}
```
--------------------------------
### Build Website
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/CONTRIBUTING.md
Optionally build the project's website. This command compiles the demo website.
```sh
# step 3.b, optional website build as well
yarn build:demo
```
--------------------------------
### Setup and Open Composite Editor Modal (TypeScript)
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Composite-Editor-Modal.md
Demonstrates how to set up the grid options to enable the composite editor and how to open the modal for creating a new item. Ensure `enableAddRow` is enabled for create/clone operations. The `registerExternalResources` option is used to include the composite editor instance.
```typescript
import { Column, CompositeEditorModalType } from 'angular-slickgrid';
import { SlickCompositeEditorComponent } from '@slickgrid-universal/composite-editor-component';
example class MyCompositeDemo {
compositeEditorInstance: SlickCompositeEditorComponent;
constructor() {
this.compositeEditorInstance = new SlickCompositeEditorComponent();
}
prepareGrid() {
this.columnDefinitions = [ /*...*/ ];
this.gridOptions = {
enableAddRow: true, // required for Create/Clone
enableCellNavigation: true,
autoEdit: true,
autoCommitEdit: true,
enableCompositeEditor: true,
registerExternalResources: [new ExcelExportService(), this.compositeEditorInstance],
};
}
openCompositeModal(modalType: CompositeEditorModalType = 'create') {
// you can use a switch/case when using the Composite Modal for more than 1 modal type
const modalTitle = 'Create Item';
this.compositeEditorInstance?.openDetails({
headerTitle: modalTitle,
modalType,
// insertNewId: 1234, // you can provide a custom Id (defaults to last Id+1)
// insertOptions: { position: 'bottom' }, // if you wish to add the item to the bottom (defaults to top of the grid)
onError: (error) => alert(error.message), // you should define how to deal with error coming from the modal
// you can optionally provide an async callback method when dealing with a backend server
onSave: (formValues, selection, dataContext) => {
// simulate a backend server call which returns true (successful) after 30sec
return new Promise(resolve => setTimeout(() => resolve(true), 500));
});
}
}
```
--------------------------------
### Multiple Select Editor with Async Collection Load
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/Editors.md
Load the collection for a `multipleSelect` editor asynchronously using `collectionAsync`. This example uses an Observable from an HTTP GET request to fetch the data.
```typescript
this.columnDefinitions = [
{
id: 'prerequisites', name: 'Prerequisites', field: 'prerequisites',
filterable: true,
editor: {
collectionAsync: this.http.get<{ value: string; label: string; }[]>('api/data/pre-requisites'),
model: Editors.multipleSelect,
}
}
];
```
--------------------------------
### Initialize Composite Editor Modal
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Composite-Editor-Modal.md
Set up the grid with `enableCompositeEditor` and register the `SlickCompositeEditorComponent`. Ensure columns intended for mass update have `massUpdate: true` in their editor configuration.
```typescript
import { Column, CompositeEditorModalType, FieldType, Filters, Editors } from 'angular-slickgrid';
import { SlickCompositeEditorComponent } from '@slickgrid-universal/composite-editor-component';
import { ExcelExportService } from '@slickgrid-universal/excel-export';
example class MyCompositeDemo {
compositeEditorInstance: SlickCompositeEditorComponent;
columnDefinitions: Column[];
gridOptions: any;
constructor() {
this.compositeEditorInstance = new SlickCompositeEditorComponent();
}
prepareGrid() {
this.columnDefinitions = [
{
id: 'percentComplete',
name: '% Complete',
field: 'percentComplete',
type: FieldType.number,
sortable: true,
filterable: true,
filter: { model: Filters.compoundSlider, operator: '>=' },
editor: {
model: Editors.slider,
massUpdate: true, // <-- this flag is required for Mass Update
minValue: 0, maxValue: 100,
},
},
];
this.gridOptions = {
enableCellNavigation: true,
autoEdit: true,
autoCommitEdit: true,
enableCompositeEditor: true,
registerExternalResources: [new ExcelExportService(), this.compositeEditorInstance],
};
}
openCompositeModal(modalType: CompositeEditorModalType = 'mass-update') {
// you can use a switch/case when using the Composite Modal for more than 1 modal type
const modalTitle = 'Mass Update';
this.compositeEditorInstance?.openDetails({
headerTitle: modalTitle,
modalType,
onError: (error) => alert(error.message), // you should define how to deal with error coming from the modal
// you can optionally provide an async callback method when dealing with a backend server
onSave: (formValues, selection, dataContext) => {
// simulate a backend server call which returns true (successful) after 30sec
return new Promise(resolve => setTimeout(() => resolve(true), 500));
});
}
}
```
--------------------------------
### Install ngx-translate for Angular 4-6
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/localization/Localization-with-ngx-translate.md
Install specific versions of ngx-translate core and http-loader for Angular versions 4-6. Adjust versions as needed for compatibility.
```bash
npm install @ngx-translate/core@9.1.1 # change to the version that works for you
npm install @ngx-translate/http-loader@2.0.0 # change to the version that works for you
```
--------------------------------
### Context Menu ItemUsabilityOverride Example
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Context-Menu.md
Conditionally enable or disable context menu items using `itemUsabilityOverride`. This example enables the 'n/a' option only when the task is not completed.
```typescript
contextMenu: {
optionItems: [
{
option: 0, title: 'n/a', textCssClass: 'italic',
// only enable this option when the task is Not Completed
itemUsabilityOverride: (args) => {
const dataContext = args && args.dataContext;
return !dataContext.completed;
},
},
{ option: 1, iconCssClass: 'mdi mdi-star-outline yellow', title: 'Low' },
{ option: 2, iconCssClass: 'mdi mdi-star orange', title: 'Medium' },
{ option: 3, iconCssClass: 'mdi mdi-star red', title: 'High' },
]
}
```
--------------------------------
### Build Project (Library)
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/CONTRIBUTING.md
Build the project's library (plugin). This command compiles the core Angular-Slickgrid components.
```sh
# step 3.a, build plugin (lib)
yarn build
```
--------------------------------
### Frozen Rows Starting from Bottom
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/frozen-columns-rows.md
To pin rows starting from the bottom, set `frozenBottom` to true in the grid options along with `frozenRow`. This allows rows to be fixed from the bottom edge of the grid.
```typescript
import { Component, OnInit} from '@angular/core';
export class GridBasicComponent implements OnInit {
columnDefinitions: Column[];
gridOptions: GridOption;
dataset: any[];
ngOnInit(): void {
// your columns definition
this.columnDefinitions = [];
this.gridOptions = {
alwaysShowVerticalScroll: false, // disable scroll since we don't want it to show on the left pinned columns
frozenColumn: 2, // number of pinned columns starting from the left
frozenRow: 3, // number of pinned rows (starting from bottom with next property)
frozenBottom: true, // this will make rows to be pinned starting from the bottom and the number of rows will be 3
}
}
}
```
--------------------------------
### Initialize GraphqlService with Basic Options
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/GraphQL.md
Configure the GraphqlService with essential options for backend data processing, including dataset name and pagination settings. The `process` callback is used to define the API call for fetching data.
```typescript
import { Component, Injectable, OnInit } from '@angular/core';
import { Column, GridOption } from 'angular-slickgrid';
import { GraphqlService, GraphqlPaginatedResult, GraphqlServiceApi, } from '@slickgrid-universal/graphql';
@Injectable()
export class MyComponent implements OnInit {
columnDefinitions: Column[];
gridOptions: GridOption;
constructor(private http: HttpClient) { }
ngOnInit(): void {
this.columnDefinitions = [
// your column definitions
];
this.gridOptions = {
enableFiltering: true,
enablePagination: true,
pagination: {
pageSizes: [10, 15, 20, 25, 30, 40, 50, 75, 100],
pageSize: defaultPageSize,
totalItems: 0
},
backendServiceApi: {
service: new GraphqlService(),
// add some options to the backend service to work
// shown below is the minimum setup for the service to work correctly
options: {
columnDefinitions: this.columnDefinitions,
datasetName: 'users',
paginationOptions: {
first: 25,
offset: 0
}
},
// define all the on Event callbacks
preProcess: () => this.displaySpinner(true),
process: (query) => this.getAllCustomers(query),
postProcess: (response) => this.displaySpinner(false)
}
};
}
// Web API call
getAllCustomers(graphqlQuery) {
return this.http.post('/api/customers', { query: graphqlQuery });
}
}
```
--------------------------------
### Example Custom Formatter with HTML String
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/Formatters.md
Create a custom formatter function that returns an HTML string. This example uses SVG icons to display a 'fire' icon for true values and a 'snowflake' icon for false values, based on boolean input.
```typescript
// create a custom Formatter with the Formatter type
const myCustomCheckboxFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) =>
value ? `` : '';
```
--------------------------------
### Main Grid Component Setup for Row Detail View
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/row-detail.md
Configure the main grid component to enable the row detail view. This involves setting 'enableRowDetailView' to true and pre-registering the 'SlickRowDetailView' extension. The 'rowDetailView' options specify how the detail panel should be processed and loaded.
```typescript
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { AngularGridInstance, Column, GridOption, GridState } from 'angular-slickgrid';
@Component({
styleUrls: ['main-grid.component.scss'],
templateUrl: './main-grid.component.html',
encapsulation: ViewEncapsulation.None,
})
export class MainGridComponent implements OnInit {
columnDefinitions: Column[] = [];
gridOptions!: GridOption;
angularGrid!: AngularGridInstance;
dataset: Distributor[] = [];
get rowDetailInstance(): SlickRowDetailView {
return this.angularGrid.extensions.rowDetailView?.instance || {};
}
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
}
ngOnInit(): void {
this.defineGrid();
this.dataset = this.getData();
}
defineGrid() {
this.columnDefinitions = [ /*...*/ ];
this.gridOptions = {
enableRowDetailView: true,
rowSelectionOptions: {
selectActiveRow: true
},
preRegisterExternalExtensions: (pubSubService) => {
// Row Detail View is a special case because of its requirement to create extra column definition dynamically
// so it must be pre-registered before SlickGrid is instantiated, we can do so via this option
const rowDetail = new SlickRowDetailView(pubSubService as EventPubSubService);
return [{ name: ExtensionName.rowDetailView, instance: rowDetail }];
},
rowDetailView: {
process: (item: any) => simulateServerAsyncCall(item),
loadOnce: false, // IMPORTANT, you can't use loadOnce with inner grid because only HTML template are re-rendered, not JS events
panelRows: 10,
preloadComponent: PreloadComponent,
viewComponent: InnerGridComponent,
},
};
}
}
```
--------------------------------
### Apply lowerCase event naming convention
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/migrations/migration-to-3.x.md
Example of how an event handler would change if `eventNamingStyle` is set to `lowerCase`.
```html
```
--------------------------------
### Backend Service API Initialization
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/migrations/migration-to-2.x.md
When using the `backendServiceApi`, the service should now be instantiated using `new` instead of being passed directly if it's not provided via dependency injection.
```diff
export class MyGrid {
- constructor(private graphqlService: GraphqlService, private i18n: I18N) {
+ constructor(private i18n: I18N) {
}
this.gridOptions = {
backendServiceApi: {
- service: this.graphqlService,
+ service: new GraphqlService(),
preProcess: () => this.displaySpinner(true),
process: (query) => this.getCustomerApiCall(query),
postProcess: (result: GraphqlResult) => this.displaySpinner(false)
},
params: {
i18: this.translate
}
};
}
```
--------------------------------
### Configure Angular Module for Root
Source: https://context7.com/ghiscoding/angular-slickgrid/llms.txt
Import AngularSlickgridModule.forRoot() in your AppModule for legacy NgModule setups or use importProvidersFrom for standalone applications.
```typescript
// app.module.ts (legacy NgModule style)
import { AngularSlickgridModule } from 'angular-slickgrid';
@NgModule({
imports: [AngularSlickgridModule.forRoot()], // forRoot() is REQUIRED
})
export class AppModule {}
// OR for Standalone / App Config style (Angular 14+):
// app.config.ts
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { AngularSlickgridModule } from 'angular-slickgrid';
export const appConfig: ApplicationConfig = {
providers: [
importProvidersFrom(AngularSlickgridModule.forRoot()),
],
};
```
--------------------------------
### Basic Autocomplete Editor and Filter Configuration
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/filters/autocomplete-filter-kraaden-lib.md
Configure a column to use an autocomplete editor and filter. This example shows how to set up the `editor` and `filter` properties with `Editors.autocompleter` and `Filters.autocompleter` respectively, including asynchronous data fetching with `minLength` and a placeholder.
```typescript
import { Component, OnInit} from '@angular/core';
export class GridBasicComponent implements OnInit {
columnDefinitions: Column[];
gridOptions: GridOption;
dataset: any[];
ngOnInit(): void {
// your columns definition
this.columnDefinitions = [
{
id: 'cityOfOrigin',
name: 'City of Origin',
field: 'cityOfOrigin',
filterable: true,
minWidth: 100,
editor: {
model: Editors.autocompleter,
placeholder: 'search city', // you can provide an optional placeholder to help your users
// use your own autocomplete options, instead of $.ajax, use http
// here we use $.ajax just because I'm not sure how to configure http with JSONP and CORS
editorOptions: {
minLength: 3, // minimum count of character that the user needs to type before it queries to the remote
fetch: (searchText, updateCallback) => {
// assuming your API call returns a label/value pair
yourAsyncApiCall(searchText) // typically you'll want to return no more than 10 results
.then(result => updateCallback((results.length > 0) ? results : [{ label: 'No match found.', value: '' }]))
.catch(error => console.log('Error:', error));
}
},
},
filter: {
model: Filters.autocompleter,
// placeholder: '🔍 search city', // 🔍 is a search icon, this provide an option placeholder
// use your own autocomplete options, instead of $.ajax, use http
// here we use $.ajax just because I'm not sure how to configure http with JSONP and CORS
filterOptions: {
minLength: 3, // minimum count of character that the user needs to type before it queries to the remote
fetch: (searchText, updateCallback) => {
// assuming your API call returns a label/value pair
yourAsyncApiCall(searchText) // typically you'll want to return no more than 10 results
.then(result => updateCallback((results.length > 0) ? results : [{ label: 'No match found.', value: '' }]))
.catch(error => console.log('Error:', error));
},
}
}
}
];
this.gridOptions = {
// your grid options config
}
}
}
```
--------------------------------
### Setup DataView Object
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/grouping-and-aggregators.md
Retrieve the DataView object from the Angular-Slickgrid instance after it's created. This object is essential for configuring grouping and aggregators.
```typescript
@Component({
templateUrl: './grid-grouping.component.html'
})
export class GridGroupingComponent implements OnInit, OnDestroy {
columnDefinitions: Column[];
gridOptions: GridOption;
dataviewObj: any;
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.gridObj = angularGrid.slickGrid;
this.dataViewObj = angularGrid.dataView;
}
}
```
--------------------------------
### Grouping and Aggregators
Source: https://context7.com/ghiscoding/angular-slickgrid/llms.txt
This section demonstrates how to enable grouping and use various aggregators like Sum and Avg. It also shows how to define custom formatters for group totals and how to set up grid options for grouping.
```APIDOC
## Grouping and Aggregators
Group rows and show aggregates (sum, avg, min, max). Requires `enableGrouping: true`.
```typescript
import {
Aggregators, Column, FieldType, Formatters,
GroupTotalFormatters,
SortComparers, SortDirectionNumber
} from 'angular-slickgrid';
const columnDefinitions: Column[] = [
{ id: 'title', field: 'title', name: 'Title' },
{ id: 'duration', field: 'duration', name: 'Duration', type: FieldType.number,
groupTotalsFormatter: GroupTotalFormatters.sumTotals,
params: { groupFormatterPrefix: 'Total: ' }
},
{ id: 'cost', field: 'cost', name: 'Cost',
formatter: Formatters.dollar,
groupTotalsFormatter: GroupTotalFormatters.sumTotalsDollar,
params: { groupFormatterPrefix: 'Total: ', groupFormatterSuffix: ' USD' }
},
];
const gridOptions = {
enableGrouping: true,
// Put the draggable grouping dropzone in the top-header panel (v8.1+)
createTopHeaderPanel: true,
showTopHeaderPanel: true,
topHeaderPanelHeight: 35,
};
// After angularGridReady, keep a reference to dataView:
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
}
groupByDuration() {
this.dataViewObj.setGrouping({
getter: 'duration',
formatter: (g) => `Duration: ${g.value} (${g.count} items)`,
comparer: (a, b) => SortComparers.numeric(a.value, b.value, SortDirectionNumber.asc),
aggregators: [
new Aggregators.Avg('percentComplete'),
new Aggregators.Sum('cost'),
],
aggregateCollapsed: false,
lazyTotalsCalculation: true,
});
}
clearGrouping() { this.dataViewObj.setGrouping([]); }
collapseAllGroups() { this.dataViewObj.collapseAllGroups(); }
expandAllGroups() { this.dataViewObj.expandAllGroups(); }
```
```
--------------------------------
### App Module Configuration for ngx-translate
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/localization/Localization-with-ngx-translate.md
Configure your AppModule to include TranslateModule for localization. This setup is necessary even if using only one locale.
```typescript
import { NgModule } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
import { AngularSlickgridModule } from 'angular-slickgrid';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
TranslateModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
--------------------------------
### Initialize Grid with Sanitizer and Trusted Types
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/developer-guides/csp-compliance.md
Initialize the Slicker Grid Bundle with the sanitizer configured to return trusted types. This ensures that HTML content is safely processed.
```typescript
import DOMPurify from 'dompurify';
import { Slicker, SlickVanillaGridBundle } from '@slickgrid-universal/vanilla-bundle';
// DOM Purify is already configured in Slickgrid-Universal with the configuration shown below
this.gridOptions = {
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
// you could also optionally use the sanitizerOptions instead
// sanitizerOptions: { RETURN_TRUSTED_TYPE: true }
}
this.sgb = new Slicker.GridBundle(gridContainerElm, this.columnDefinitions, this.gridOptions, this.dataset);
```
--------------------------------
### Implement Custom Title Validator
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/Editors.md
Example of a custom validator function for a 'title' field. It checks for required input and a specific format.
```typescript
const myCustomTitleValidator: EditorValidator = (value: any, args: EditorArgs) => {
// you can get the Editor Args which can be helpful, e.g. we can get the Translate Service from it
const grid = args && args.grid;
const columnDef = args.column;
const dataContext = args.item;
const gridOptions = (grid && grid.getOptions) ? grid.getOptions() : {};
const i18n = gridOptions.i18n;
if (value == null || value === undefined || !value.length) {
return { valid: false, msg: 'This is a required field' };
} else if (!/^Task\s\d+$/.test(value)) {
return { valid: false, msg: 'Your title is invalid, it must start with "Task" followed by a number' };
// OR use the Translate Service with your custom message
// return { valid: false, msg: i18n.tr('YOUR_ERROR', { x: value }) };
} else {
return { valid: true, msg: '' };
}
};
```
--------------------------------
### Define Cell Menu Options
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/Cell-Menu.md
Configure a cell menu with a list of options for the user to select. This example shows how to define options with titles, values, and icons, and includes a divider. The `action` callback is used to perform an action when an option is selected.
```typescript
this.columnDefinitions = [
{ id: 'firstName', field: 'firstName', name: 'First Name' },
{ id: 'lastName', field: 'lastName', name: 'Last Name' },
// ... more column defs
{
id: 'action', name: 'Action', field: 'action', width: 110, maxWidth: 200,
excludeFromExport: true, // you typically don't want this column exported
formatter: actionFormatter, // your Custom Formatter
cellMenu: {
optionTitle: 'Change Effort Driven Flag', // optional, add title
optionItems: [
{ option: true, title: 'True', iconCssClass: 'mdi mdi-check-box-outline' },
{ option: false, title: 'False', iconCssClass: 'mdi mdi-checkbox-blank-outline' },
{ divider: true, command: '', positionOrder: 60 },
],
// subscribe to Context Menu onOptionSelected event (or use the "action" callback on each option)
action: (e, args) => {
console.log(args.dataContext, args.column); // action callback.. do something
}
}
}
];
```
--------------------------------
### Basic GraphQL Query Structure
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/graphql/GraphQL-Filtering.md
Example of a GraphQL query with pagination and nested data fetching. Use dot notation for nested fields.
```typescript
{
users(first: 20, offset: 0, userId: 123) {
totalCount,
nodes {
name,
company,
billing {
address {
street,
zip
}
}
}
}
}
```
--------------------------------
### Enable Custom Footer with Options
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Custom-Footer.md
Enable the custom footer and configure its appearance with options like custom left text and hiding metrics. This setup is useful for displaying grid creation information and metrics.
```typescript
defineGrid() {
this.columnDefinitions = [ /*...*/ ];
this.gridOptions = {
// ...
showCustomFooter: true, // display some metrics in the bottom custom footer
customFooterOptions: {
// optionally display some text on the left footer container
leftFooterText: 'Grid created with Slickgrid-Universal',
hideMetrics: false,
hideTotalItemCount: false,
hideLastUpdateTimestamp: false
},
};
}
```
--------------------------------
### Instantiate Custom Backend Service in Grid Options
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/Custom-Backend-Service.md
Integrate your custom backend service by instantiating it directly within the grid options. This approach is suitable when the service is specific to the component's usage.
```typescript
class MyComponent {
gridInit() {
this.gridOptions = {
backendServiceApi: {
service: new YourCustomBackendService(),
options: {
// custom service options that extends "backendServiceOption" interface
},
preProcess: () => !this.isDataLoaded ? this.displaySpinner(true) : '',
process: (query) => this.getCountries(query),
postProcess: (result) => {
this.displaySpinner(false);
this.isDataLoaded = true;
}
} as YourCustomBackendServiceApi
};
}
}
```
--------------------------------
### Instantiate Custom Backend Service Separately
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/Custom-Backend-Service.md
Instantiate your custom backend service in a separate variable and then pass it to the grid options. This is recommended for reusability and cleaner code structure.
```typescript
class MyComponent {
myCustomService = new YourCustomBackendService();
gridInit {
this.gridOptions = {
backendServiceApi: {
service: this.myCustomService,
// ...
} as YourCustomBackendServiceApi
};
}
}
```
--------------------------------
### Get Last Resize Dimensions
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Grid-Auto-Resize.md
The `resizeGrid()` method returns a promise that resolves with the last used dimensions, which can be used to synchronize the size of other elements.
```typescript
async openSidebar() {
this.isSidebarOpen = true;
// resize the CPA list grid and resize the sidebar to the same height as the grid with it's pagination
const lastDimensions = await this.sgb.resizerService.resizeGrid();
if (lastDimensions && lastDimensions.heightWithPagination) {
this.sidebarMaxHeight = `${lastDimensions.heightWithPagination}px`;
}
}
```
--------------------------------
### CSP Meta Tag Configuration
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/developer-guides/csp-compliance.md
Example of a Content Security Policy meta tag that includes trusted types and specifies DOMPurify for enhanced security.
```html
```
--------------------------------
### Basic Inline Editor Setup
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/column-functionalities/Editors.md
Configure column definitions to use various inline editors like text, integer, date, and checkbox. Ensure `enableCellNavigation: true` and `editable: true` are set in Grid Options for editors to function.
```typescript
this.columnDefinitions = [
{ id: 'title', name: 'Title', field: 'title', type: FieldType.string, editor: { model: Editors.longText } },
{ id: 'duration', name: 'Duration (days)', field: 'duration', type: FieldType.number, editor: { model: Editors.text } },
{ id: 'complete', name: '% Complete', field: 'percentComplete', type: FieldType.number, editor: { model: Editors.integer } },
{ id: 'start', name: 'Start', field: 'start', type: FieldType.date, editor: { model: Editors.date } },
{
id: 'finish', name: 'Finish', field: 'finish', type: FieldType.date,
editor: {
model: Editors.date,
// you can also add an optional placeholder
placeholder: 'choose a date'
}
},
{
id: 'effort-driven', name: 'Effort Driven', field: 'effortDriven',
formatter: Formatters.checkmarkMaterial,
type: FieldType.number, editor: { model: Editors.checkbox }
}
];
this.gridOptions {
enableCellNavigation: true, // <<-- VERY IMPORTANT, it won't work without this flag enabled
editable: true,
};
```
--------------------------------
### Toggle Dark Mode with setOptions
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/styling/dark-mode.md
Demonstrates how to toggle dark mode using the `setOptions` method on the SlickGrid instance. This is useful for dynamic theme changes.
```typescript
export class MyDemo {
isDarkModeEnabled = false;
gridOptions: GridOption;
prepareGrid() {
this.gridOptions = {
// ...
darkMode: this.isDarkModeEnabled;
}
}
toggleDarkMode() {
this.isDarkModeEnabled = !this.isDarkModeEnabled;
this.sgb.slickGrid?.setOptions({ darkMode: this.isDarkModeEnabled });
// optionally update your local grid options as well
this.gridOptions = { ...this.gridOptions, darkMode: this.isDarkModeEnabled };
}
}
```
--------------------------------
### Example GraphQL Query with Extra Arguments
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/backend-services/GraphQL.md
Illustrates how the `extraQueryArguments` are incorporated into the final GraphQL query string. The `userId` argument is appended to the query parameters.
```graphql
// extraQueryArguments will change the userId with
{
users(first: 20, offset: 0, userId: 567) {
totalCount,
nodes {
id,
name,
company
}
}
}
```
--------------------------------
### Update Formatter Using DocumentFragment
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/migrations/migration-to-7.x.md
This example demonstrates how to adapt a formatter that uses `Formatters.multiple` when dealing with native HTML elements or DocumentFragments. It shows creating a DocumentFragment and appending elements to it, ensuring compatibility with the new formatter output.
```typescript
const priceFormatter: Formatter = (_cell, _row, value, _col, dataContext) => {
const direction = dataContext.priceChange >= 0 ? 'up' : 'down';
- return ` ${value}`;
+ const fragment = document.createDocumentFragment();
+ const spanElm = document.createElement('span');
+ spanElm.className = `mdi mdi-arrow-${direction} color-${direction === 'up' ? 'success' : 'danger'}`;
+ fragment.appendChild(spanElm);
+ if (value instanceof HTMLElement) {
+ fragment.appendChild(value);
+ }
+ return fragment;
};
init() {
this.columnDefinitions = [
{
id: 'priceChange', name: 'Change', field: 'priceChange', filterable: true, sortable: true, minWidth: 80, width: 80,
filter: { model: Filters.compoundInputNumber }, type: FieldType.number,
formatter: Formatters.multiple,
params: {
formatters: [Formatters.dollarColored, priceFormatter],
maxDecimal: 2,
}
},
],
}
```
--------------------------------
### Show Loading Spinner During Export
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Export-to-Excel.md
Display a loading spinner while the Excel export process is running. Use `onBeforeExportToExcel` to start the spinner and `onAfterExportToExcel` to stop it.
```html
```
```typescript
export class MyComponent() implements OnInit {
processing = false;
}
```
--------------------------------
### Handling Angular Grid Creation Event
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/migrations/migration-to-2.x.md
Use the `onAngularGridCreated` event to get the `AngularGridInstance` when the grid is ready. This instance provides access to grid services.
```diff
```
```typescript
export class MyGridDemo implements OnInit {
+ angularGrid: AngularGridInstance;
columnDefinitions: Column[];
gridOptions: GridOption;
dataset: any[];
- constructor(private GridExtraService) {}
+ angularGridReady(angularGrid: AngularGridInstance) {
+ this.angularGrid = angularGrid;
+ // Slick Grid & DataView objects
+ this.gridObj = angularGrid.slickGrid;
+ this.dataViewObj = angularGrid.dataView;
+ }
addNewItem() {
const newItem = {
id: newId,
title: 'Task ' + newId,
effortDriven: true,
// ...
};
- this.gridExtraService.addItemToDatagrid(newItem);
+ this.angularGrid.gridService.addItemToDatagrid(newItem);
}
```
--------------------------------
### Override Checkbox SVG Icon Path with SASS
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/styling/styling.md
A SASS-specific example for overriding just the SVG path for a checkbox icon, demonstrating a simpler approach compared to CSS.
```scss
$slick-checkbox-icon-checked-svg-path: "M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"
```
--------------------------------
### Context Menu with Action Callback
Source: https://github.com/ghiscoding/angular-slickgrid/blob/master/docs/grid-functionalities/Context-Menu.md
Use the `action` callback to define specific logic for each command item in the context menu. This is suitable when each command has a unique, simple action.
```typescript
contextMenu: {
commandItems: [
{ command: 'command1', title: 'Command 1', action: (e, args) => console.log(args) }
{ command: 'command2', title: 'Command 2', action: (e, args) => console.log(args) }
// ...
]
}
```