Skip to content

Commit

Permalink
fix: input filter loses focus after edit+filtering with `enableExcelC…
Browse files Browse the repository at this point in the history
…opyBuffer` (#1750)

* fix: input filter loses focus after edit+filtering
  • Loading branch information
ghiscoding authored Nov 27, 2024
1 parent af9f5db commit b2f4f52
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class SlickCellExternalCopyManager {
// we give focus on the grid when a selection is done on it (unless it's an editor, if so the editor should have already set focus to the grid prior to editing a cell).
// without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work
this._eventHandler.subscribe(cellSelectionModel.onSelectedRangesChanged, () => {
if (!this._grid.getEditorLock().isActive()) {
if (!this._grid.getEditorLock().isActive() && !document.activeElement?.classList.contains('slick-filter')) {
this._grid.focus();
}
});
Expand Down Expand Up @@ -543,4 +543,4 @@ export class SlickCellExternalCopyManager {
window.clearTimeout(this._clearCopyTI as number);
this._clearCopyTI = window.setTimeout(() => this.clearCopySelection(), this.addonOptions?.clearCopySelectionDelay || CLEAR_COPY_SELECTION_DELAY);
}
}
}
2 changes: 1 addition & 1 deletion packages/common/src/filters/autocompleterFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ export class AutocompleterFilter<T extends AutocompleteItem = any> implements Fi
ariaLabel: this.columnFilter?.ariaLabel ?? `${toSentenceCase(columnId + '')} Search Filter`,
autocomplete: 'off', ariaAutoComplete: 'none',
placeholder,
className: `form-control search-filter filter-${columnId} slick-autocomplete-container`,
className: `form-control search-filter slick-filter filter-${columnId} slick-autocomplete-container`,
value: (searchTerm ?? '') as string,
dataset: { columnid: `${columnId}` }
});
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/filters/dateFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ export class DateFilter implements Filter {

if (this.inputFilterType === 'range') {
// if there's a search term, we will add the "filled" class for styling purposes
const inputContainerElm = createDomElement('div', { className: `date-picker form-group search-filter filter-${columnId}` });
const inputContainerElm = createDomElement('div', { className: `date-picker form-group search-filter slick-filter filter-${columnId}` });

if (Array.isArray(searchTerms) && searchTerms.length > 0 && searchTerms[0] !== '') {
this._currentDateOrDates = searchTerms as Date[];
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/filters/inputFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export class InputFilter implements Filter {
if (this.inputFilterType === 'single') {
this._filterContainerElm = this._filterInputElm;
// append the new DOM element to the header row & an empty span
this._filterInputElm.classList.add('search-filter');
this._filterInputElm.classList.add('search-filter', 'slick-filter');
this._cellContainerElm.appendChild(this._filterInputElm);
this._cellContainerElm.appendChild(document.createElement('span'));
} else {
Expand Down Expand Up @@ -316,7 +316,7 @@ export class InputFilter implements Filter {
this.callback(event, { columnDef: this.columnDef, clearFilterTriggered: isClearFilterEvent, shouldTriggerQuery: this._shouldTriggerQuery });
this.updateFilterStyle(false);
} else {
const eventType = event?.type ?? '';
const eventType = event?.type || '';
const selectedOperator = (this._selectOperatorElm?.value ?? this.operator) as OperatorString;
let value = this._filterInputElm.value;
const enableWhiteSpaceTrim = this.gridOptions.enableFilterTrimWhiteSpace || this.columnFilter.enableTrimWhiteSpace;
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/filters/sliderFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export class SliderFilter implements Filter {
// put all DOM elements together to create the final Slider
const hideSliderNumbers = (this.filterOptions as SliderOption)?.hideSliderNumber ?? (this.filterOptions as SliderRangeOption)?.hideSliderNumbers;
const sliderNumberClass = hideSliderNumbers ? '' : 'input-group';
this._divContainerFilterElm = createDomElement('div', { className: `${sliderNumberClass} search-filter slider-container slider-values filter-${columnId}`.trim() });
this._divContainerFilterElm = createDomElement('div', { className: `${sliderNumberClass} search-filter slick-filter slider-container slider-values filter-${columnId}`.trim() });

this._sliderRangeContainElm.appendChild(this._sliderTrackElm);
if (this.sliderType === 'double' && this._sliderLeftInputElm) {
Expand Down
64 changes: 30 additions & 34 deletions packages/common/src/services/filter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,8 @@ export class FilterService {
}

// when using a backend service, we need to manually trigger a filter change but only if the filter was previously filled
if (isBackendApi) {
if (currentColFilter !== undefined) {
this.onBackendFilterChange(event, { grid: this._grid, columnFilters: this._columnFilters } as unknown as OnSearchChangeEventArgs);
}
if (isBackendApi && currentColFilter !== undefined) {
this.onBackendFilterChange(event, { grid: this._grid, columnFilters: this._columnFilters } as unknown as OnSearchChangeEventArgs);
}

// emit an event when filter is cleared
Expand Down Expand Up @@ -358,40 +356,38 @@ export class FilterService {
}
return filtered;
}
} else {
if (typeof columnFilters === 'object') {
for (const columnId of Object.keys(columnFilters)) {
const searchColFilter = columnFilters[columnId] as SearchColumnFilter;
const columnFilterDef = searchColFilter.columnDef?.filter;

// user could provide a custom filter predicate on the column definition
if (typeof columnFilterDef?.filterPredicate === 'function') {
// only return on false, when row is filtered out and no further filter to be considered
if (!columnFilterDef.filterPredicate(item, searchColFilter)) {
return false;
}
} else {
// otherwise execute built-in filter condition checks
const conditionOptions = this.preProcessFilterConditionOnDataContext(item, searchColFilter, grid);
if (typeof conditionOptions === 'boolean') {
return conditionOptions; // reaching this line means that the value is not being filtered out, return it right away
}
} else if (typeof columnFilters === 'object') {
for (const columnId of Object.keys(columnFilters)) {
const searchColFilter = columnFilters[columnId] as SearchColumnFilter;
const columnFilterDef = searchColFilter.columnDef?.filter;

// user could provide a custom filter predicate on the column definition
if (typeof columnFilterDef?.filterPredicate === 'function') {
// only return on false, when row is filtered out and no further filter to be considered
if (!columnFilterDef.filterPredicate(item, searchColFilter)) {
return false;
}
} else {
// otherwise execute built-in filter condition checks
const conditionOptions = this.preProcessFilterConditionOnDataContext(item, searchColFilter, grid);
if (typeof conditionOptions === 'boolean') {
return conditionOptions; // reaching this line means that the value is not being filtered out, return it right away
}

let parsedSearchTerms = searchColFilter?.parsedSearchTerms; // parsed term could be a single value or an array of values
let parsedSearchTerms = searchColFilter?.parsedSearchTerms; // parsed term could be a single value or an array of values

// in the rare case of an empty search term (it can happen when creating an external grid global search)
// then we'll use the parsed terms and whenever they are filled in, we typically won't need to ask for these values anymore.
if (parsedSearchTerms === undefined) {
parsedSearchTerms = getParsedSearchTermsByFieldType(searchColFilter.searchTerms, searchColFilter.columnDef.type || FieldType.string); // parsed term could be a single value or an array of values
if (parsedSearchTerms !== undefined) {
searchColFilter.parsedSearchTerms = parsedSearchTerms;
}
// in the rare case of an empty search term (it can happen when creating an external grid global search)
// then we'll use the parsed terms and whenever they are filled in, we typically won't need to ask for these values anymore.
if (parsedSearchTerms === undefined) {
parsedSearchTerms = getParsedSearchTermsByFieldType(searchColFilter.searchTerms, searchColFilter.columnDef.type || FieldType.string); // parsed term could be a single value or an array of values
if (parsedSearchTerms !== undefined) {
searchColFilter.parsedSearchTerms = parsedSearchTerms;
}
}

// execute the filtering conditions check, comparing all cell values vs search term(s)
if (!FilterConditions.executeFilterConditionTest(conditionOptions as FilterConditionOption, parsedSearchTerms)) {
return false;
}
// execute the filtering conditions check, comparing all cell values vs search term(s)
if (!FilterConditions.executeFilterConditionTest(conditionOptions as FilterConditionOption, parsedSearchTerms)) {
return false;
}
}
}
Expand Down

0 comments on commit b2f4f52

Please sign in to comment.