Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 26, 2021 11:29 pm GMT

100DaysOfCodeChallenge -Crop Management Information System- Day 3

Recap

On Day 2 I created the FarmerServce() class that is responsible for making network calls to Firebase Auth Farmer collection and documents. I also created the AddFarmerCommand() class that is responsible for passing an instance of the FarmerServiceModel() to FarmerService().

Overview

Today I created the Farmer registration form. This form will accept user input than will create an instance of the FarmerServiceModel() that will be stored in cloud firestore.

Building this form exposed weaknesses in my understanding for Flutter layout and using dart late variable.

Add Farmer Form

Below is a screenshot of the form design followed by the code.
Farmer Form

NB: 436 lines of code

class AddFarmerPage extends StatefulWidget {  static String routeName = 'AddFarmerPage';  const AddFarmerPage({    Key? key,  }) : super(key: key);  @override  _AddFarmerPageController createState() => _AddFarmerPageController();}class _AddFarmerPageController extends State<AddFarmerPage> {  @override  Widget build(BuildContext context) => _AddFarmerPageView(this);  FarmerServiceModel farmer = FarmerServiceModel.form();  final GlobalKey<FormState> _formkey = GlobalKey<FormState>();  bool _formChanged = false;  late FocusNode registrationNumberFocusNode;  late FocusNode nationalIdFocusNode;  late FocusNode profilePictureFocusNode;  late FocusNode firstNameFocusNode;  late FocusNode lastNameFocusNode;  late FocusNode nicknameFocusNode;  late FocusNode dateOfBirthFocusNode;  late FocusNode genderFocusNode;  late FocusNode ethnicityFocusNode;  late FocusNode maritalStatusFocusNode;  late FocusNode addressFocusNode;  late FocusNode isHeadOfHouseholdFocusNode;  late FocusNode isFarmingPrimaryIncomeSourceFocusNode;  late FocusNode isActiveFarmerFocusNode;  late FocusNode farmerCategoryFocusNode;  late FocusNode subsectorFocusNode;  late FocusNode operationScaleFocusNode;  @override  void initState() {    super.initState();    registrationNumberFocusNode = FocusNode();    nationalIdFocusNode = FocusNode();    profilePictureFocusNode = FocusNode();    firstNameFocusNode = FocusNode();    lastNameFocusNode = FocusNode();    nicknameFocusNode = FocusNode();    dateOfBirthFocusNode = FocusNode();    genderFocusNode = FocusNode();    ethnicityFocusNode = FocusNode();    maritalStatusFocusNode = FocusNode();    addressFocusNode = FocusNode();    isHeadOfHouseholdFocusNode = FocusNode();    isFarmingPrimaryIncomeSourceFocusNode = FocusNode();    isActiveFarmerFocusNode = FocusNode();    farmerCategoryFocusNode = FocusNode();    subsectorFocusNode = FocusNode();    operationScaleFocusNode = FocusNode();  }  @override  void dispose() {    super.dispose();    registrationNumberFocusNode.dispose();    nationalIdFocusNode.dispose();    profilePictureFocusNode.dispose();    firstNameFocusNode.dispose();    lastNameFocusNode.dispose();    nicknameFocusNode.dispose();    dateOfBirthFocusNode.dispose();    genderFocusNode.dispose();    ethnicityFocusNode.dispose();    maritalStatusFocusNode.dispose();    addressFocusNode.dispose();    isHeadOfHouseholdFocusNode.dispose();    isFarmingPrimaryIncomeSourceFocusNode.dispose();    isActiveFarmerFocusNode.dispose();    farmerCategoryFocusNode.dispose();    subsectorFocusNode.dispose();    operationScaleFocusNode.dispose();  }  //FORM LEVEL METHODS  void _hanldeOnFormChanged() {    if (_formChanged) return;    setState(() {      _formChanged = true;    });  }  void _handleRegisterFarmer() async {    if (_formkey.currentState!.validate()) {      _formkey.currentState!.save();      // todo: create register farmer command    }  }  void _handleDropdownOnChanged(String? value) {}  String _date = '';  void _showDatePicker() {    showDatePicker(      context: context,      initialDate: DateTime.now(),      firstDate: DateTime(1900),      lastDate: DateTime.now(),    ).then((value) {      if (value != null) {        setState(() {          // farmer.saveDateOfBirth(value);          // print(farmer.dateOfBirth);          print(value.toString());          _date = value.toString();          // print(_date);        });      }    });  }}class _AddFarmerPageView    extends WidgetView<AddFarmerPage, _AddFarmerPageController> {  final state;  const _AddFarmerPageView(this.state) : super(state);  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('Add Farmer'),      ),      body: Padding(        padding: const EdgeInsets.all(24.0),        child: Form(            key: state._formkey,            onChanged: state._hanldeOnFormChanged,            child: Column(              mainAxisAlignment: MainAxisAlignment.spaceEvenly,              children: [                Padding(                  padding: const EdgeInsets.only(bottom: 24.0),                  child: Center(                    child: Text(                      'Farmer Registration Form',                      style: TextStyles.title.bold,                    ),                  ),                ),                Expanded(                  child: ListView(children: [                    Row(                      mainAxisAlignment: MainAxisAlignment.spaceAround,                      children: [                        // Registration Number                        Expanded(                          child: TextFormField(                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Registration Number'),                            focusNode: state.registrationNumberFocusNode,                            textInputAction: TextInputAction.next,                            keyboardType: TextInputType.visiblePassword,                            autovalidateMode:                                AutovalidateMode.onUserInteraction,                            validator: state.farmer.validateRegistrationNumber,                            onSaved: state.farmer.saveRegistrationNumber,                          ),                        ),                        SizedBox(                          width: 20.0,                        ),                        // National ID Number                        Expanded(                          child: TextFormField(                            decoration: FormStyles.textFieldDecoration(                                labelText: 'National ID Number'),                            focusNode: state.nationalIdFocusNode,                            textInputAction: TextInputAction.next,                            autovalidateMode:                                AutovalidateMode.onUserInteraction,                            validator: state.farmer.validateNationalId,                            onSaved: state.farmer.saveNationalId,                          ),                        )                      ],                    ),                    Row(                      children: [                        Expanded(                          child: Column(                            // mainAxisSize: MainAxisSize.min,                            crossAxisAlignment: CrossAxisAlignment.stretch,                            children: [                              SizedBox(                                height: 300,                                width: 300,                                child: Container(                                  color: Colors.blue,                                ),                              ),                              ElevatedButton.icon(                                  onPressed: () {},                                  icon: Icon(Icons.camera_alt_outlined),                                  label: Text('Take Picture')),                            ],                          ),                        ),                        SizedBox(width: 30.0),                        Expanded(                          child: Column(children: [                            // FIRST NAME                            TextFormField(                              decoration: FormStyles.textFieldDecoration(                                  labelText: 'First Name'),                              focusNode: state.firstNameFocusNode,                              textInputAction: TextInputAction.next,                              autovalidateMode:                                  AutovalidateMode.onUserInteraction,                              validator: state.farmer.validateFirstName,                              onSaved: state.farmer.saveFirstName,                            ),                            // NICKNAME                            TextFormField(                              decoration: FormStyles.textFieldDecoration(                                  labelText: 'Nickname'),                              focusNode: state.nicknameFocusNode,                              textInputAction: TextInputAction.next,                              autovalidateMode:                                  AutovalidateMode.onUserInteraction,                              validator: state.farmer.validateNickname,                              onSaved: state.farmer.saveNickname,                            ),                            // LAST NAME                            TextFormField(                              decoration: FormStyles.textFieldDecoration(                                  labelText: 'Last Name'),                              focusNode: state.lastNameFocusNode,                              textInputAction: TextInputAction.next,                              autovalidateMode:                                  AutovalidateMode.onUserInteraction,                              validator: state.farmer.validateLastName,                              onSaved: state.farmer.saveLastName,                            ),                          ]),                        )                      ],                    ),                    SizedBox(                      height: 15,                    ),                    Row(                      children: [                        Expanded(                          child: TextFormField(                            readOnly: true,                            focusNode: state.dateOfBirthFocusNode,                            decoration: InputDecoration(                                border: OutlineInputBorder(),                                labelText: 'Date of Birth',                                hintText: state._date,                                suffixIcon: GestureDetector(                                  child: Icon(Icons.calendar_today_outlined),                                  onTap: state._showDatePicker,                                )),                          ),                        ),                        SizedBox(width: 30.0),                        Expanded(                          child: DropdownButtonFormField(                            focusNode: state.genderFocusNode,                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Gender'),                            value: Gender.all[1],                            onChanged: state._handleDropdownOnChanged,                            onSaved: state.farmer.saveGender,                            items: Gender.all                                .map((e) => DropdownMenuItem(                                      child: Text(e),                                      value: e,                                    ))                                .toList(),                          ),                        ),                        SizedBox(width: 30.0),                        Expanded(                          child: DropdownButtonFormField(                            focusNode: state.ethnicityFocusNode,                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Ethnicity'),                            onChanged: state._handleDropdownOnChanged,                            onSaved: state.farmer.saveGender,                            items: Ethnicity.all                                .map((e) => DropdownMenuItem(                                      child: Text(e),                                      value: e,                                    ))                                .toList(),                          ),                        ),                        SizedBox(width: 30.0),                        Expanded(                          child: DropdownButtonFormField(                            focusNode: state.maritalStatusFocusNode,                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Marital Status'),                            onChanged: state._handleDropdownOnChanged,                            onSaved: state.farmer.saveGender,                            items: MaritalStatus.all                                .map((e) => DropdownMenuItem(                                      child: Text(e),                                      value: e,                                    ))                                .toList(),                          ),                        ),                      ],                    ),                    TextFormField(                      focusNode: state.addressFocusNode,                      decoration:                          FormStyles.textFieldDecoration(labelText: 'Address'),                      textInputAction: TextInputAction.next,                      autovalidateMode: AutovalidateMode.onUserInteraction,                      validator: state.farmer.validateAddress,                      onSaved: state.farmer.saveAddress,                      maxLines: 5,                      minLines: 2,                    ),                    Row(                      children: [                        // FARMER CATEGORY                        Expanded(                          child: DropdownButtonFormField(                            focusNode: state.farmerCategoryFocusNode,                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Farmer Category'),                            onChanged: state._handleDropdownOnChanged,                            onSaved: state.farmer.saveFarmerCategory,                            items: FarmerCategory.all                                .map((e) => DropdownMenuItem(                                      child: Text(e),                                      value: e,                                    ))                                .toList(),                          ),                        ),                        SizedBox(width: 30.0),                        // SUBSECTOR                        Expanded(                          child: DropdownButtonFormField(                            focusNode: state.subsectorFocusNode,                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Subsector'),                            onChanged: state._handleDropdownOnChanged,                            onSaved: state.farmer.saveSubsector,                            items: Subsector.all                                .map((e) => DropdownMenuItem(                                      child: Text(e),                                      value: e,                                    ))                                .toList(),                          ),                        ),                        SizedBox(width: 30.0),                        // OPERATION SCALE                        Expanded(                          child: DropdownButtonFormField(                            focusNode: state.operationScaleFocusNode,                            decoration: FormStyles.textFieldDecoration(                                labelText: 'Operation Scale'),                            onChanged: state._handleDropdownOnChanged,                            onSaved: state.farmer.saveOperationScale,                            items: OperationScale.all                                .map((e) => DropdownMenuItem(                                      child: Text(e),                                      value: e,                                    ))                                .toList(),                          ),                        ),                      ],                    ),                    SizedBox(                      height: 15,                    ),                    Row(                      children: [                        Expanded(                          child: FormField(builder: (builder) {                            return CheckboxListTile(                                title: Text('Head of Household'),                                value: false,                                onChanged: (bool) {});                          }),                        ),                        Expanded(                          child: FormField(builder: (builder) {                            return CheckboxListTile(                                title: Text('Farming Primary Income Source'),                                value: false,                                onChanged: (bool) {});                          }),                        ),                        Expanded(                          child: FormField(builder: (builder) {                            return CheckboxListTile(                                title: Text('Active Farmer'),                                value: true,                                onChanged: (bool) {});                          }),                        ),                      ],                    ),                    SizedBox(                      height: 15,                    ),                    ElevatedButton(                        onPressed: () {}, child: Text('Register Farmer'))                  ]),                )              ],            )),      ),    );  }}

This code need to be refactored to improve readability and maintainability. I will refactor this code in a future post.

Building this form made me realize the need to better understand how Layout and constraints in flutter works. We will build our capacity in this area in a future post as well.

Wrap up

On Day 3, I built the Farmer Form but more importantly I realized the need to improve my knowledge of flutter layout and constraints.

Coming to flutter from a Django background made we realize the need of a dart package that automate the creation of forms from dart Models. This is a beautiful problem that I hope to solve in the future.

Connect with me

Thank you for reading my post. Feel free to subscribe below to join me on the #100DaysOfCodeChallenge or connect with me on LinkedIn and Twitter.


Original Link: https://dev.to/curtlycritchlow/100daysofcodechallenge-crop-management-information-system-day-3-5b45

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To