Skip to content

Commit

Permalink
fix: Filter model is now FilterConstructor and shouldn't be newed
Browse files Browse the repository at this point in the history
- the Filter `model` prop should be a constructor and it shouldn't newed (instantiated), it was defined like so in the docs and Wikis but that was actually wrong
- ref Slickgrid-Universal [PR 1430](ghiscoding/slickgrid-universal#1430)
  • Loading branch information
ghiscoding committed Mar 13, 2024
1 parent b5d6191 commit 6831c53
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 22 deletions.
24 changes: 12 additions & 12 deletions docs/column-functionalities/filters/custom-filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ You can also create your own Custom Filter with any html/css you want and/or jQu
#### Limitations
- as mentioned in the description, only html/css and/or jQuery libraries are supported.
- this mainly mean that Angular templates (components) are not supported (feel free to contribute).
- SlickGrid uses `table-cell` as CSS for it to display a consistent height for each rows (this keeps the same row height/line-height to always be the same).
- SlickGrid uses `table-cell` as CSS for it to display a consistent height for each rows (this keeps the same row height/line-height to always be the same).
- all this to say that you might be in a situation were your filter shows in the back of the grid. The best approach to overcome this is to use a modal if you can or if the library support `append to body container`. For example, you can see that `multiple-select-vanilla` supports a `container`

### How to use Custom Filter?
1. You first need to create a `class` using the [Filter interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/filter.interface.ts). Make sure to create all necessary public properties and functions.
1. You first need to create a `class` using the [Filter interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/filter.interface.ts). Make sure to create all necessary public properties and functions.
- You can see a demo with a [custom-inputFilter.ts](https://github.com/ghiscoding/angular-slickgrid/blob/master/src/app/examples/custom-inputFilter.ts) that is used in the [demo - example 4](https://ghiscoding.github.io/Angular-Slickgrid/#/clientside)
2. Simply set the `columnDefinition.filter.model` to your new custom Filter class and instantiate it with `new` (you can also use dependency injection in the constructor if you wish). Here is an example with a custom input filter:
```typescript
2. Simply set the `columnDefinition.filter.model` to your new custom Filter class and instantiate it with `new` (you can also use dependency injection in the constructor if you wish). Here is an example with a custom input filter:
```typescript
// define you columns, in this demo Effort Driven will use a Select Filter
this.columnDefinitions = [
this.columnDefinitions = [
{ id: 'title', name: 'Title', field: 'title' },
{ id: 'description', name: 'Description', field: 'description', type: FieldType.string,
filterable: true,
filterable: true,
filter: {
model: new CustomInputFilter() // create a new instance to make each Filter independent from each other
model: CustomInputFilter // create a new instance to make each Filter independent from each other
}
}
];
Expand All @@ -47,7 +47,7 @@ If you want to load the grid with certain default filter(s), you can use the fol

For example, setting a default value into an `input` element, you can simply get the search term with `columnDef.filter.searchTerms` and set the default value in jquery with `$(filterElm).val(this.searchTerms);`

### Collection
### Collection
If you want to pass a `collection` to your filter (for example, a multiple-select needs a select list of options), you can then use it in your custom filter through `columnDef.filter.collection`

#### `key/label` pair
Expand All @@ -61,7 +61,7 @@ this.columnDef.filter.collection.forEach((option: SelectOption) => {
```

#### Custom Structure (key/label pair)
What if your `collection` have totally different value/label pair? In this case, you can use the `customStructure` to change the property name(s) to use. You can change the label and/or the value, they can be passed independently.
What if your `collection` have totally different value/label pair? In this case, you can use the `customStructure` to change the property name(s) to use. You can change the label and/or the value, they can be passed independently.
For example:
```typescript
// use custom structure value/label pair
Expand All @@ -80,7 +80,7 @@ this.columnDef.filter.collection.forEach((option: SelectOption) => {
By default a `collection` uses the `label/value` pair without translation or `labelKey/value` pair with translation usage. So if you want to use translations, then you can loop through your `collection` and use the `labelKey/value` properties. For example:
```typescript
this.columnDef.filter.collection.forEach((option: SelectOption) => {
// translate label
// translate label
const textLabel = (option.labelKey && typeof this.i18n.tr === 'function') ? this.i18n.tr(option.labelKey || ' ') : option.labelKey;

// use the option value & translated label
Expand All @@ -98,7 +98,7 @@ const labelName = (this.columnDef.filter.customStructure) ? this.columnDef.filte
const valueName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.value : 'value';

this.columnDef.filter.collection.forEach((option: SelectOption) => {
// translate label
// translate label
const textLabel = (option.labelKey && typeof this.i18n.tr === 'function') ? this.i18n.tr(option[labelName] || ' ') : option[labelName];

// use the option value & translated label
Expand All @@ -109,7 +109,7 @@ this.columnDef.filter.collection.forEach((option: SelectOption) => {
## Custom Filter with Angular Components
You can see them in [Example 22](https://ghiscoding.github.io/Angular-Slickgrid/#/angular-components) which have both Custom Editors & Filters which uses Angular Components. The 2nd column "Assignee" is the column that uses both (it uses `ng-select` 3rd party lib wrapped in an Angular Components [here](https://github.com/ghiscoding/angular-slickgrid/blob/master/src/app/examples/filter-ng-select.component.ts)) and you need to create a Custom Filter like [here](https://github.com/ghiscoding/angular-slickgrid/blob/master/src/app/examples/custom-angularComponentFilter.ts) and use that Custom Filter in your column definition like [here](https://github.com/ghiscoding/angular-slickgrid/blob/master/src/app/examples/grid-angular.component.ts#L109).

Personally I don't find this very straightforward and I don't recommend using Angular Components for Editors/Filters as it adds a lot of boilerplate (compare to 1 step with a jQuery Custom Filter) but if you really wish to go that route, it's now possible following the steps shown below.
Personally I don't find this very straightforward and I don't recommend using Angular Components for Editors/Filters as it adds a lot of boilerplate (compare to 1 step with a jQuery Custom Filter) but if you really wish to go that route, it's now possible following the steps shown below.

The steps to use an Angular Component as a Custom Filter are the following:
1. Create a Custom Filter that will handle the creation or compilation of the Angular Component into a SlickGrid Editors. For that you can take a look at this [Custom Filter](https://github.com/ghiscoding/angular-slickgrid/blob/master/src/app/examples/custom-angularComponentFilter.ts)
Expand Down
4 changes: 2 additions & 2 deletions docs/migrations/Migration-to-2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ this.columnDefinitions = [
id: 'description', name: 'Description', field: 'description',
filter: {
- type: FilterType.custom,
- customFilter: new CustomInputFilter()
+ model: new CustomInputFilter() // create a new instance to make each Filter independent from each other
- customFilter: CustomInputFilter
+ model: CustomInputFilter // create a new instance to make each Filter independent from each other
}
},
{
Expand Down
4 changes: 2 additions & 2 deletions src/app/examples/custom-angularComponentEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ export class CustomAngularComponentEditor implements Editor {
init() {
if (!this.columnEditor || !this.columnEditor.params.component || !(this.angularUtilService instanceof AngularUtilService)) {
throw new Error(`[Angular-Slickgrid] For Editor with Angular Component to work properly, you need to provide the "AngularUtilService" via the Editor "params" OR the Grid Options "params"
Example: this.columnDefs = [{ id: 'title', field: 'title', editor: { model: CustomAngularComponentEditor, collection: [...], params: { component: MyComponent, angularUtilService: this.angularUtilService }}];
OR this.columnDefs = [{ id: 'title', field: 'title', editor: { model: CustomAngularComponentEditor, collection: [...] }]; this.gridOptions = { params: { angularUtilService: this.angularUtilService }}`);
Example: this.columnDefs = [{ id: 'title', field: 'title', editor: { model: CustomEditor, collection: [...], params: { component: MyComponent, angularUtilService: this.angularUtilService }}];
OR this.columnDefs = [{ id: 'title', field: 'title', editor: { model: CustomEditor, collection: [...] }]; this.gridOptions = { params: { angularUtilService: this.angularUtilService }}`);
}
if (this.columnEditor?.params.component) {
const componentOutput = this.angularUtilService.createAngularComponentAppendToDom(this.columnEditor.params.component, this.args.container);
Expand Down
4 changes: 2 additions & 2 deletions src/app/examples/custom-angularComponentFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export class CustomAngularComponentFilter implements Filter {

if (!this.columnFilter || !this.columnFilter.params.component || !(this.angularUtilService instanceof AngularUtilService)) {
throw new Error(`[Angular-Slickgrid] For Filter with Angular Component to work properly, you need to provide the "AngularUtilService" via the Filter "params" OR the Grid Options "params"
Example: this.columnDefs = [{ id: 'title', field: 'title', filter: { model: CustomAngularComponentFilter, collection: [...], params: { component: MyComponent, angularUtilService: this.angularUtilService }}];
OR this.columnDefs = [{ id: 'title', field: 'title', filter: { model: CustomAngularComponentFilter, collection: [...] }]; this.gridOptions = { params: { angularUtilService: this.angularUtilService }}`);
Example: this.columnDefs = [{ id: 'title', field: 'title', filter: { model: CustomFilter, collection: [...], params: { component: MyComponent, angularUtilService: this.angularUtilService }}];
OR this.columnDefs = [{ id: 'title', field: 'title', filter: { model: CustomFilter, collection: [...] }]; this.gridOptions = { params: { angularUtilService: this.angularUtilService }}`);
}

if (this.columnFilter?.params.component) {
Expand Down
4 changes: 2 additions & 2 deletions src/app/examples/grid-angular.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export class GridAngularComponent implements OnInit {
filterable: true,
sortable: true,
filter: {
model: new CustomAngularComponentFilter(), // create a new instance to make each Filter independent from each other
model: CustomAngularComponentFilter, // create a new instance to make each Filter independent from each other
collection: this.assignees,
params: {
component: FilterNgSelectComponent,
Expand Down Expand Up @@ -155,7 +155,7 @@ export class GridAngularComponent implements OnInit {
filterable: true,
sortable: true,
filter: {
model: new CustomAngularComponentFilter(), // create a new instance to make each Filter independent from each other
model: CustomAngularComponentFilter, // create a new instance to make each Filter independent from each other
collection: this.assignees,
params: {
component: FilterNgSelectComponent,
Expand Down
2 changes: 1 addition & 1 deletion src/app/examples/grid-clientside.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class GridClientSideComponent implements OnInit {
id: 'description', name: 'Description', field: 'description', filterable: true, sortable: true, minWidth: 80,
type: FieldType.string,
filter: {
model: new CustomInputFilter(), // create a new instance to make each Filter independent from each other
model: CustomInputFilter, // create a new instance to make each Filter independent from each other
enableTrimWhiteSpace: true // or use global "enableFilterTrimWhiteSpace" to trim on all Filters
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/app/examples/grid-range.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export class GridRangeComponent implements OnInit, OnDestroy {
id: 'description', name: 'Description', field: 'description', filterable: true, sortable: true, minWidth: 80,
type: FieldType.string,
filter: {
model: new CustomInputFilter(), // create a new instance to make each Filter independent from each other
model: CustomInputFilter, // create a new instance to make each Filter independent from each other
enableTrimWhiteSpace: true // or use global "enableFilterTrimWhiteSpace" to trim on all Filters
}
},
Expand Down

0 comments on commit 6831c53

Please sign in to comment.