nui_form 1.0.1 nui_form: ^1.0.1 copied to clipboard
A new Flutter package for form
IForm
is part of the Flutter SDK that allows you to create a form with a list of supported form components such as Input Text
, Drop Down
and more with validation feature provided for form validation. IForm
is built on top of NUIForm
and it act as the decoder before passing the readable form configuration to NUIForm
.
-
Validation Rules - Programmers can configure the validation for each form component such as the min/max length as well as the string expression of a form field.
-
Customizable - The form is fully customizable from the arrangement and alignment of the form components to the colors of the borders and text.
Rendering The Form from JSON Configuration #
As IForm
is mainly to decode the form configuration JSON and process them into a readable set of form configuration for NUIForm
, programmer can initialize the form with IFRenderEngineBuilder
.
IFRenderEngine renderer = IFRenderEngineBuilder()
.boyJson(yourJson)
.textStyle(yourCustomizedTextStyle)
.build();
Once you successfully parse the JSON to the IFRenderEngine
, you can render the NUIForm
through the renderForm()
method with a set of optional listeners such as textChangeListener
, buttonClickListener
and itemSelectListener
.
final form = renderer.renderForm(
textChangeListener: (id, value, form){
//TODO: text of a form component has changed
},
buttonClickListener: (id, clickType, form){
//TODO: a button component has been clicked
},
itemSelectListener: (id, selection, selected, form){
//TODO an item has been selected from drop down or check box
}
);
With the NUIForm
instance in place, you can now render the form as a widget by passing the form
to a NUIFormContent
widget.
return Container(
child: NUIFormContent(form: form)
);
NUIForm
Components #
The list of supported NUIForm
components can be found from http://dev.g-i.com.my/istudio/docs/dynamic-form/components/. Sample of a complete json can be found from http://dev.g-i.com.my/istudio/docs/dynamic-form/sample-json/.
Available Methods for NUIForm
#
Method | Remark |
---|---|
fillInValues() |
Fill in values for the components in the form |
validate() |
Validate the form either quietly (without showing the error in UI) or normal validate |
updateItem() |
Update any form component such as visibility or any other properties |
Fill In Form Values #
Programmers can fill in values into the form. As each form component's unique is the inpId
, filling in values require the programmer to specify which form component to be updated.
form.fillInValues({
"edtCountry": NUIFormValue(
inpId: "edtCountry",
value: NUIFromSelection(
value: "Malaysia"
)
),
"edtState": NUIFormValue(
inpId: "edtState",
value: NUIFormSelection(
value: "Selangor"
)
)
});
Validate the Form #
Part of the configuration for the form is to have a validation rule for each of the form component, to configure whether the component is compulsory, or is there a length limitation on the form component. Once these validation rules are configured, calling the validate()
from NUIForm
will validate the form based on these validations and return a result of success if all the validations are successful or failed if one of the validation failed.
final validated = form.validate();
Update a Form Component #
Programmers can update any of the form component after the form is rendered, such as changing the title of an input text or any other properties of the form component based on the component type. Below is an example of updating a NUIFTextItem
component.
final updateItem = form.updateItem<NUIFTextItem>("edtCountry", (item){
item.hint = "What are you from?";
item.helperText = "Please fill this in";
});
A sample of NUIForm
#
//Defining your form styles
NUIFTextStyle myFontStyle(BuildContext context) => NUIFTextStyle(
labelStyle: getFont(context, size: 16, color: accentBright, isBold: false),
helperStyle: getFont(context, size: 12, color: accentBright, isBold: false),
errorHelperStyle: getFont(context, size: 12, color: formErrorRed, isBold: false),
border: OutlineInputBorder(borderSide: BorderSide(color: getColor(context, textGray), width: 1)),
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: getColor(context, accentBright), width: 2)),
errorBorder: OutlineInputBorder(borderSide: BorderSide(color: getColor(context, formErrorRed), width: 1)),
errorFocusedBorder: OutlineInputBorder(borderSide: BorderSide(color: getColor(context, formErrorRed), width: 2)),
design: NUIFTextDesign.BORDER,
dense: true,
cursor: NUIFTextCursor(color: getColor(context, accentBright), cursorWidth: 2),
textStyle: getFont(context, size: 16, color: textDarkGray, isBold: false),
hintStyle: getFont(context, size: 16, singleColor: getColor(context, textLightGray), isBold: false),
);
//Using the form as your widget
class YourFormContent extends StatefulWidget {
@override
_YourFormContentState createState() => _YourFormContentState();
}
class _YourFormContentState extends State<YourFormContent> {
NUIForm form;
@override
void initState(){
super.initState();
//Always initialize your form in initState() and not in the build() method as you do not want your form to get refreshed everytime the widget is rebuilt
form = NUIForm(
allButtonClickListener: (inpId, clickType, form){
},
allTextChangeListener: (inpId, value, form){
},
allItemSelectListener: (inpId, selection, selected, form){
},
item: NUIFColumnItem(inpId: "lytMyProfile", divider: 20, items: [
NUIFTextItem(
controller: TextEditingController(text: ""),
inpId: "edtName",
label: getString('formProfileNameLabel'),
maskedInputType: NUIFTextInputType.NAME,
minLength: 5,
style: myFontStyle(context),
),
NUIFTextItem(
controller: TextEditingController(text: ""),
inpId: "edtDateofBirth",
hint: "Date of birth",
label: getString('formProfileDateofBirthLabel'),
style: myFontStyle(context),
validateOnChange: true,
maskedInputType: NUIFTextInputType.DATE,
suffixIcon:
Icon(Icons.event_note, color: getColor(context, accentBright)),
),
NUIFDropdownItem(
inpId: "spnGender",
selections: [GenderSelection("Male"), GenderSelection("Female")],
label: "Gender",
style: myFontStyle(context),
),
])
);
}
void extractFormValues(){
Map<String, NUIFormValue> values = form.extractValues();
final name = values["edtName"].value.value; //This is your name input from the form
}
@override
Widget build(BuildContext context) {
return Container(
child: NUIFormContent(
form: form,
),
);
}
}
A sample of NUIForm
from a JSON
configuration #
A sample of JSON form configuration would be like below. The properties of the form component are configured in the JSON configuration itself such as the id, caption and more.
{
"jsLogic": "",
"inputVerticalSpacing": 10,
"inputs": [
{
"inpId": "txtAft",
"caption": "Aft (m)",
"compulsory": true,
"show": true,
"validateErrMsg": "Please enter a Aft value",
"layout": 2,
"intLayout": null,
"preferredWidth": null,
"type": "IngSinglelineText",
"inputAllowType" : 1005,
"inputAllowRegularExpression": "any",
"rightSpacing": 10,
"topSpacing": null
},
{
"inpId": "txtFore",
"caption": "Fore (m)",
"compulsory": true,
"show": true,
"validateErrMsg": "Please enter a Fore value",
"layout": 2,
"intLayout": null,
"preferredWidth": null,
"type": "IngSinglelineText",
"inputAllowType" : 1005,
"inputAllowRegularExpression": "any",
"rightSpacing": 10,
"topSpacing": null
},
{
"inpId": "txtTrim",
"caption": "Trim (m)",
"compulsory": true,
"show": true,
"readOnly": true,
"validateErrMsg": "Please enter a Trim value",
"layout": 2,
"intLayout": null,
"preferredWidth": null,
"type": "IngSinglelineText",
"inputAllowType" : 1005,
"inputAllowRegularExpression": "any",
"rightSpacing": 10,
"topSpacing": null
},
{
"inpId": "txtDate",
"caption": "Date",
"compulsory": true,
"show": true,
"validateErrMsg": "Please enter a Date value",
"layout": 3,
"intLayout": null,
"preferredWidth": null,
"type": "IngDatePicker",
"dateTimeDisplayFormat": "dd MMM yyyy",
"rightSpacing": null,
"topSpacing": null
}
]
}
After you have configured your form in the JSON, you can then later decode the JSON configuration into a NUIForm
instance using the IFRenderEngineBuilder
.
class YourFormContent extends StatefulWidget {
@override
_YourFormContentState createState() => _YourFormContentState();
}
class _YourFormContentState extends State<YourFormContent> {
NUIForm form;
IFRenderEngine renderer;
@override
void initState(){
super.initState();
renderer = IFRenderEngineBuilder()
.bodyJson(yourJSONConfig)
.textStyle(myFontStyle(context))
.build();
form = renderer.renderForm(
buttonClickListener: (inpId, clickType, form){
},
textChangeListener: (inpId, value, form){
},
itemSelectListener: (inpId, selection, selected, form){
}
);
}
void extractFormValues(){
Map<String, NUIFormValue> values = form.extractValues();
final aftValue = values["txtAft"].value.value; //This is your name input from the form
}
@override
Widget build(BuildContext context) {
return Container(
child: NUIFormContent(
form: form,
),
);
}
}