Open FlorianRuen opened 1 year ago
The correct way to achieve this is to add custom function (you can take LINEAR_REGRESSION as example).
With version 6.4.0 you can use functions in LHS.
I will add support of simple math functions in next version.
For now there is no support of dynamic arg length (like SUM(...numbers)
instead of SUM(a, b)
), but I'll work on it soon.
@ukrbublik Thanks for the answer While waiting to have a list of arguments, would it be possible to accept at least 3 rather than 2? I saw on the LINEAR_REGRESSION we can ave multiple args, so my idea is to create multiple args here
As a workaround, you can have several functions:
SUM2(a, b)
with 2 argsSUM3(a, b, c)
with 3 argsSUM4(a, b, c, d)
with 4 argsOr (probably better) one function SUM4(a, b, c, d)
where c
and d
are optional
I tried using this, but I think, two problems will appear if I want var1 + var2 + var3 <= 21
(as example) :
const funcs = {
SUM: {
label: '+',
returnType: 'number',
jsonLogic: ({a, b, c, d}) => ({ "+": [a, b, c, d]}),
renderBrackets: ['', ''],
renderSeps: [' + ', ' + ', ' + ', ' + '],
args: {
a: {
label: "A",
type: 'number',
defaultValue: 1,
valueSources: ['value'],
},
b: {
label: "B",
type: 'number',
defaultValue: 0,
valueSources: ['value'],
},
c: {
label: "C",
type: 'number',
defaultValue: 0,
valueSources: ['field', 'value'],
},
d: {
label: "D",
type: 'number',
defaultValue: 0,
valueSources: ['value'],
}
}
}
};
valueSources = ['field', 'value']
seems not working very well, because of the first field selector ;Want I want is sum(a, b, c, d) == 10
and I appear that I can only create varA = sum(a, b, c, d)
Please use
fieldSources: ["field", "func"],
in config.settings
, then you can put sum in left side and 10 in right side
Please use
fieldSources: ["field", "func"],
in
config.settings
, then you can put sum in left side and 10 in right side
Indeed, I already had it is, but I had not installed the latest version from yesterday
The correct way to achieve this is to add custom function (you can take LINEAR_REGRESSION as example).
With version 6.4.0 you can use functions in LHS. I will add support of simple math functions in next version. For now there is no support of dynamic arg length (like
SUM(...numbers)
instead ofSUM(a, b)
), but I'll work on it soon.
Do you have an estimate of the release dates for these versions? For both simple math function (because should be better in operator than in funcs) and for the dynamic arg lenght
(because should be better in operator than in funcs)
I don't have plans to extend operators. I have plans to add new math funcs. In your example you use operator ==
All right. So the math functions will be considered as funcs
But in JsonLogic, the negative operator can take only two values (similar as division), the alternative should be
A - (B + C)
is equal to A - B - C
, using funcs, this will not be possible (like func in func or something) ?
It's already possible to put func in func, of you specify valueSources: ['value', 'func']
for arg
If this is already possible, there might already be a way to manage the sum more easily:
Could the arg be of type multi select ? like this, a sum function could take the set of values selected in the list (like for cars / vendor on the demo)
If this is possible, it would be quite possible to be able to sum with several values (as for a dynamic arg number finally)
Yes, it can be multiselect, but it provides array of strings, and you need array of integers. Probably you can customize multiselect widget to not allow any characters other than 0-9 I plan to support array of integers in future, but can't give you ETA as it's my hobby project and I have full time work
Great, I will go deeper in the configuration, and maybe If I found some time, I can submit some pull request to improve the project
Last thing, you said, we can select func in func, but on my side, the result isn't working (the second func dropdown is always empty), am I doing something wrong?
Please add allowNesting: true
in func config
@ukrbublik Thanks for the advice, the property is allowSelfNesting
I'm testing some custom multi select components, and if works, I will comment here, can be helpful
@ukrbublik
One question : with custom function it seems the loadFromJsonLogic
isn't working. Does that mean importing is only possible with default items?
The error in console is : Errors while importing from JsonLogic: ['Unknown LHS']
I tried to import a custom function called SUM
Also, a standard jsonLogic generated by the UI, cannot be imported using the same method
{"and":[{"==":[{"var":"a"},10]},{">=":[{"var":"b"},12]}]};
Got an error : Cannot real propety of null (reading type)
happend in jsonLogic.js:465:1
at Array.map (<anonymous>)
at convertConj (http://localhost:4040/main.5cedf9f968dbbd461af5.hot-update.js:8803:83)
at convertFromLogic (http://localhost:4040/main.5cedf9f968dbbd461af5.hot-update.js:8489:11)
at _loadFromJsonLogic (http://localhost:4040/main.5cedf9f968dbbd461af5.hot-update.js:8394:28)
at loadFromJsonLogic (http://localhost:4040/main.5cedf9f968dbbd461af5.hot-update.js:8386:10)
You need to add jsonLogicImport
const SUM = {
label: '+',
returnType: 'number',
// export
jsonLogic: ({a, b, c, d}) => ({ "+": [a, b, c, d]}),
// import
jsonLogicImport: (v) => {
const args = v["+"];
return [...args];
},
...
As for the error, please provide your config, or codesandbox to reproduce
Here is my config :
[... imports ...]
const operators = {
...BootstrapConfig.operators,
between: {
...BootstrapConfig.operators.between,
label: "Between",
valueLabels: ['from', 'to'],
textSeparators: ['from', 'to'],
},
};
const widgets = {
...BootstrapConfig.widgets,
number: { ...BootstrapConfig.widgets.number },
select: { ...BootstrapConfig.widgets.select },
func: { ...BootstrapConfig.widgets.func },
time: {
...BootstrapConfig.widgets.time,
timeFormat: 'HH:mm',
valueFormat: 'HH:mm:ss',
}
};
const types = {
...BootstrapConfig.types,
boolean: merge(BootstrapConfig.types.boolean, {
widgets: {
boolean: {
widgetProps: {
hideOperator: true,
operatorInlineLabel: "is",
}
},
},
}),
};
const localeSettings = { locale: { short: 'en', full: 'en-US' } };
const settings = {
...BootstrapConfig.settings,
...localeSettings,
valueSourcesInfo: {
value: { label: "Value" },
field: { label: "Variable", widget: "field" },
func: { label: "Function", widget: "func" }
},
maxNesting: 3,
canLeaveEmptyGroup: false,
canReorder: true,
canRegroup: false,
fieldSources: ["field", "func"],
renderField: (props) => <BootstrapFieldSelect {...props} />,
renderValueSources: (props) => <BootstrapValueSources {...props} />,
};
const fields = {
"Pipeline": {
label: 'Pipeline',
tooltip: 'Pipeline',
type: '!struct',
subfields: GetPipelineQueryFields()
}
};
const funcs = {
...BootstrapConfig.funcs,
SUM: {
label: 'Sum',
returnType: 'number',
allowSelfNesting: true,
jsonLogic: ({firstNumber, secondNumber}) => ({ "+": [firstNumber, secondNumber]}),
jsonLogicImport: (v) => {
const args = v["+"];
return [...args];
},
renderSeps: [' + '],
args: {
firstNumber: {
label: "Number",
type: "number",
valueSources: ['field']
},
secondNumber: {
label: "Number or func",
type: "number",
valueSources: ['field', 'func']
},
}
},
MINUS: {
label: 'Subtraction',
returnType: 'number',
allowSelfNesting: true,
jsonLogic: ({firstNumber, secondNumber}) => ({ "-": [firstNumber, secondNumber]}),
jsonLogicImport: (v) => {
const args = v["-"];
return [...args];
},
renderSeps: [' - '],
args: {
firstNumber: {
label: "Number",
type: "number",
valueSources: ['field']
},
secondNumber: {
label: "Number or func",
type: "number",
valueSources: ['field', 'func']
},
}
},
MULTIPLY: {
label: 'Multiply',
returnType: 'number',
allowSelfNesting: true,
jsonLogic: ({firstNumber, secondNumber}) => ({ "*": [firstNumber, secondNumber]}),
jsonLogicImport: (v) => {
const args = v["*"];
return [...args];
},
renderSeps: [' * '],
args: {
firstNumber: {
label: "Number",
type: "number",
valueSources: ['field']
},
secondNumber: {
label: "Number or func",
type: "number",
valueSources: ['field', 'func']
},
}
},
DIVIDE: {
label: 'Division',
returnType: 'number',
allowSelfNesting: true,
jsonLogic: ({firstNumber, secondNumber}) => ({ "/": [firstNumber, secondNumber]}),
jsonLogicImport: (v) => {
const args = v["/"];
return [...args];
},
renderSeps: [' / '],
args: {
firstNumber: {
label: "Number",
type: "number",
valueSources: ['field']
},
secondNumber: {
label: "Number or func",
type: "number",
valueSources: ['field', 'func']
},
}
}
};
const config = {
ctx: BootstrapConfig.ctx,
conjunctions,
operators,
widgets,
types,
settings,
fields,
funcs
};
export default config;
Please try version 6.4.1 to fix the error Just triggered the release, should be available soon at NPM
@ukrbublik seems working perfectly now! good and fast release !
I'm using a jsonlogic standard to create some queries, but on react query builder I didn't see a way to create custom operators like
plus
,minus
,multiply
with some constraintsMultiply
andplus
, can take multiple value (array [2,2,2,2] for example)Minus
andDivide
can take only two args (array [4,2] for example)I tried to add an element to the operators, but it's not showing (very simple without logic, but not showing at this time)
There is a way to create this kind of arithmetic operators ? I saw a answer using https://github.com/ukrbublik/react-awesome-query-builder/issues/809 but I want to create an operator instead of function (easier to use and better UI for users)
Also, I tried to copy the
LINEAR_REGRESSION
and put the content in operators, but not showing anymoreIn JSONLOGIC, I need to generate something like :
Any idea ?