Open helmenaem opened 4 years ago
Hi @helmenaem ,
I tried your code and I can see a couple of issues:
After you hit add button, you add an item to the list, but itemsChanged
Stream doesn't emit value, because it listens to the property changes and not changes to single items in a list.
To fix this you first need to make this list property mutable, so you can change this property later and Stream will emit the value.
1) In your multi_insert_parser.g.dart
just add isImmutable: false
in the getChildrenProperty
method.
2) Your renderer will look like this:
class DefaultMultiInsertRenderer
extends FormElementRenderer<model.Multiinsert> {
double iconSize = 40;
@override
Widget render(
model.Multiinsert element,
BuildContext context,
FormElementEventDispatcherFunction dispatcher,
FormElementRendererFunction renderer) {
return StreamBuilder<List<MultiInsertItem>>(
initialData: element.items,
stream: element.itemsChanged,
builder: (context, snapshot) {
List<Widget> childrenWidgets = [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
element.name,
style: TextStyle(color: Colors.grey),
),
)
];
for (var child in element.children) {
if (child.isVisible) {
childrenWidgets.add(renderer(child, context));
}
}
childrenWidgets.add(RaisedButton(
child: Text('Add'),
onPressed: () {
var newList = List<MultiInsertItem>.from(
element.items
..add(
MultiInsertItem(
rowId: (element.items.isEmpty
? 0
: element.items[element.items.length - 1].rowId) +
1,
rowData: [
element.items.length.toString(),
'row num : ' + element.items.length.toString()
],
),
),
);
var mutableProperty = element.itemsProperty
as MutableProperty<List<MultiInsertItem>>;
mutableProperty.setValue(newList);
print(element.items);
}));
childrenWidgets.add(Table(
border: TableBorder.all(),
children: element.items
.map((entry) => TableRow(
children: entry.rowData.map((d) => Text(d)).toList()))
.toList()));
return Column(
children: childrenWidgets,
);
},
);
}
}
This will update the UI,
Then there is the question of collecting the data back via _formManager.getFormData();
. It basically calls toString
on all mutable properties so it will call toString
on your items
property which is a list. You can improve the output by overriding toString
in your MultiInsertItem
, but to make each MultiInsertItem
have one FormItemValue
record, you would need to extend FormElement
in your MultiInsertItem
.
I would recommend checking this issue #65 - specifically CopyContainer
in my ok/copy-container
branch. It is trying to solve similar problem, but the solution is more general.
hello @OndrejKunc,
Thanks for your support, your fixes fixed the re-render of the table but still the check box is having the same issue that it is not evaluating the expression
"isVisible": { "expression": "!@hideWelcomeCheckBox && length(@fullNameLabel) > 0" }
also do you have any implementation of file input ?
sorry again for bothering you I'm new to flutter :(
Thanks,
Not bothering at all :) I am just busy lately and sometimes my response takes a long time...
The checkbox expression doesn't work because you are not subscribed to the isVisibleChanged
streams on the children element... This is the fix - just replace the beginning of your StreamBuilder code with this:
return StreamBuilder(
stream: MergeStream(
[
...element.children.map((child) => child.isVisibleChanged),
element.itemsChanged
],
),
That being said I think it doesn't make much sense to let your Multiinsert
component extend container because you need to handle two types of the collections - the children
and items
. I think Multiinsert
should extend just FormElement
and care only about the items
property.
Unfortunately, I don't have any implementation of file input. I believe the implementation is not that difficult, especially if you keep the content of the file in a string variable. I may try to implement it when I have more time.
I'm trying to add a multi insert component
but changes in the model don't update the UI
attached complete example of the code
Thanks,
example.zip