Closed bytecast-de closed 10 months ago
Hi @bytecast-de this is not possible at the moment.
I think we can come up with something similar to the action mapper though. I'll have to think about some reasonable format. Do you have some syntax in mind?
Hi @Hyperkid123,
thank you for your quick response.
Based on the examples from the docs, there are some variations that come to mind from "user" perspective:
// value and config are always passed as arguments, "age" is the first "variable arg" from config
const olderThan = (value, config, age): boolean => {
return calculateAge(value) > age;
}
// this will be passed to the FormRenderer
const conditionMapper = {
"olderThan": olderThan,
}
// variant 1: using "is" with an array (function name + variable arguments), similar to ActionMapper
const schemaJSON = {
"title": "Is condition",
"fields": [
{
"component": "text-field",
"name": "field-2",
"label": "Field 2",
"condition": { "when": "field-1", "is": ["olderThan", 18] },
},
],
};
// variant 2: using a new condition type with same ActionMapper-like array as in variant 1
const schemaJSON = {
...
"condition": { "when": "field-1", "isFunction": ["olderThan", 18] },
...
};
// variant 3: using "is" (or a new condition type), but with a config object instead of an array
const schemaJSON = {
...
"condition": { "when": "field-1", "is": {"fn": "olderThan", "params": [18]} },
...
};
Variant 1 possibly won't work, as far as I've seen in the source, you can currently pass an array to "is", that behaves like "oneOf" - which is an undocumented feature, btw, or i missed it in the docs ;-) It maybe would be hard to make a distinction between the new feature and the old behaviour with arrays.
Variant 2 is probably more work - i don't know how many other parts must be changed, to add another condition type.
Variant 3 is in my opinion the most self-explaining and could possibly be used within the "is"-condition without the need to add another condition.
Please let me know what you think about it, and if I can be of any help with this feature.
@bytecast-de thanks for the suggestions.
I was thinking about something similar, bit there is an issue. All of the examples of is
implementation are valid values that can appear in a form state. This is not an issue within the action mapper as we map the entire prop to an action.
I think we will have to add some flag to the condition object that states that a particular condition is supposed to be mapped to a function
"condition": { "when": "field-1", "is": {"fn": "olderThan", "params": [18]}, mappedAttributes: { is: true } },
We can have an attribute like mappedAttributes
that would specify which condition attribute is supposed to be mapped to a function at runtime. There can be many attributes in that can be mapped, not just the is
. This mappedAttributes
syntax is in a way similar to the subscription
configuration.
@rvsia opinion?
@Hyperkid123
1) regarding the format of mapping, we should stay consistent with usage of action mappers so I prefer this variant: ["olderThan", 18]
2) regarding mappedAttributes
Following attributes could be mapped to some function, nothing else makes sense in the condition context:
And we could use mappedAttributes (or similar name) to map them as we do with the actions:
mappedAttributes: { is: ['olderThan', 18] }
@rvsia agreed.
I hope I'll have some time later this week to implement the condition mapper. Feel free to pick the issue if you want.
@Hyperkid123 @rvsia thanks for your feedback, sounds great to me - really looking forward to this feature.
I'd like to add that this is an awesome project, much appreciated!
OK I got some time on my hands. I'll work on the implementation
@rvsia if we were to follow the current option for condition function config, it does not make sens to send anything other than the mapped attribute name. We do not pass any custom argument function conditions. Its always just a value and the condition config,
@rvsia
Would it make sense to change it to higher-order-function to allow customization from the schema? 🤔
conditionMapper: {
ageValidation: (age = 18) => (value, config) => calculateAge(value, config) > (age)
}
// alcohol related page
schema = {
name: 'age',
component: 'date-picker',
condition: {
mappedAttributes: {
is: ['ageValidation', 18]
},
}
}
// senior sale related page :D
schema = {
name: 'age',
component: 'date-picker',
condition: {
mappedAttributes: {
is: ['ageValidation', 65]
},
}
}
We can do that or append the arguments after the regular arguments. HOF will follow the pattern set within the validation mapper.
@Hyperkid123 I would not append the arguments after regular - that could limit extensibility in the future.
@rvsia I've added the HOC. Right now the mapped conditions will work only for the is
and when
attributes. If we ever required the set
, it can be added later on.
:tada: This issue has been resolved in version 3.22.0 :tada:
The release is available on
@bytecast-de You can check the docs here: https://www.data-driven-forms.org/mappers/condition-mapper
@Hyperkid123 great job, thank you!
Scope: react-form-renderer / conditions
Description
I am looking for a way to define a condition via custom function (https://www.data-driven-forms.org/schema/is#customfunction) BUT i cannot use a javascript object, the schema has to be in JSON format since it will be retrieved from the backend.
I've looked into the ActionMapper (https://www.data-driven-forms.org/mappers/action-mapper), but as far as I understand, the mapped functions can only be applied to a field property. In my case I would need to assign a mapped function inside a (possibly nested) condition - some sort of "ConditionMapper" if that makes any sense. See example below.
My question is: Can this somehow be done with the current implementation, or would this be a feature request?
Schema
This is the javascript version, works as documented:
This would be the corresponding JSON-Version, I have no idea if/how this can be done at the moment: