Skip to content

Commit

Permalink
feat: add global defaultEditorOptions & defaultFilterOptions (#326)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding authored Apr 20, 2024
1 parent 71e111d commit 317e4e0
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 186 deletions.
31 changes: 30 additions & 1 deletion docs/column-functionalities/editors.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [Collection Label Prefix/Suffix](#collection-label-prefixsuffix)
- [Collection Label Render HTML](#collection-label-render-html)
- [`multiple-select.js` Options](#multiple-selectjs-options)
- [Editor Options](#editor-options)
- [Validators](#validators)
- [Custom Validator](#custom-validator)
- [Disabling specific cell Edit](#disabling-specific-cell-edit)
Expand All @@ -27,7 +28,7 @@
Editors won't work without these 2 flags `enableCellNavigation: true` and `editable: true` enabled in your Grid Options, so make sure to always to always defined them. Also note that you can toggle the grid to read only (not editable) via the `editable` grid option flag.

### Demo
##### with plain javascript/jQuery
##### with plain javascript
[Demo Page](https://ghiscoding.github.io/slickgrid-react/#/slickgrid/Example3) / [Demo ViewModel](https://github.com/ghiscoding/slickgrid-react/blob/master/src/examples/slickgrid/Example3.tsx)

##### with React Custom Components
Expand Down Expand Up @@ -370,6 +371,34 @@ const columnDefinitions = [
### Change Default DOMPurify Options (sanitize html)
If you find that the HTML that you passed is being sanitized and you wish to change it, then you can change the default `sanitizeHtmlOptions` property defined in the Global Grid Options, for more info on how to change these global options, see the [Docs - Global Grid Options](../grid-functionalities/global-options.md) and also take a look at the [GitHub - DOMPurify](https://github.com/cure53/DOMPurify#can-i-configure-it) configurations.
## Editor Options
#### Column Editor `editorOptions`
Some of the Editors could receive extra options, which is mostly the case for Editors using external dependencies (e.g. `autocompleter`, `date`, `multipleSelect`, ...) you can provide options via the `editorOptions`, for example
```ts
this.columnDefinitions = [{
id: 'start', name: 'Start Date', field: 'start',
editor: {
model: Editors.date,
editorOptions: { minDate: 'today' }
}
}];
```
#### Grid Option `defaultEditorOptions
You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultEditorOptions` Grid Option. Note that they are set via the editor type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `editorOptions` (also note that each key is already typed with the correct editor option interface), for example

```ts
this.gridOptions = {
defaultEditorOptions: {
autocompleter: { debounceWaitMs: 150 }, // typed as AutocompleterOption
date: { minDate: 'today' },
longText: { cols: 50, rows: 5 }
}
}
```

## Validators
Each Editor needs to implement the `validate()` method which will be executed and validated before calling the `save()` method. Most Editor will simply validate that the value passed is correctly formed. The Float Editor is one of the more complex one and will first check if the number is a valid float then also check if `minValue` or `maxValue` was passed and if so validate against them. If any errors is found it will return an object of type `EditorValidatorOutput` (see the signature on top).

Expand Down
46 changes: 20 additions & 26 deletions docs/column-functionalities/editors/autocomplete-editor-kraaden.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ this.columnDefinitions = [
// example with a fixed Collection (or collectionAsync)
editorOptions: {
showOnFocus: true, // display the list on focus of the autocomplete (without the need to type anything)
},
} as AutocompleterOption,
enableRenderHtml: true, // this flag only works with a fixed Collection
// collectionAsync: this.http.get(URL_COUNTRIES_COLLECTION),
collection: [
Expand All @@ -114,6 +114,17 @@ editor: {
}
```

#### Grid Option `defaultEditorOptions
You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultEditorOptions` Grid Option. Note that they are set via the editor type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `editorOptions` (also note that each key is already typed with the correct editor option interface), for example

```ts
this.gridOptions = {
defaultEditorOptions: {
autocompleter: { debounceWaitMs: 150 }, // typed as AutocompleterOption
}
}
```

## Using External Remote API
You could also use external 3rd party Web API (can be JSONP query or regular JSON). This will make a much shorter result since it will only return a small subset of what will be displayed in the AutoComplete Editor or Filter. For example, we could use GeoBytes which provide a JSONP Query API for the cities of the world, you can imagine the entire list of cities would be way too big to download locally, so this is why we use such API.

Expand Down Expand Up @@ -302,7 +313,6 @@ export class GridBasicComponent extends React.Component<Props, State> {
},
} as AutocompleteOption,
callbacks: {
// callback on the jQuery UI AutoComplete on the instance, example from https://jqueryui.com/autocomplete/#custom-data
_renderItem: (ul: HTMLElement, item: any) => {
const template = `<div class="autocomplete-container-list">
<div class="autocomplete-left">
Expand Down Expand Up @@ -348,42 +358,26 @@ export class GridBasicComponent extends React.Component<Props, State> {
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) => {
$.ajax({
url: 'http://gd.geobytes.com/AutoCompleteCity',
dataType: 'jsonp',
data: {
q: searchText // geobytes requires a query with "q" queryParam representing the chars typed (e.g.: gd.geobytes.com/AutoCompleteCity?q=van
},
success: (data) => updateCallback(data)
});
// 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: '&#128269; search city', // &#128269; 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) => {
$.ajax({
url: 'http://gd.geobytes.com/AutoCompleteCity',
dataType: 'jsonp',
data: {
q: searchText
},
success: (data) => {
updateCallback(data);
}
});
// 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));
}
},
}
Expand Down
21 changes: 15 additions & 6 deletions docs/column-functionalities/editors/date-editor-flatpickr.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
- See the [Editors - Wiki](../Editors.md) for more general info about Editors (validators, event handlers, ...)

### Information
The Date Editor is provided through an external library named [Flatpickr](https://flatpickr.js.org/examples/) and all options from that library can be added to your `editorOptions` (see below [Editor Options]()), so in order to add things like minimum date, disabling dates, ... just review all the [Flatpickr Examples](https://flatpickr.js.org/examples/) and then add them into `editorOptions`. Also just so you know, `editorOptions` is use by all other editors as well to expose external library like Flatpickr, Multiple-Select.js, etc...
The Date Editor is provided through an external library named [Flatpickr](https://flatpickr.js.org/examples/) and all options from that library can be added to your `editorOptions` (see below), so in order to add things like minimum date, disabling dates, ... just review all the [Flatpickr Examples](https://flatpickr.js.org/examples/) and then add them into `editorOptions`. Also just so you know, `editorOptions` is use by all other editors as well to expose external library like Flatpickr, Multiple-Select.js, etc...

### Demo
[Demo Page](https://ghiscoding.github.io/slickgrid-react/#/slickgrid/Example3) | [Demo Component](https://github.com/ghiscoding/slickgrid-react/blob/master/src/examples/slickgrid/Example3.tsx)
Expand All @@ -22,11 +22,9 @@ defineGrid() {
editor: {
model: Editors.date,
editorOptions: {
editorOptions: {
minDate: 'today',
disable: [(date: Date) => this.isWeekendDay(date)], // disable weekend days (Sat, Sunday)
} as FlatpickrOption,
},
minDate: 'today',
disable: [(date: Date) => this.isWeekendDay(date)], // disable weekend days (Sat, Sunday)
} as FlatpickrOption,
},
}
];
Expand All @@ -38,6 +36,17 @@ isWeekendDay(date: Date): boolean {
}
```

#### Grid Option `defaultEditorOptions
You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultEditorOptions` Grid Option. Note that they are set via the editor type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `editorOptions` (also note that each key is already typed with the correct editor option interface), for example

```ts
this.gridOptions = {
defaultEditorOptions: {
date: { minDate: 'today' }, // typed as FlatpickrOption
}
}
```

### Custom Validator
You can add a Custom Validator from an external function or inline (inline is shown below and comes from [Example 3](https://ghiscoding.github.io/slickgrid-react/#/slickgrid/Example3))

Expand Down
11 changes: 11 additions & 0 deletions docs/column-functionalities/editors/longtext-editor-textarea.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ defineGrid() {
}
```

#### Grid Option `defaultEditorOptions
You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultEditorOptions` Grid Option. Note that they are set via the editor type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `editorOptions` (also note that each key is already typed with the correct editor option interface), for example

```ts
this.gridOptions = {
defaultEditorOptions: {
longText: { cols: 50, rows: 5 }, // typed as LongTextEditorOption
}
}
```

### Custom Validator
You can add a Custom Validator, from an external function or inline.
```ts
Expand Down
13 changes: 13 additions & 0 deletions docs/column-functionalities/editors/select-dropdown-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ editor: {
} as MultipleSelectOption
}
```

#### Grid Option `defaultEditorOptions
You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultEditorOptions` Grid Option. Note that they are set via the editor type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `editorOptions` (also note that each key is already typed with the correct editor option interface), for example

```ts
this.gridOptions = {
defaultEditorOptions: {
// Note: that `select` combines both multipleSelect & singleSelect
select: { minHeight: 350 }, // typed as MultipleSelectOption
}
}
```

### Complex Object
If your `field` string has a dot (.) it will automatically assume that it is dealing with a complex object. There are however some options you can use with a complex object, the following options from the `ColumnEditor` might be useful to you
```ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class GridBasicComponent extends React.Component<Props, State> {
```

### Filter Options (`AutocompleterOption` interface)
All the available options that can be provided as `filterOptions` to your column definitions can be found under this [AutocompleterOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/autocompleterOption.interface.ts) and you should cast your `filterOptions` to that interface to make sure that you use only valid options of the jQueryUI autocomplete library.
All the available options that can be provided as `filterOptions` to your column definitions can be found under this [AutocompleterOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/autocompleterOption.interface.ts) and you should cast your `filterOptions` to that interface to make sure that you use only valid options of the autocomplete library.

```ts
filter: {
Expand All @@ -81,9 +81,6 @@ filter: {
## Using External Remote API
You could also use external 3rd party Web API (can be JSONP query or regular JSON). This will make a much shorter result since it will only return a small subset of what will be displayed in the AutoComplete Editor or Filter. For example, we could use GeoBytes which provide a JSONP Query API for the cities of the world, you can imagine the entire list of cities would be way too big to download locally, so this is why we use such API.

#### Note
I don't have time to invest in finding how to use JSONP + CORS in React, if someone wants to submit a PR (Pull Request) with the proper React code, I would be happy to merge the code and update the Wiki. For now, I'll simply make a quick and easy example with the jQuery `$.ajax` call just for you to get the idea of how it works.

##### Component
```tsx
export class GridBasicComponent extends React.Component<Props, State> {
Expand Down
14 changes: 14 additions & 0 deletions docs/column-functionalities/filters/compound-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,20 @@ In order to use different locale, you will have to import whichever Flatpickr lo
setTimeout(() => import('flatpickr/dist/l10n/fr'));
```

#### Grid Option `defaultFilterOptions
You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultFilterOptions` Grid Option. Note that they are set via the filter type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `filterOptions` (also note that each key is already typed with the correct filter option interface), for example

```ts
this.gridOptions = {
defaultFilterOptions: {
// Note: that `date`, `select` and `slider` are combining both compound & range filters together
date: { minDate: 'today' },
select: { minHeight: 350 }, // typed as MultipleSelectOption
slider: { sliderStartValue: 10 }
}
}
```

### Compound Operator List (custom list)
Each Compound Filter will try to define the best possible Operator List depending on what Field Type you may have (for example we can have StartsWith Operator on a string but not on a number). If you want to provide your own custom Operator List to a Compound Filter, you can do that via the `compoundOperatorList` property (also note that your Operator must be a valid OperatorType/OperatorString).

Expand Down
6 changes: 3 additions & 3 deletions docs/column-functionalities/filters/custom-filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
[Demo Page](https://ghiscoding.github.io/slickgrid-react/#/slickgrid/Example4) / [Demo Client Component](https://github.com/ghiscoding/slickgrid-react/blob/master/src/examples/slickgrid/Example4.tsx) / [Custom InputFilter.ts](https://github.com/ghiscoding/slickgrid-react/blob/master/src/examples/slickgrid/custom-inputFilter.ts)

### Description
You can also create your own Custom Filter with any html/css you want and/or jQuery library you wish to use. React template (View) are not supported at this point, if you wish to contribute on that end then I certainly accept PR (Pull Request).
You can also create your own Custom Filter with any html/css you want to use. React template (View) are not supported at this point, if you wish to contribute on that end then I certainly accept PR (Pull Request).

#### Limitations
- as mentioned in the description, only html/css and/or jQuery libraries are supported.
- as mentioned in the description, only html/css and/or JS libraries are supported.
- this mainly mean that React templates (Views) 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).
- 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.js` support a `container` and is needed for the filter to work as can be seen in the [multipleSelectFilter.ts](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/filters/multipleSelectFilter.ts#L26)
Expand Down Expand Up @@ -95,7 +95,7 @@ By default, the library uses the [inputFilter](https://github.com/ghiscoding/sli
If you want to load the grid with certain default filter(s), you can use the following optional properties:
- `searchTerms` (array of values)
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);`
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 with `filterElm.value = this.searchTerms;`
### 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`
Expand Down
Loading

0 comments on commit 317e4e0

Please sign in to comment.