react-querybuilder integration for FilterKit. Turn a react-querybuilder query into a filter expression you can send to your API.
import { toFilterExpression } from '@turkraft/filterkit-querybuilder';
const query = {
combinator: 'and',
rules: [
{ field: 'year', operator: 'between', value: '2020,2025' },
{ field: 'status', operator: 'in', value: 'active,pending' },
{ field: 'name', operator: 'contains', value: 'John' },
],
};
const expr = toFilterExpression(query);
// => year between '2020' and '2025' and status in ['active', 'pending'] and name ~ '%John%'npm install @turkraft/filterkit-querybuilder @turkraft/filterkitSee the other FilterKit integrations:
import { QueryBuilder } from 'react-querybuilder';
import { toFilterExpression } from '@turkraft/filterkit-querybuilder';
function MyComponent() {
const [query, setQuery] = useState(initialQuery);
const filterString = toFilterExpression(query);
const fetchData = () => {
fetch(`/api/data?filter=${encodeURIComponent(filterString)}`);
};
return <QueryBuilder query={query} onQueryChange={setQuery} />;
}toFilterExpression returns '' for an empty query — that means "no filter", so
check for it before sending an empty filter= parameter.
| react-querybuilder operator | FilterKit expression |
|---|---|
= |
field : 'value' |
!= |
field ! 'value' |
<, >, <=, >= |
comparisons |
contains |
field ~ '%value%' |
beginsWith |
field ~ 'value%' |
endsWith |
field ~ '%value' |
doesNotContain |
not field ~ '%value%' |
doesNotBeginWith |
not field ~ 'value%' |
doesNotEndWith |
not field ~ '%value' |
null |
field is null |
notNull |
field is not null |
in |
field in ['a', 'b'] |
notIn |
field not in ['a', 'b'] |
between |
field between 'a' and 'b' |
notBetween |
not field between 'a' and 'b' |
in, notIn, between and notBetween accept either an array or
react-querybuilder's comma-separated string form.
An operator outside this table throws, so a typo or a custom operator you have not
mapped surfaces immediately instead of quietly becoming =. Pass
{ onUnknownOperator: 'skip' } to drop those rules instead:
toFilterExpression(query, { onUnknownOperator: 'skip' });Group combinators (and, or, xor) and negation (not) are preserved. A
combinator outside those three throws; defaulting it to and would silently
change the query, since and is not a subset of xor. A group with no
combinator at all still means and.
Sub-groups and negated groups are parenthesised, so the emitted expression means
what the builder showed:
toFilterExpression({
combinator: 'and',
not: true,
rules: [
{ field: 'a', operator: '=', value: 1 },
{ field: 'b', operator: '=', value: 2 },
],
});
// => not (a : '1' and b : '2')react-querybuilder's RuleGroupTypeIC puts a combinator string between each pair
of rules. That shape is supported; rules are combined left to right and
parenthesised where precedence requires it:
toFilterExpression({
rules: [
{ field: 'a', operator: '=', value: 1 },
'or',
{ field: 'b', operator: '=', value: 2 },
'and',
{ field: 'c', operator: '=', value: 3 },
],
});
// => (a : '1' or b : '2') and c : '3'A rule with valueSource: 'field' compares against another column rather than a
literal:
toFilterExpression({
combinator: 'and',
rules: [{ field: 'startDate', operator: '<=', value: 'endDate', valueSource: 'field' }],
});
// => startDate <: endDate- Values are quoted; the backend converts them to each field's type.
contains/beginsWith/endsWithwrap the value in%without escaping, so a%or_the user types becomes a wildcard. Sanitise the value first if that matters for your endpoint.- The
in/betweenstring form splits on commas, so a value containing a comma must be passed as an array.
The expression syntax matches Spring Filter,
so the string this package produces can go straight into a filter= parameter on a
Spring Boot endpoint. Nothing here depends on that — any API that understands the
syntax works the same way.
Sponsor our project and have your issues prioritized.
ixorbv |
marcopag90 |
MIT