jonataslaw / getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
MIT License
10.33k stars 1.62k forks source link

first widget not show veiled message from validation bug #1431

Closed mahesh1071997 closed 3 years ago

mahesh1071997 commented 3 years ago

there is no error but here is show the bug in validation . if user have many text field( minimum 10 to 20 in short user need to scroll for summit button ) then all text field is blanc , use scroll down and click on submit button.

in this case error massage not show starting field(widget) but you see validation only show on screen.

look below screen . i have set validation in first text field.

Screenshot_20210515_174141 Screenshot_20210515_174200

if you click fullname widget then show error.

why not fire validation firs time ??? . ///view

class AddUserView extends GetView { @override Widget build(BuildContext context) { return Form( key: controller.formKey, autovalidateMode: AutovalidateMode.onUserInteraction, child: ListView( shrinkWrap: true, padding: EdgeInsets.all(8.0), children: [ SizedBox( height: 10, ), formField( labelText: 'Full Name', helperText: "Required", onSave: (value) { controller.name = value!; }, validator: controller.fullNameValid, textEditingController: controller.fullNameController), SizedBox( height: 10, ), formField( labelText: 'Email', onSave: (value) { controller.email = value!; }, helperText: 'Required', validator: controller.emailValid, textEditingController: controller.emailController, keyboardType: TextInputType.emailAddress), SizedBox( height: 10, ), formField( labelText: 'Password', helperText: 'Required', validator: controller.passwordValid, textEditingController: controller.passwordController, onSave: (value) { controller.password = value!; }, obscureText: true), SizedBox( height: 10, ), formField( labelText: 'confirm Password', helperText: 'Required', //Confirm Password Required. Password must be 8 char long. textEditingController: controller.confirmPasswordController, validator: controller.passwordValid, onSave: (value) { controller.confirmPassword = value!; }, obscureText: true), SizedBox( height: 10, ), userDropdown( labelText: "User Type", value: controller.userType, helperText: 'Required', validator: controller.userTypeValid, onSave: (value) { controller.userType = value!; }, items: controller.userTypeList), SizedBox( height: 10, ), formField( labelText: 'City', onSave: (value) { controller.city = value!; }, textEditingController: controller.cityController), SizedBox( height: 10, ), formField( labelText: 'Zipcode ', helperText: 'Required', validator: controller.zipCodeValid, onSave: (value) { controller.zipCode = value!; }, textEditingController: controller.zipCodeController, keyboardType: TextInputType.number), SizedBox( height: 10, ), formField( labelText: 'Phone', onSave: (value) { controller.phone = value!; }, textEditingController: controller.phoneController, keyboardType: TextInputType.phone), SizedBox( height: 10, ), OutlinedButton( onPressed: () { controller.checkFrom(); // _formKey.currentState.reset(); }, child: Text('Submit'), ), ], ), ); }

Widget formField( {TextEditingController? textEditingController, String? labelText, TextInputType? keyboardType, Function(String?)? onSave, FormFieldValidator? validator, String? helperText, bool obscureText = false}) => TextFormField( controller: textEditingController, keyboardType: keyboardType, textInputAction: TextInputAction.next, decoration: InputDecoration( labelText: labelText, helperText: helperText, border: OutlineInputBorder( borderSide: BorderSide(color: Colors.teal), ), ), onSaved: onSave, validator: validator, / onFieldSubmitted: (term) { print(term); },/ );

Widget userDropdown( {String? labelText, String? errorText, String? helperText, String? value, Function(String?)? onSave, FormFieldValidator? validator, required List items}) { return DropdownButtonFormField( value: value, icon: Icon(Icons.arrow_drop_down), onChanged: (String? newValue) { value = newValue; }, onSaved: onSave, validator: validator, decoration: InputDecoration( labelText: labelText, helperText: helperText, border: OutlineInputBorder(), ), items: items.map<DropdownMenuItem>((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(), ); } }

//////////////////////////////////////////////////////////

import 'package:car_auction/app/data/models/user_model.dart'; import 'package:car_auction/app/data/providers/api_service_provider.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart';

class UserController extends GetxController with StateMixin<List> { final formKey = GlobalKey();

late TextEditingController fullNameController; late TextEditingController emailController; late TextEditingController passwordController, confirmPasswordController, cityController, zipCodeController, phoneController; late List userTypeList;

var email = ''; var name = ''; var password = ''; var confirmPassword = ''; late String userType; var city = ''; var zipCode = ''; var phone = ''; var age = '';

@override void onInit() { super.onInit(); userList(); userTypeList = [ 'Choose a Usertype', 'Admin', 'Manager', 'Buyer', 'Inspector' ]; userType = userTypeList[0]; fullNameController = TextEditingController(); emailController = TextEditingController(); passwordController = TextEditingController(); confirmPasswordController = TextEditingController(); cityController = TextEditingController(); zipCodeController = TextEditingController(); phoneController = TextEditingController(); }

@override void onReady() { super.onReady(); // getProductList(); }

@override void onClose() { fullNameController.dispose(); emailController.dispose(); passwordController.dispose(); confirmPasswordController.dispose(); cityController.dispose(); zipCodeController.dispose(); phoneController.dispose(); }

String? fullNameValid(String? value) { if (value!.trim().isEmpty) { return 'Full Name Required.'; } return null; }

void checkFrom() { final isValid = formKey.currentState!.validate(); if (!isValid) { Get.rawSnackbar( title: "Warning", message: "Feel Required Value.", icon: Icon( Icons.warning, color: Colors.amber, )); return; } formKey.currentState!.save(); }

String? emailValid(String? emailStr) { if (emailStr!.trim().isEmpty) { return 'Email Required.'; } else if (!emailStr.isEmail) { return "Invalid Email Address"; } return null; }

String? passwordValid(String? value) { if (value!.trim().isEmpty) { return 'Password Required.'; } else if (value.length < 8) { return 'Password must be 8 char long.'; } return null; }

String? userTypeValid(String? value) { if (value == userTypeList[0]) { return 'Please Select User Type.'; } return null; }

String? zipCodeValid(String? value) { if (value!.trim().isEmpty) { return 'Zipcode Required.'; } else if (!value.isNumericOnly) { return 'Zipcode Required.'; } return null; }

void userList() { ApiServiceProvider().fetchUsers().then((resp) { // UserList.value = resp.map((x) => User.fromJson(x)).toList(); change(resp!.map((x) => User.fromJson(x)).toList(), status: RxStatus.success()); }, onError: (err) { change( null, status: RxStatus.error(err.toString()), ); }); } }

mahesh1071997 commented 3 years ago

i have got the solution .

do not use ListView replace by Column (If you need Scroll then use SingleChildScrollView do not use ListView). you Look Like below.

return Form( key: controller.formKey, autovalidateMode: AutovalidateMode.onUserInteraction, child: SingleChildScrollView( padding: EdgeInsets.all(8.0), child: Column( children: [ SizedBox( height: 10, ), formField( labelText: 'Full Name', helperText: "Required", onSave: (value) { controller.name = value!; }, validator: controller.fullNameValid, textEditingController: controller.fullNameController), SizedBox( height: 10, ), formField( labelText: 'Email', onSave: (value) { controller.email = value!; }, helperText: 'Required', validator: controller.emailValid, textEditingController: controller.emailController, keyboardType: TextInputType.emailAddress), SizedBox( height: 10, ), formField( labelText: 'Password', helperText: 'Required', validator: controller.passwordValid, textEditingController: controller.passwordController, onSave: (value) { controller.password = value!; }, obscureText: true), SizedBox( height: 10, ), formField( labelText: 'confirm Password', helperText: 'Required', //Confirm Password Required. Password must be 8 char long. textEditingController: controller.confirmPasswordController, validator: controller.passwordValid, onSave: (value) { controller.confirmPassword = value!; }, obscureText: true), SizedBox( height: 10, ), userDropdown( labelText: "User Type", value: controller.userType, helperText: 'Required', validator: controller.userTypeValid, onSave: (value) { controller.userType = value!; }, items: controller.userTypeList), SizedBox( height: 10, ), formField( labelText: 'City', onSave: (value) { controller.city = value!; }, textEditingController: controller.cityController), SizedBox( height: 10, ), formField( labelText: 'Zipcode ', helperText: 'Required', validator: controller.zipCodeValid, onSave: (value) { controller.zipCode = value!; }, textEditingController: controller.zipCodeController, keyboardType: TextInputType.number), SizedBox( height: 10, ), formField( labelText: 'Phone', onSave: (value) { controller.phone = value!; }, textEditingController: controller.phoneController, keyboardType: TextInputType.phone), SizedBox( height: 10, ), OutlinedButton( onPressed: () { controller.checkFrom(); // _formKey.currentState.reset(); }, child: Text('Submit'), ), ], ), ), );

why is working i Don't know ? but is working fine.