Skip to Content
1

How to build SAP UI5 Filters with NOT?

Jun 03, 2017 at 08:26 PM

261

avatar image

How can I negate a sap.ui.model.Filter?

I know that for example the sap.ui.model.FilterOperator "EQ" is the opposite of "NE", and "LT" is the opposite of "GE" and so on, but what if I have a sap.ui.model.Filter that combines multiple filters, and I want to negate the entire combination? Or in code:

var path1 = 'field1', value1 = 'X'; 

//make a filter equivalent to OData: $filter=field1 eq 'X'

var filter1 = new Filter({  
  path: path,  
  value1: value,  
  operator: FilterOperator.EQ
});

//negate filter1, OData equivalent: $filter=field1 ne 'X':

var negatedFilter1 = new Filter({
  path: path,
  value1: value,
  operator: FilterOperator.NE 
});

var path2 = 'field2', value2 = 'Y';

//make a filter equivalent to OData: $filter=field2 lt 'Y'
var filter2 = new Filter({
  path: path2,
  value1: value2,
  operator: FilterOperator.LT 
});

//negate filter2, OData equivalent: $filter=field2 ge 'Y':
var negatedFilter2 = new Filter({
  path: path2,
  value1: value2,
  operator: FilterOperator.GE 
});

//combine filters 1 and 2 with AND
//OData equivalent: $filter=field1 eq 'X' and field2 lt 'Y'

var combinedFilter1AndFilter2 = new Filter({
  filters: [filter1, filter2],  
  and: true
});

//negate combinedFilter1AndFilter2
//Odate equivalent: $filter=not (field1 eq 'X' and field2 lt 'Y') ...?

I mean, sure, I can combine the negated filters individually, but in a practical situation this would become very complicated and error prone since we would have to travese the entire filter and come up with a negation for each and every one of them. I simply want to set a "not" flag on the combined filter as a whole, or if that isn't possible, wrap the combined filter in a new Filter and set a not flag there.

From what i have seen and read, I don't think such a not flag exists, is that correct? What is the recommended work-around? Will SAP UI5 build such a feature?

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

1 Answer

Arnd vom Hofe
Apr 20 at 12:55 PM
0

You can transform any logical

NOT (a AND b)

into
NOT a OR NOT b
so your negated filter could look like

var negateCombinedFilter1AndFilter2 = new Filter({
  filters: [negatedFilter1, negatedFilter2 ],  
  and: false
});
Show 1 Share
10 |10000 characters needed characters left characters exceeded

Hi Arnd vom Hofe , thanks for your reply.

Maybe I didn't specify this clearly enough in my question but my problem is not that I don't know how to rewrite a filter to a negated filter. The problem is mainly that something that would be trivially simple to do at the OData url level:

newFilterQueryOption = "not (" + oldFilterQueryOption + ")";

...becomes almost comically complex when done in UI5. One would have to build some filterTransformation function, that accepts a filter and then negate it, and this has to be done recursively too in case the filter is compound.

Now, suppose I would have to write such a function:
- in order to do the negation, I need to peer into the filter's private/protected members. At least, the API documentation does not list any methods that allow UI to inspect the operator,value and path of a filter
- While EQ can be negated with NEQ, LT by GTE, GT by LTE (and vice versa), it is unclear how we can negate Contains, StartsWith and EndsWith.

Basically, it just seems to me the ui5 Filter lacks a pretty simple and basic functionality.

1