FlutterArtist FormModel.patchFormFields() Ex1
In most Form libraries, data is entered into the Form through user interaction. However, in some situations, the program can update Form Fields automatically.
In FlutterArtist, this is achieved through the Patching mechanism. The key point to remember: this method does not directly modify data at the Backend. Instead, it relies on suggestions from a FormInput object to update new values for FormProp(s) within the FormModel, which are then reflected in the user interface.

Scenario: Demo26a
The main screen of this example is divided into two sections:
- The left panel displays a list of Suppliers.
- The right panel contains a Form that allows the user to create or edit a Supplier.
When the user clicks the “Patch Form Fields” button, several fields in the Form are updated or overwritten with new values provided by a FormInput.
- Download FlutterArtist Demo
2. Supplier26aFormInput
The Supplier26aFormInput class extends the FormInput class. The values of its properties serve as the basis for calculating and updating the values of the FormModel's FormProp(s).
supplier26a_form_input.dart
class Supplier26aFormInput extends FormInput {
String email;
String? supplierTypeCode;
String address;
String phone;
Supplier26aFormInput({
required this.email,
required this.supplierTypeCode,
required this.address,
required this.phone,
});
Supplier26aFormInput.defaultForTest()
: email = "testEmail@example.com",
// DI = Distributors
supplierTypeCode = "DI",
address = "Test Address",
phone = "123456789";
}
Note on Validity
Please pay attention to the MultiOptFormProp("supplierType") seen on the FormView, which has 3 selectable values. Looking at the actual data, there are 3 valid supplierTypeCode(s): ("DI", "MF", "WS").
If your Supplier26aFormInput provides an invalid supplierTypeCode (one that doesn't match the list), FlutterArtist will be unable to calculate the corresponding value to update the MultiOptFormProp("supplierType"). Thus, in this scenario, the values provided by FormInput merely act as a suggestion and will not perform an override if no match is found.
supplierTypes
[
{
"code": "DI",
"id": 2,
"name": "Distributors"
},
{
"code": "MF",
"id": 1,
"name": "Manufacturers"
},
{
"code": "WS",
"id": 3,
"name": "Wholesalers"
}
]No ADS
Note that the Generics parameter - FORM_INPUT - is defined in both the Block and the FormModel.
FormModel |
Block |
Make sure the Generics - FORM_INPUT parameter of Supplier26aFormModel and Supplier26aBlock are the same; otherwise, you will get a red error screen when the application starts.
Supplier26aFormModel | Supplier26aBlock |
3. Supplier26aShelf
supplier26a_shelf.dart
class Supplier26aShelf extends Shelf {
@override
ShelfStructure defineShelfStructure() {
return ShelfStructure(
filterModels: {},
blocks: [
Supplier26aBlock(
name: Supplier26aBlock.blkName,
description: null,
config: BlockConfig(),
filterModelName: null,
formModel: Supplier26aFormModel(),
childBlocks: [],
),
],
);
}
Supplier26aBlock findSupplier26aBlock() {
return findBlock(Supplier26aBlock.blkName) as Supplier26aBlock;
}
}4. Supplier26aFormModel
The properties defined in the FormModel of this example are:
Supplier26aFormModel
class Supplier26aFormModel
extends
FormModel<
int, //
SupplierData,
Supplier26aFormInput,
EmptyFormRelatedData
> {
@override
FormModelStructure defineFormModelStructure() {
return FormModelStructure(
simplePropDefs: [
SimpleFormPropDef<int>(propName: "id"),
SimpleFormPropDef<String>(propName: "name"),
SimpleFormPropDef<String>(propName: "email"),
SimpleFormPropDef<String>(propName: "address"),
SimpleFormPropDef<String>(propName: "phone"),
SimpleFormPropDef<bool>(propName: "active"),
SimpleFormPropDef<String>(propName: "description"),
// List<XFile>
SimpleFormPropDef<dynamic>(propName: "xFiles"),
],
multiOptPropDefs: [
// Multi Option Single Selection Prop.
MultiOptFormPropDef<SupplierTypeInfo>.singleSelection(
propName: 'supplierType',
),
],
);
}
...
}
FormModel.patchFormFields()
When this method is called, the system initiates the process of extracting data from the FormInput to "patch" the form.
patchFormFields (*)
Supplier26aFormModel formModel = block.formModel as Supplier26aFormModel;
// Create a FormInput object:
Supplier26aFormInput formInput = Supplier26aFormInput.defaultForTest();
await formModel.patchFormFields(formInput: formInput);No ADS
FormModel.performLoadMultiOptPropXData()
This is the method for loading actual data for multi-option fields. The rule is: root fields load first, followed by child fields.

performLoadMultiOptPropXData()
@override
Future<XData?> performLoadMultiOptPropXData({
required String multiOptPropName,
required SelectionType selectionType,
required Object? parentMultiOptPropValue,
required Supplier26aFormInput? formInput,
required SupplierData? itemDetail,
required EmptyFormRelatedData formRelatedData,
}) async {
if (multiOptPropName == "supplierType") {
ApiResult<SupplierTypeInfoPage> result = await _supplierTypeProvider
.queryAll();
result.throwIfError();
//
return ListXData<int, SupplierTypeInfo>.fromPageData(
pageData: result.data,
getItemId: (item) => item.id,
);
}
return null;
}FormModel.extractUpdateValueForMultiOptProp()
Based on the value from FormInput (e.g., code "DI"), this method extracts the correct Object (SupplierTypeInfo) from the loaded dataset to update the MultiOptFormProp.

extractUpdateValueForMultiOptProp()
@override
OptValueWrap? extractUpdateValueForMultiOptProp({
required String multiOptPropName,
required SelectionType selectionType,
required XData multiOptPropXData,
required Object? parentMultiOptPropValue,
required Object? parentBlockCurrentItemId,
required Supplier26aFormInput formInput,
required EmptyFormRelatedData formRelatedData,
}) {
if (multiOptPropName == "supplierType") {
var listXData = multiOptPropXData as ListXData<int, SupplierTypeInfo>;
SupplierTypeInfo? supplierType = listXData.data.firstWhereOrNull(
(s) => s.code == formInput.supplierTypeCode,
);
return OptValueWrap.single(supplierType);
}
return null;
}
- FlutterArtist ListXData
FormModel.extractUpdateValuesForSimpleProps()
This method relies on the attribute values of FormInput to extract the values to update the SimpleFormProp(s) of FormModel.

extractUpdateValuesForSimpleProps()
@override
Map<String, SimpleValueWrap?>? extractUpdateValuesForSimpleProps({
required Object? parentBlockCurrentItemId,
required Supplier26aFormInput formInput,
required EmptyFormRelatedData formRelatedData,
}) {
return {
"email": SimpleValueWrap.useIfNotNull(formInput.email),
"address": SimpleValueWrap.useIfNotNull(formInput.address),
"phone": SimpleValueWrap.useIfNotNull(formInput.phone),
};
}No ADS
FlutterArtist
- Basic concepts in Flutter Artist
- FlutterArtist Block ex1
- FlutterArtist Form ex1
- FlutterArtist FormModel.patchFormFields() Ex1
- FlutterArtist BlockQuickItemUpdateAction Ex1
- FlutterArtist BlockQuickMultiItemCreationAction Ex1
- FlutterArtist BackgroundWebDownloadAction ex1
- FlutterArtist Master-detail Blocks ex1
- FlutterArtist Scalar ex1
- FlutterArtist Form Parent-child MultiOptFormProp ex1
- FlutterArtist Context Provider Views
- FlutterArtist Internal Shelf Event ex1
Show More

