I'm trying to validate two different TextFormFields in two widgets (One for Email, another one for password) with a single _formkey in a flutter. it gave me this error: Multiple widgets used the same GlobalKey. So defined two _formkey but the problem is Flutter form validators don't validate, simultaneously:
class _RegisterState extends State<Register> {
String email = "";
String password = "";
String error = "";
final _formKey1 = GlobalKey<FormState>();
final _formKey2 = GlobalKey<FormState>();
// bool _rememberMe = false;
Widget _buildEmailTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Email',
style: kLabelStyle,
),
SizedBox(height: 10.0),
Form(
key: _formKey1,
child: Container(
alignment: Alignment.centerLeft,
decoration: kBoxDecorationStyle,
height: 60.0,
child: TextFormField(
validator: (value) => value.isEmpty ? "Enter an Email" : null,
onChanged: (value) {
setState(() {
email = value;
});
},
style: TextStyle(
color: Colors.white,
fontFamily: 'OpenSans',
),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.email,
color: Colors.white,
),
hintText: 'Enter your Email',
hintStyle: kHintTextStyle,
),
),
),
),
],
);
}
Widget _buildPasswordTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Password',
style: kLabelStyle,
),
SizedBox(height: 10.0),
Form(
key: _formKey2,
child: Container(
alignment: Alignment.centerLeft,
decoration: kBoxDecorationStyle,
height: 60.0,
child: TextFormField(
validator: (value) =>
value.length < 6 ? "More than 6 Character" : null,
onChanged: (value) {
setState(() {
password = value;
});
},
obscureText: true,
style: TextStyle(
color: Colors.white,
fontFamily: 'OpenSans',
),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.lock,
color: Colors.white,
),
hintText: 'Enter your Password',
hintStyle: kHintTextStyle,
),
),
),
),
],
);
}
and then :
onPressed: () async {
if (_formKey1.currentState.validate() &&
_formKey2.currentState.validate()) {
dynamic result =
await _auth.signUpWithEmailandPassword(email, password);
if (result == null) {
setState(() => error = "Something is wrong");
}
}
},
Just remember that you need one Form Widget above in the widget Tree.
And thus you can use the _formKey to validate multiple TextFormField below in the Widget Tree.
Modified Code
class _RegisterPageState extends State<RegisterPage> {
String email = "";
String password = "";
String error = "";
final _formKey1 = GlobalKey<FormState>();
// final _formKey2 = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Form(
key: _formKey1,
child: Container(
child: Column(
children: [
_buildEmailTF(),
SizedBox(
height: 20,
),
_buildPasswordTF(),
FlatButton(
onPressed: () async {
if (_formKey1.currentState.validate()) {
// dynamic result = await _auth.signUpWithEmailandPassword(
// email, password);
// if (result == null) {
// setState(() => error = "Something is wrong");
// }
print('DOne Working');
}
},
child: Text(
'Done',
))
],
),
),
),
);
}
// bool _rememberMe = false;
Widget _buildEmailTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Email',
),
SizedBox(height: 10.0),
Container(
alignment: Alignment.centerLeft,
height: 60.0,
child: TextFormField(
validator: (value) => value.isEmpty ? "Enter an Email" : null,
onChanged: (value) {
setState(() {
email = value;
});
},
style: TextStyle(
color: Colors.white,
fontFamily: 'OpenSans',
),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.email,
color: Colors.white,
),
hintText: 'Enter your Email',
),
),
),
],
);
}
Widget _buildPasswordTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Password',
),
SizedBox(height: 10.0),
Container(
alignment: Alignment.centerLeft,
height: 60.0,
child: TextFormField(
validator: (value) =>
value.length < 6 ? "More than 6 Character" : null,
onChanged: (value) {
setState(() {
password = value;
});
},
obscureText: true,
style: TextStyle(
color: Colors.white,
fontFamily: 'OpenSans',
),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.lock,
color: Colors.white,
),
hintText: 'Enter your Password',
),
),
),
],
);
}
}
I/flutter (24750): DOne Working
Related
Still a newbie with flutter and was wondering if someone could help me with a problem I'm having. I am trying to create a registeration form with email, password, password confirmation, a county and a zip code. (County and zip code forms are the drop down button form fields) I have successfully coded all else except for the zip code drop down. I would need it to be conditional on the county selection. (In a way that if I select a specific county in cali, it would only display that selected county's zip codes and nothing else). Also if someone would know a quick fix to make the dropdown button form fields empty unless clicked on. My current adaptation on it isn't very functional, since you can just leave the option unanswered, when it's supposed to be mandatory. Thank you in advance :)
Existing code below
(I only have the string for one county zip codes) (Also deleted the irrelevant firebase related code for this post)
class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);
#override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
// dropdown area
_MyFormStateArea(){
selectedArea = dropdownListArea[0];
}
var selectedArea = '';
final dropdownListArea = <String>['', 'LA', 'San Francisco'...'Santa Barbara'];
// dropdown zipcode
_MyFormStateZip(){
selectedZip = dropdownListZip[0];
}
var selectedZip = '';
final dropdownListZip = <String>['', '90001', '90002', '90003',..., '91609'];
// editing Controller
final emailEditingController = new TextEditingController();
final passwordEditingController = new TextEditingController();
final confirmPasswordEditingController = new TextEditingController();
#override
Widget build(BuildContext context) {
// email field
final emailField = TextFormField(
autofocus: false,
controller: emailEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Please enter email.");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please enter a working email.");
}
return null;
},
onSaved: (value) {
emailEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail_outline_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// password field
final passwordField = TextFormField(
autofocus: false,
controller: passwordEditingController,
obscureText: true,
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("A password required.");
}
if(!regex.hasMatch(value)) {
return ("Please enter other password (Min. 6 characters)");
}
},
onSaved: (value) {
passwordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
));
// confirm password field
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordEditingController,
obscureText: true,
validator: (value)
{
if(confirmPasswordEditingController.text != passwordEditingController.text)
{
return "Passwords don't match";
}
return null;
},
onSaved: (value) {
confirmPasswordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password again",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// area dropdown
final areaField = DropdownButtonFormField(
value: selectedArea,
items: dropdownListArea.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: dropdownListZip.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// sign up button
final signUpButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.white,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signUp(emailEditingController.text, passwordEditingController.text);
},
child: Text("Sign Up", textAlign: TextAlign.center,
style: TextStyle(fontSize: 20,
color: Colors.lightBlue[900],
fontWeight: FontWeight.bold)
),
),
);
return Scaffold(
backgroundColor: Color(0xFFAED8E6),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => FrontPage()));
},
icon: Icon(Icons.arrow_back),
color: Colors.lightBlue[900],
),
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Color(0xFFAED8E6),
child: Padding(
padding: const EdgeInsets.fromLTRB(36, 20, 36, 30),
child: Form(
key: _formKey,
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 170,
child: Image.asset("assets/AR_logoBold.png",
fit: BoxFit.contain
)),
SizedBox(height: 40,),
emailField,
SizedBox(height: 25,),
passwordField,
SizedBox(height: 25,),
confirmPasswordField,
SizedBox(height: 25,),
areaField,
SizedBox(height: 25,),
zipCodeField,
SizedBox(height: 35,),
signUpButton,
SizedBox(height: 15,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("You already own an account? "),
GestureDetector(onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Text("Login",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.lightBlue[900])
),)
],
)
],
)),
),
),
),
),
);
}
}
First you should initalize the selectedArea and selectedZip with the first Entry of your List: = dropdownListZip.first and the first entry should not be an empty String
To get only zips that belong to the choosen area you need to know them. At the moment you have two independent lists.
Better you use a map like:
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
Than you can only display zips that belong to the area quite easy.
Take a look at: Flutter Documentation for Map
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
final areaField = DropdownButtonFormField(
value: selectedArea,
items: zipmap.keys.toList().map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: zipmap[selectedArea].map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
Hi in the below code when I enter my mobile number, password and then click on the login button nothing is happening. My API working in Postman is not working here.
When I press the button it is not working, Entering a valid mobile number and password are not working.
Can anyone help me to find where I did any mistakes?
Login_screen.dart:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:sample_live/home_screen.dart';
import 'package:sample_live/model/login_model.dart';
import 'package:sample_live/splash_screen.dart';
import 'package:sample_live/login_otp.dart';
import 'ProgressHUD.dart';
import 'api/api_service.dart';
class LoginScreen extends StatefulWidget {
String name;
LoginScreen({this.name});
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final mobileController = TextEditingController();
final passwordController = TextEditingController();
LoginRequestModel requestModel;
bool isApiCallProcess = false;
GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();
LoginRequestModel loginRequestModel;
final scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState(){
super.initState();
requestModel=new LoginRequestModel();
}
#override
Widget build(BuildContext context) {
return ProgressHUD(
child: _uiSetup(context),
inAsyncCall: isApiCallProcess,
opacity: 0.3,
);
}
Widget _uiSetup(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Login", style: TextStyle(color: Colors.white)),
centerTitle: true,
),
body:
Stack(
children: [
Padding(
padding: EdgeInsets.all(30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/hand.png',),
Padding(
padding: EdgeInsets.all(10),
child: Text("Welcome Doctor! ",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold
),),
),
Padding(
padding: EdgeInsets.all(10),
),
Text("Let's treat everyone great",
style: TextStyle(
color: Colors.black,
fontSize: 15,
),),
Padding(
padding: EdgeInsets.all(10),
),
TextFormField(
minLines: 1,
keyboardType: TextInputType.number,
onSaved: (input) => loginRequestModel.Mobile = input,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: "Enter Mobile No.",
hintText: "Enter Mobile No.",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0)))),
),
SizedBox(
height: 10,
),
TextFormField(
onSaved: (input) =>
loginRequestModel.Password = input,
validator: (input) =>
input.length < 3
? "Password should be more than 3 characters"
: null,
minLines: 1,
obscureText: true,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: "Password",
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0)))),
),
SizedBox(
height: 10,
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
margin: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30)
),
child: RaisedButton(
color: Color(0xFF0769AA),
onPressed: () {
if (validateAndSave()) {
print(loginRequestModel.toJson());
setState(() {
isApiCallProcess = true;
});
APIService apiService = new APIService();
apiService.login(loginRequestModel).then((value) {
if (value != null) {
setState(() {
isApiCallProcess = false;
});
if (value.Status.isNotEmpty) {
final snackBar = SnackBar(
content: Text("Login Successful"));
scaffoldKey.currentState
.showSnackBar(snackBar);
} else {
final snackBar =
SnackBar(content: Text(value.Message));
scaffoldKey.currentState
// ignore: deprecated_member_use
.showSnackBar(snackBar);
}
}
});
}
},
child: Text(
"Login",
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(
height: 10,
),
Text("Or",
style: TextStyle(
color: Colors.black,
fontSize: 15,
),),
Container(
width: double.infinity,
child: FlatButton(
color: Color(0xFF0769AA),
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => LoginOtp("Welcome")),
(route) => false);
},
child: Text(
"Login With OTP",
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
// write your function
Navigator.push(
context,
MaterialPageRoute(
builder: (contex) => SplashScreen()));
},
child: Text(
"Forgot Password",
style: TextStyle(
color: Colors.blue,
fontSize: 16,
fontWeight: FontWeight.bold,
)
)),
],
),
],
),
),
Container(
alignment: Alignment.bottomCenter,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"By logging in or signing up, you agree to the",
textAlign: TextAlign.end,
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
Text(
"Privacy Policy & Terms and Condition",
textAlign: TextAlign.end,
style: TextStyle(
color: Colors.blue,
fontSize: 12,
),
),
],
)
)
]),
);
}
bool validateAndSave() {
final form = globalFormKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
}
I want to validate the passwords. The Widget _buildRepeatPasswordTF, has a TextFormField that validates if the value is not equal to the controller from _buildPasswordTF().
Widget _buildPasswordTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: < Widget > [
Container(
alignment: Alignment.centerLeft,
decoration: kBoxDecorationStyle,
height: 60.0,
child: TextField(
controller: _passwordController,
obscureText: true,
style: TextStyle(
color: Color.fromRGBO(0, 128, 128, 1),
fontFamily: 'OpenSans',
),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.lock,
color: Color.fromRGBO(0, 128, 128, 1),
),
hintText: 'Password',
hintStyle: kHintTextStyle,
),
),
),
],
);
}
Widget _buildRepeatPasswordTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
decoration: kBoxDecorationStyle,
height: 60.0,
child: TextFormField(
controller: _repeatPasswordController,
obscureText: true,
style: TextStyle(
color: Color.fromRGBO(0, 128, 128, 1),
fontFamily: 'OpenSans',
),
validator: (value) {
if (value != _passwordController.text) {
return 'The password doesnt match';
}
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(
Icons.lock,
color: Color.fromRGBO(0, 128, 128, 1),
),
hintText: 'Repeat password',
hintStyle: kHintTextStyle,
),
),
),
],
);
}
Widget _buildSignUpBtn() {
return Container(
padding: EdgeInsets.symmetric(vertical: 25.0),
width: double.infinity,
child: RaisedButton(
elevation: 5.0,
onPressed: () async {
var password = _passwordController.text;
var email = _emailController.text;
var nom = _nameController.text;
var cognoms = _cognomsController.text;
try {
var r = await _provider.attemptSignUp(email, password, nom, cognoms, interessos, sexe, dataNeixement);
if(r['success'] == false) {
displayDialog(context, "Error", r['data']['message']);
}
else {
displayDialog(context, "Registrat", "Verifica el correu.").then((val) {
Navigator.of(context).pop();
});
}
} catch (err) {
displayDialog(context, "Error", err.response.toString());
}
},
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Color.fromRGBO(0, 128, 128, 1),
child: Text(
'Registrar-se',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'OpenSans',
),
),
),
);
}
You have missed a main Form and GlobalKeys.
Here a complete functional sample:
import 'package:flutter/material.dart';
class Password extends StatefulWidget {
#override
_PasswordState createState() => _PasswordState();
}
class _PasswordState extends State<Password> {
final TextEditingController _password = TextEditingController();
final TextEditingController _confirmPassword = TextEditingController();
final GlobalKey<FormState> _form = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(30),
child: Form(
key: _form,
child: Column(children: <Widget>[
TextFormField(
controller: _password,
validator: (validator) {
if (validator.isEmpty) return 'Empty';
return null;
}),
TextFormField(
controller: _confirmPassword,
validator: (validator) {
if (validator.isEmpty) return 'Empty';
if (validator != _password.text)
return 'The passwords do not match';
return null;
}),
RaisedButton(
child: Text(
'Registrar-se',
),
elevation: 5.0,
onPressed: () async {
_form.currentState.validate();
})
])),
);
}
}
I also have made a validation more sophisticated using RxDart and Streams. Check it out on medium
I have a TextField where I allow numbers like 1,4. I am trying ti replace the , to a . so the number will be 1.4.
I am trying this
double alphareceipe = double.parse(_alphareceipe.text);
alphareceipe = alphareceipe.replace("," ".");
But get this error:
error: The method 'replace' isn't defined for the class 'double'. (undefined_method at [brewingapp] lib/screens/calculator/alphaacid.dart:227).
The total code looks like this:
import 'package:flutter/material.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'package:brewingapp/app_localizations.dart';
import 'package:flutter/services.dart';
import 'package:devicelocale/devicelocale.dart';
const String testDevice = "Mobile_id";
class AlphaAcid extends StatefulWidget {
#override
_AlphaAcidState createState() => _AlphaAcidState();
}
class _AlphaAcidState extends State<AlphaAcid> {
}
String _emiResult = "";
final TextEditingController _weight = TextEditingController();
final TextEditingController _alphareceipe = TextEditingController();
final TextEditingController _alphanew = TextEditingController();
#override
void initState() {
initPlatformState();
super.initState();
}
#override
String _locale;
Future<void> initPlatformState() async {
String currentLocale;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
currentLocale = await Devicelocale.currentLocale;
print(currentLocale);
} on PlatformException {
print("Error obtaining current locale");
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_locale = currentLocale;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context).translate('Hopsalpha'),),
backgroundColor: Colors.green[800],
//elevation: 0.0,
),
body: Center(
child: Container(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
child: TextField(
cursorColor: Colors.green[800],
controller: _alphareceipe,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.green[800], width: 2.0,),
),
filled: true,
fillColor: Colors.green[10],
labelText: _locale != 'da-DK'
? "Alpha acid receipe"
: "Alpha syre opskrift",
labelStyle: TextStyle(color: Colors.green[800])
),
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: <TextInputFormatter>[
// WhitelistingTextInputFormatter.digitsOnly
],
),
),
Container(
padding: EdgeInsets.all(20.0),
child: TextField(
cursorColor: Colors.green[800],
controller: _alphanew,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.green[800], width: 2.0,),
),
filled: true,
fillColor: Colors.green[10],
//labelText: "Final Gravity (1018)",
labelText: _locale != 'da-DK'
? "Your alpha acid"
: "Din alpha syre",
labelStyle: TextStyle(color: Colors.green[800]),
),
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: <TextInputFormatter>[
//WhitelistingTextInputFormatter.digitsOnly
],
),
),
Container(
padding: EdgeInsets.all(20.0),
child: TextField(
cursorColor: Colors.green[800],
controller: _weight,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.green[800], width: 2.0,),
),
filled: true,
fillColor: Colors.green[10],
//labelText: "Final Gravity (1018)",
labelText: _locale != 'da-DK'
? "Weight receipe"
: "Vægt i opskrift",
labelStyle: TextStyle(color: Colors.green[800]),
),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
),
),
Flexible(
fit: FlexFit.loose,
child: FlatButton(
onPressed: _handleCalculation,
//child: Text("Calculate"),
child: Text(AppLocalizations.of(context).translate('calculate'),),
color: Colors.green[600],
textColor: Colors.white,
padding: EdgeInsets.only(top: 10.0, bottom: 10.0, left: 24.0, right: 24.0),
),
),
emiResultsWidget(_emiResult)
],
),
),
));
}
void _handleCalculation() {
double newWeight = 0.0;
//
//
//
//
//
double alphareceipe = double.parse(_alphareceipe.text);
alphareceipe = alphareceipe.replace("," ".");
int alphanew =int.parse(_alphanew.text);
int weightreceipe = int.parse(_weight.text);
//
try {
newWeight = (weightreceipe * alphareceipe) / alphanew;
_emiResult = newWeight.toStringAsFixed(0);
setState(() {
});
} //catch(e) {
on Exception catch(e){
print(e);
setState(() {
});
}
//_emiResult = A.toStringAsFixed(1);
//setState(() {
//});
}
Widget emiResultsWidget(emiResult) {
bool canShow = false;
String _emiResult = emiResult;
if(_emiResult.length > 0) {
canShow = true;
}
return
Container(
margin: EdgeInsets.only(top: 30.0, left: 20.0, right: 20.0),
alignment: FractionalOffset.center,
color: Colors.green[50],
child: canShow ? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
//crossAxisAlignment: CrossAxisAlignment.start,
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget> [
Padding(
padding: EdgeInsets.all(10.0),
child:
Text(AppLocalizations.of(context).translate('newweight'),
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.green[800],
),
)
),
SizedBox(width: 20.0,),
Text(_emiResult,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.green[800],
)
),
SizedBox(width: 10.0,),
]),
]
) : Container(),
);
}
}
I would suggest to use an appropriate keyboard type in combination with an input formatter.
keyboardType: TextInputType.numberWithOptions(decimal: allowDecimal),
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]+[,.]{0,1}[0-9]*')),
TextInputFormatter.withFunction(
(oldValue, newValue) => newValue.copyWith(
text: newValue.text.replaceAll(',', '.'),
),
),
],
This way, the user can only enter digits and ",", ".", "-" and even if a "," is entered, the second input formatter (they can be chained) replaces the ",". All this happens while this is still a String and not a number.
You cannot use a String function on a double. Replace the symbol on the String, then cast to double.
You are trying to replace the characters after the text has already been converted to a double. Try this instead:
double alphareceipe = double.parse(_alphareceipe.text.replaceAll(",", "."));
The error is at user p = await createuser() inside Raisedbutton onpressed function
I have added toString() at the end of mobileinputcontroller while passing parameter to user.dart inside Raisedbutton onpressed function, still i am getting the above error.
What else should be done?
Here is the code:
Future<User> createUser (String url,{Map body}) async{
String userId;
return http.post(url,
body:body).then((http.Response response){
if (response.statusCode < 200 || response.statusCode > 400 || json == null) {
throw new Exception("Error while fetching data");
}
print(json.decode(response.body));
var extractdata = json.decode(response.body);
userId = extractdata["uid"];
print(userId);
return User.fromJson(json.decode(response.body));
});
}
class Register extends StatefulWidget {
#override
_RegisterState createState() => _RegisterState();
}
class _RegisterState extends State<Register> implements RegisterPageContract{
BuildContext _ctx;
final _formKey = new GlobalKey<FormState>();
final scaffoldKey = new GlobalKey<ScaffoldState>();
bool loading = false;
RegisterPagePresenter _presenter;
User newUser;
static final create_url = "http://www.hiddenmasterminds.com/web/index.php?r=featured/createinitialstudent";
TextEditingController firstNameInputController;
TextEditingController lastNameInputController;
TextEditingController emailInputController;
TextEditingController pwdInputController;
TextEditingController confirmPwdInputController;
TextEditingController mobileNoInputController;
TextEditingController referCodeInputController;
#override
initState() {
firstNameInputController = new TextEditingController();
lastNameInputController = new TextEditingController();
mobileNoInputController = new TextEditingController();
emailInputController = new TextEditingController();
pwdInputController = new TextEditingController();
confirmPwdInputController = new TextEditingController();
referCodeInputController = new TextEditingController();
super.initState();
_presenter = RegisterPagePresenter(this);
}
void _submit(){
final form = _formKey.currentState;
if(form.validate()){
loading = true;
form.save();
_presenter.doRegister(firstNameInputController.text.toString(),
firstNameInputController.text.toString(),
emailInputController.text.toString(),
mobileNoInputController.text.toString(),
pwdInputController.text.toString(),
"comp",
"sppu",
"pict",
"abc",
"123",
"cdv" );
}
}
String error = '';
bool _showPassword = false;
bool _showConfirmPassword = false;
bool checkBoxValue = true;
#override
void dispose() {
pwdInputController.dispose();
super.dispose();
}
String emailValidator(String value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (!regex.hasMatch(value)) {
return 'Email Format Is Invalid';
} else {
return null;
}
}
String pwdValidator(String value) {
if (value.length < 8) {
return 'Password Must Be Longer Than 8 Characters';
} else {
return null;
}
}
String confirmPwdValidator(String val) {
if(val.isEmpty)
return 'Empty';
if(val != pwdInputController.text)
return "Password Doesn't Match";
return null;
}
#override
Widget build(BuildContext context) {
_ctx = context;
final bgColor = const Color(0xFF4b0081);
return loading ? Loading() : Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: bgColor,
body:SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
padding: const EdgeInsets.only(top:30.0, right: 30, left: 30, bottom: 100),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 25.0,),
TextFormField(
validator: (val) {
if (val.length < 3) {
return "Enter a Valid First Name";
}
return null;
},
decoration: InputDecoration(
labelText: "First and Last Name",
hintText: "John Joe",
labelStyle: TextStyle(color: Colors.white),
prefixIcon: Icon(
Icons.perm_identity,
color: Colors.blue[400],
)
),
controller: firstNameInputController,
style: TextStyle(color: Colors.white, fontSize: 17.0),
),
TextFormField(
validator: (val) => val.length != 10 ? "Enter a 10 Digit Mobile Number" : null,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.phone_android,
color: Colors.blue[400],
),
labelText: "10 Digit Mobile Number(for OTP)",
hintText: "94XXXXXX12",
labelStyle: TextStyle(color: Colors.white)
),
controller: mobileNoInputController,
keyboardType: TextInputType.number,
style: TextStyle(color: Colors.white, fontSize: 17.0),
),
TextFormField(
validator: (val) => emailValidator(val),
controller: emailInputController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.mail,
color: Colors.blue[400],
),
labelText: "Email ID",
hintText: "john.doe#gmail.com",
labelStyle: TextStyle(color: Colors.white)
),
style: TextStyle(color: Colors.white, fontSize: 17.0),
),
TextFormField(
validator: (val) => pwdValidator(val),
controller: pwdInputController,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.lock,
color: Colors.blue[400],
),
labelText: "Passoword",
hintText: "********",
labelStyle: TextStyle(color: Colors.white),
suffixIcon: GestureDetector(
onTap: (){
setState(() {
_showPassword = !_showPassword;
});
},
child: Icon(
_showPassword ? Icons.visibility : Icons.visibility_off,
color: Colors.blue[400],
)
),
),
style: TextStyle(color: Colors.white, fontSize: 17.0),
obscureText: !_showPassword,
),
TextFormField(
validator: (val) => confirmPwdValidator(val),
controller: confirmPwdInputController,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.lock,
color: Colors.blue[400],
),
suffixIcon: GestureDetector(
onTap: (){
setState(() {
_showConfirmPassword = !_showConfirmPassword;
});
},
child: Icon(
_showConfirmPassword ? Icons.visibility : Icons.visibility_off,
color: Colors.blue[400],
)
),
labelText: "Confirm Passoword",
hintText: "********",
labelStyle: TextStyle(color: Colors.white)
),
style: TextStyle(color: Colors.white, fontSize: 17.0),
obscureText: !_showConfirmPassword,
),
TextFormField(
controller: referCodeInputController,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.insert_emoticon,
color: Colors.blue[400],
),
labelText: "Refer Code(If Any)",
labelStyle: TextStyle(color: Colors.white)
),
style: TextStyle(color: Colors.white, fontSize: 17.0),
),
SizedBox(height: 15.0,),
Row(
children: <Widget>[
Checkbox(
value: checkBoxValue,
onChanged: (bool value){
setState(() {
checkBoxValue = value;
});
},
),
Text('By Clicking This You Agree All The Terms and Conditions.',
style: TextStyle(
color: Colors.white,
fontSize: 10
),
)
],
),
RaisedButton(
color: Colors.white,
child: Text(
'Register',
style: TextStyle(color: bgColor),
),
onPressed: () async {
newUser = new User(firstName:firstNameInputController.text.toString(),
lastName: lastNameInputController.text.toString(),emailId:emailInputController.text.toString(),
mobile: mobileNoInputController.text.toString(),password: pwdInputController.text.toString(),
department: "comp",univ_name: "abc",college_name: "hello",
university_year: "234",build_no: "234",android_no: "asd");
User p = await createUser(create_url,body:newUser.toMap());
// _submit();
},
splashColor: Colors.grey,
),
SizedBox(height: 12.0,),
Text(
error,
style: TextStyle(
color: Colors.red,
fontSize: 14.0
),
),
FlatButton(
color: bgColor,
child: Text(
'Already Have An Account? Login Here!',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
Navigator.pushNamed(_ctx, './SignIn');
},
),
],
),
),
),
],
),
),
);
}
Please help to resolve the problem!!
userId = extractdata["uid"].toString();