Backend
Most likely the actual filtering will be done on the backend. To do so, you can send the output of onValueChange prop to the backend for this purpose:
const filters = createDatabitFilters(rootEl, {
onValueChange: ({ output }) => {
if (output !== null) {
sendToBackend(output);
}
},
});Example output shape:
{
"type": "logic",
"operator": "and",
"children": [
{
"type": "condition",
"variable": "x",
"operator": "=",
"value": "0",
},
{
"type": "logic",
"operator": "and",
"children": [
{
"type": "condition",
"variable": "y",
"operator": "<",
"value": "1",
},
{
"type": "condition",
"variable": "z",
"operator": "!=",
"value": "\"hello\"",
},
],
},
],
}On the backend side, in case you use typescript as your backend language, you can use the FiltersOutputVisitor type to travel through the output tree.
An example simple implementation that does nothing:
import type {
FiltersOutput,
FiltersOutputCondition,
FiltersOutputLogic,
} from "@databit/filters";
interface MyVisitorCtx {}
export type MyVisitorResult = void;
export class MyVisitor extends FiltersOutputVisitor<MyVisitorCtx, MyVisitorResult> {
visitLogicNode(node: FiltersOutputLogic, ctx: MyVisitorCtx): MyVisitorResult {
// node is the logic node
}
visitConditionNode(node: FiltersOutputCondition, ctx: MyVisitorCtx): MyVisitorResult {
// node is the condition node
}
visit(node: FiltersOutput) {
// custom entry point of the visitor
}
}We use here the Visitor pattern to go through all the nodes in the output, and MyVisitor is a concrete visitor of FiltersOutput. You can, for example, modify the MyVisitorResult to be a string and in visit*Node methods return strings that will create an sql query (remember about sanitizing the SQL if you do that!). The ctx: MyVisitorCtx is a helper context variable where you can store any information you want down the tree.
You can of course have a backend in a different language, but in that case you will need to write the visitor yourself.