Open markphillips100 opened 4 years ago
I managed to get it working with a bit of map/reduce which is simple enough for my use case. Although it would be nice to wrap that up into a simple expression to drive the underlying map/reduce.
class MultiSelectCheckBoxConstraintsGroupParser<TMultiSelectCheckBoxConstraintsGroup extends MultiSelectCheckBoxConstraintsGroup>
extends MultiSelectConstraintsGroupParser<TMultiSelectCheckBoxConstraintsGroup, MultiSelectCheckBoxConstraintsChoice> {
@override
String get name => 'multiSelectCheckBoxConstraintsGroup';
@override
FormElement getInstance() => MultiSelectCheckBoxConstraintsGroup();
@override
void fillProperties(
TMultiSelectCheckBoxConstraintsGroup multiSelectCheckBoxConstraintsGroup,
ParserNode parserNode,
Element parent,
ElementParserFunction parser,
) {
super.fillProperties(multiSelectCheckBoxConstraintsGroup, parserNode, parent, parser);
multiSelectCheckBoxConstraintsGroup
..quantityProperty = getQuantityExpression(multiSelectCheckBoxConstraintsGroup);
}
LazyExpressionProperty<int> getQuantityExpression(MultiSelectCheckBoxConstraintsGroup multiSelectCheckBoxConstraintsGroup) {
return LazyExpressionProperty(
() {
final resultExpression = multiSelectCheckBoxConstraintsGroup.choices
.map<Expression<Number>>((c) =>
IntToIntegerExpression(
DelegateExpression(
[multiSelectCheckBoxConstraintsGroup.id],
c.getExpressionProvider(MultiSelectConstraintsGroup.quantityPropertyName),
),
),
)
.reduce((value, next) => ConversionExpression<Number, Integer>(PlusNumberExpression(value, next)));
return IntegerToIntExpression(resultExpression);
}
);
}
}
Hi @markphillips100 , Sorry for the late response, but I didn't have any solution to your problem - until now.
What we need is expression with lambda, something like "sum(children.map((x) => x.quantity))"
. Unfortunately, it is not possible to easily implement lambda functions in the current version of the expression_language
package. It is something I would like to implement in the future, but I think it will take a significant amount of work because I would need to completely change the way how the parser works.
To be honest I am quite impressed you were able to find a solution since there is not much documentation for those cases.
However, I don't like the approach of the RequiredValidation where we define the expression directly on the property - it is difficult to understand and not very reusable.
For this reason, I just released a new version of packages with the possibility of implementing custom expressions, see https://github.com/OndrejKunc/flutter_dynamic_forms/tree/master/packages/expression_language#writing-custom-expressions I also added the "Advanced expression form" screen to the example project: https://github.com/OndrejKunc/flutter_dynamic_forms/blob/master/packages/flutter_dynamic_forms_components/example/lib/advanced_expression_form/advanced_expression_form.dart which should solve your issue.
I solved it by adding two custom expressions
SelectNumberPropertyExpression
which is the equivalent of the lambda above "children.map((x) => x.quantity)"
SumNumbersExpression
which gets a list of number expressions and returns a sum similar to your solution.Then you can just declare it directly in the XML/JSON without the need to define custom property:
sumNumbers(selectNumberProperty(@sliderCollection.children, \"value\"))
Hi @OndrejKunc . Apologies for my even later late response to your response :-) I'll hopefully revisit this soon so I can try out your changes. Appreciate your efforts.
I've been trying to create a custom grouping of checkbox choice items where each choice component has an integer quantity property and the parent group component also has a quantity property. The requirement I have is for the parent quantity value to be calculated as a sum of all the child choices' individual quantity values. The calculation should be reevaluated each time there is a change to any of the child quantity values.
I also want the calculation to be implicit in the parent parser, a bit like how RequiredValidation defines its expression in the parser. Basically I don't want the expression to be defined in the data.
I tried the following but the expression fires only once which makes sense considering the expression is only dependent on the choices property and not the underlying quantity properties. So my question is, is there support for simple aggregate expressions that can take a list of properties? If not, is there some other way of achieving the desired result?