-
-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filter collection items with a string contains instead of equal #808
Comments
The Angular-Slickgrid/src/app/examples/grid-graphql-nopage.component.ts Lines 76 to 91 in 4a5ae71
![]() For this kind of filtering, I typically use a Select Filter (single/multiple) and build the The code for the For reference here's the next breaking PR #803 and the announcement of it in the last release |
Well, that multiple select only works if the backend field contains a single value. For example: But in my case a user can have multiple roles and the roles field is a plain string field which holds comma delimited values (CSV). So like
Cool!
I understand and agree we should not fix this in the current Angular-Slickgrid, also because I found a workaround: export class CustomGridODataService extends GridOdataService {
updateFilters(columnFilters: ColumnFilters | CurrentFilter[], isUpdatedByPresetOrDynamically?: boolean): void {
const replacers: { searchValue: string; replaceValue: string}[] = [];
if (!Array.isArray(columnFilters)) {
for (const key in columnFilters) {
if ({}.hasOwnProperty.call(columnFilters, key)) {
const columnFilter = columnFilters[key];
if (columnFilter.operator === OperatorType.inContains) {
columnFilter.operator = OperatorType.in;
const delimiter = columnFilter.columnDef?.params?.inContainsDelimiter ?? ',';
const searchField = columnFilter.columnDef.queryFieldFilter ?? columnFilter.columnDef.queryField ?? columnFilter.columnDef.field;
for (const searchTerm of columnFilter.searchTerms) {
// Example with , as delimiter and searching for a role 'User'. Imagine the backend has [{ roles: 'SuperUser,User,UserEditor' }]
//
// - searchValue: roles eq 'User'
// - replaceValue: contains(concat(',', concat(roles, ',')), ',User,')
//
// On the backend this translates to SQL: ... WHERE CHARINDEX(',Sales,', ',' + Roles + ',') > 0
replacers.push({
searchValue: `${searchField} eq '${searchTerm}'`,
replaceValue: `contains(concat('${delimiter}', concat(${searchField}, '${delimiter}')), '${delimiter}${searchTerm}${delimiter}')`
});
}
}
}
}
}
// Monkey patch the 'updateOptions' method.
const oldUpdateOptions = this.odataService.updateOptions;
this.odataService.updateOptions = (options: Partial<OdataOption>): void => {
if (typeof options.filter === 'string') {
for (const replacer of replacers) {
options.filter = options.filter.replace(replacer.searchValue, replacer.replaceValue);
}
}
oldUpdateOptions.apply(this.odataService, [options]);
};
try {
super.updateFilters(columnFilters, isUpdatedByPresetOrDynamically);
} finally {
this.odataService.updateOptions = oldUpdateOptions;
}
}
} Not the nicest, but it's good enough 😄 For the
I can work on that, but will be after summer vacation... |
Nice, I'm going in vacation the week after that and that is why I'm pushing hard to release the new major version before then 😉
if it's something that could also be used by others, feel free to push new code and/or new function(s) on the Slickgrid-Universal repo, like I said earlier the Service is exactly the same as the one from Angular-Slickgrid (which the exception that it's not a standalone package)
There's only a few I didn't use OData in a few years but I know you are a big user of it and there are also a lot of other developers using it (probably more than the GraphQL Service). I'm always open to your contributions and they always bring enhancements, so feel free to contribute some more in the future. I won't be able to test these enhancements myself because I don't have access to an OData Server anymore but I can still review the changes. |
hey what's the |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch |
Some updates
|
@jr01 if there's no update on this, I think I'll turn this into a "Discussion" instead of an "Issue" since I think it's pretty much that anyway... |
@ghiscoding I'll migrate to 3.x first and will then create an issue or PR on the new repo. |
I'm submitting a Feature request
Motivation / Use Case
Hi!
My oData backend returns a field that holds a comma delimited string of values:
[{ roles: 'User,Sales,SuperUser' }]
.I'm presenting this in the grid with a formatter that displays each value as a (bootstrap) badge 📛. Nice!
Ultimately I want to be able to search with a (custom) multiselect
FilterControl
on any combination of the values.Now at first I started with a single select and because searching for
User
shouldn't returnSuperUser
I added a,
to the query field and each queried value and use a 'contains':This works and
$filter=contains(concat(roles, ','), 'User,')
is send to the oData backend. 😀The next step is to get the multiselect working and I noticed
OperatorType.inContains
which sounds like it fits my need, butIN_CONTAINS
isn't implemented: https://github.com/ghiscoding/Angular-Slickgrid/blob/master/src/app/modules/angular-slickgrid/services/grid-odata.service.ts#L352 😢Now I'm not completely sure what the purpose of
IN_CONTAINS
is and I'm wondering if it can be used and if I can implement it roughly like:or if there would be a different direction/solution perhaps? 😄
What do you think?
Expected Behavior
IN_CONTAINS
can be used in oData and other backends.Other Information
The text was updated successfully, but these errors were encountered: