如何在Ag-grid同一列同时配置set-filter与text-filter?
Hey there! Great question—combining these two filter types on one column is absolutely achievable, though the approach varies a bit depending on whether you're using AG Grid Community or Enterprise. Let's break down both scenarios:
Enterprise Version: Use the Built-in Multi Filter
If you're on AG Grid Enterprise, you're in luck! The grid has a native multiFilter that lets you stack multiple filter types on the same column with minimal code. Here's how to set it up:
const columnDefs = [ { headerName: "Your Column", field: "yourField", filter: 'multiFilter', filterParams: { filters: [ { filter: 'textFilter', filterParams: { // Optional: Configure text filter options like case sensitivity caseSensitive: false } }, { filter: 'setFilter', filterParams: { // Optional: Configure set filter options, e.g. values to show values: ['Option 1', 'Option 2', 'Option 3'] } } ] } } ];
This will render both filters in the column's filter menu, and the grid automatically combines their results with AND logic (you can adjust this if needed via additional filterParams configurations).
Community Version: Build a Custom Filter Component
For the Community edition, you'll need to create a custom filter component that integrates both text and set filtering logic. Here's a simplified vanilla JS example:
Step 1: Define the Custom Filter Component
class CombinedFilter { init(params) { this.params = params; this.filterText = ''; this.selectedValues = new Set(); // Create the filter UI elements this.eGui = document.createElement('div'); this.eGui.innerHTML = ` <div style="margin-bottom: 10px;"> <label>Text Filter:</label> <input type="text" id="text-filter-input" style="width: 100%; margin-top: 5px;"> </div> <div> <label>Set Filter:</label> <div id="set-filter-options"></div> </div> `; // Populate set filter options const optionsContainer = this.eGui.querySelector('#set-filter-options'); params.values.forEach(value => { const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.value = value; checkbox.addEventListener('change', () => this.onFilterChanged()); const label = document.createElement('label'); label.textContent = value; label.prepend(checkbox); optionsContainer.appendChild(label); optionsContainer.appendChild(document.createElement('br')); }); // Text filter input listener const textInput = this.eGui.querySelector('#text-filter-input'); textInput.addEventListener('input', (e) => { this.filterText = e.target.value.toLowerCase(); this.onFilterChanged(); }); } getGui() { return this.eGui; } doesFilterPass(params) { const value = params.data[this.params.field].toLowerCase(); // Text filter check: if filter text exists, value must include it const textPasses = !this.filterText || value.includes(this.filterText); // Set filter check: if any values are selected, value must be in selected set const setPasses = this.selectedValues.size === 0 || this.selectedValues.has(params.data[this.params.field]); // Combine both conditions with AND (adjust to OR if needed) return textPasses && setPasses; } onFilterChanged() { // Update selected values from checkboxes this.selectedValues.clear(); const checkboxes = this.eGui.querySelectorAll('input[type="checkbox"]:checked'); checkboxes.forEach(cb => this.selectedValues.add(cb.value)); // Notify grid of filter change this.params.filterChangedCallback(); } // Optional: Implement required methods for filter state management isFilterActive() { return this.filterText !== '' || this.selectedValues.size > 0; } getModel() { return { filterText: this.filterText, selectedValues: Array.from(this.selectedValues) }; } setModel(model) { if (!model) return; this.filterText = model.filterText || ''; this.eGui.querySelector('#text-filter-input').value = this.filterText; this.selectedValues = new Set(model.selectedValues || []); const checkboxes = this.eGui.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach(cb => { cb.checked = this.selectedValues.has(cb.value); }); } }
Step 2: Register the Component and Use It in Column Defs
// Register the custom filter with AG Grid agGrid.registerFilter('combinedFilter', CombinedFilter); // Define your column def const columnDefs = [ { headerName: "Your Column", field: "yourField", filter: 'combinedFilter', filterParams: { // Pass unique values for the set filter (generate from your row data) values: Array.from(new Set(rowData.map(item => item.yourField))) } } ];
This custom component will render both a text input and a list of checkboxes for set selection, and apply both filters together when either input changes.
Quick Tips:
- For framework-specific apps (React, Angular, Vue), adapt the logic to use framework components instead of vanilla JS.
- Tweak the
doesFilterPassmethod to use OR logic instead of AND if you want rows to pass either filter condition. - Don't forget to handle empty filter states (e.g., no text entered and no set values selected should show all rows).
内容的提问来源于stack exchange,提问作者Sai

