Add new text form field when button pressed? - flutter

I have screen which have username field,
Here, When i press the submit button add new TextFormField below the UserName field so how i can do this?
Code as Below.
return Container(
child: Form(
key: _formKey,
child: Column(
children: [
Container(
padding: const EdgeInsets.all(10),
child: Text("Reset Password"),
),
Container(
child: Center(
child: Expanded(
child: Text(
"Enter your username below to recieve password reset instruction",
textAlign: TextAlign.center,
maxLines: 2,
),
),
),
),
TextFormField(
controller: userNameController,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "User Name",
),
focusNode: fnField1,
validator: (value) {
if (value?.isEmpty == true) {
return AppLocalizations.of(context)!.valEnterUserName;
}
return null;
},
),
Container(
constraints: const BoxConstraints(minWidth: double.infinity),
child: ElevatedButton(
onPressed: () async {},
child: Text("Submit"),
),
),
],
),
),
);
Please help me that how i can do this.

In such a case we can use a StatefulWidget to set a _displayNewTextField boolean to true once the button is pressed:
bool _displayNewTextField = false;
...
Container(
constraints: const BoxConstraints(minWidth: double.infinity),
child: ElevatedButton(
onPressed: () async {
setState(() {
_displayNewTextField = true;
});
},
child: const Text("Submit"),
),
),
And use a Visibility Widget to show the new TextField accordingly:
Visibility(
visible: _displayNewTextField,
child: TextFormField(
controller: newTextFieldController,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: "User Name",
),
),
),
A full example is reported below:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _displayNewTextField = false;
TextEditingController newTextFieldController = TextEditingController();
TextEditingController userNameController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Form(
child: Column(
children: [
Container(
padding: const EdgeInsets.all(10),
child: const Text("Reset Password"),
),
const Center(
child: Expanded(
child: Text(
"Enter your username below to recieve password reset instruction",
textAlign: TextAlign.center,
maxLines: 2,
),
),
),
TextFormField(
controller: userNameController,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: "User Name",
),
),
Visibility(
visible: _displayNewTextField,
child: TextFormField(
controller: newTextFieldController,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: "User Name",
),
),
),
Container(
constraints: const BoxConstraints(minWidth: double.infinity),
child: ElevatedButton(
onPressed: () async {
setState(() {
_displayNewTextField = true;
});
},
child: const Text("Submit"),
),
),
],
),
),
),
);
}
}

Related

Flutter Simple Login Page

I am a flutter beginner. How to make a simple login page in flutter like this. I tried, but I get a lot of errors. Can anyone help to resolve this?
Please see here to find what I want
Thanks in advance!...............
My code:
Container(
width: 350,
child: TextField(
decoration: InputDecoration(
label Text: 'Email',
),
),
),
Container(
width: 350,
child: TextField(
obscureText: true,
decoration: InputDecoration(
label Text: 'Password',
suffixIcon: Icon(CupertinoIcons.eye_slash_fill,
size: 17),
),
),
),
Padding(
padding: EdgeInserts.fromLTRB(20,20,40,40),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text('Forget Password')
],
),
),
GestureDetector(
child: Container(
alignment: Alignment.center,
width: 250,
child: TextField(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
),
child: Padding(
padding: EdgeInsets.all(top: 12),
child: Text('LOGIN')
),
),
),
),
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final _formKey = GlobalKey<FormState>();
String _email, _password;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login Screen'),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
validator: (input) {
if (input.isEmpty) {
return 'Please enter an email';
}
return null;
},
onSaved: (input) => _email = input,
decoration: InputDecoration(
labelText: 'Email',
),
),
TextFormField(
validator: (input) {
if (input.length < 6) {
return 'Your password needs to be at least 6 characters';
}
return null;
},
onSaved: (input) => _password = input,
decoration: InputDecoration(
labelText: 'Password',
),
obscureText: true,
),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
// This is where you can handle the login logic
}
},
child: Text('Submit'),
),
],
),
),
),
);
}
}
This is sample code of Login screen.
For get more design and code head to https://flutterawesome.com/tag/login-screen
there is lot of sample code available. And I think you can get better idea from it.

I can't change my widget's visibility with using mobx

I'm trying to change my second TextField's visibility in my other Auth class but I'm using mobx. I tried this version. But I can't solve my problem anyway.
If I declare my otpvisibility variable in SignInView class, I need to use setstate when i change the value of this variable in the Auth class. But i can't use setstate because I am using mobx. On the other hang if I declare otpvisibility variable in my mobx class, changes won't effect.
class SignInView extends StatelessWidget {
final BuildContext context;
SignInView({required this.context, Key? key}) : super(key: key);
TextEditingController phonecontroller = TextEditingController();
TextEditingController otpcontroller = TextEditingController();
Auth auth = Auth();
SignInViewModel svm = SignInViewModel();
#override
Widget build(BuildContext context) {
return Scaffold(
body: buildbody,
);
}
Widget get buildbody {
double screenWidth = MediaQuery.of(context).size.width;
return Observer(builder: (_) {
return SizedBox(
width: screenWidth,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"Welcome to Whatsapp Clone, Let's begin!",
style: TextStyle(color: Colors.green, fontSize: 20),
),
const SizedBox(height: 30),
Container(
padding: const EdgeInsets.all(8),
height: 80,
child: TextField(
controller: phonecontroller,
decoration: const InputDecoration(
border: OutlineInputBorder(borderSide: BorderSide()),
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.done,
onSubmitted: (String value) {
if (phonecontroller.text != '') {
if (svm.otpVisibility) {
svm.otpvisiblty(context);
auth.verifyotp(context, otpcontroller.text);
} else {
print('otpvisible false');
auth.loginWithPhone(
context: context, phone: phonecontroller.text);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Please enter your phone number')));
}
},
)),
Visibility(
visible: svm.otpVisibility,
child: Container(
padding: const EdgeInsets.all(8),
height: 80,
child: TextField(
controller: otpcontroller,
decoration: const InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(),
),
),
keyboardType: TextInputType.number,
maxLength: 6,
),
),
),
TextButton(
onPressed: () {
print(phonecontroller.text);
if (phonecontroller.text != '') {
if (svm.otpVisibility) {
svm.otpvisiblty(context);
auth.verifyotp(context, otpcontroller.text);
} else {
print('otpvisible false');
auth.loginWithPhone(
context: context, phone: phonecontroller.text);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Please enter your phone number')));
}
},
child: const Text(
'Verify',
style: TextStyle(color: Colors.green),
),
)
],
),
),
);
});
}
}

Error: The parameter 'onSubmit' can't have a value

Hi I have created a default form field, in a separate dart file called components, and I have login_screen.dart also.
there are many errors I don't know how to fix it, and make the code work, I will put down the code of the component.dart code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Widget defaultButton(
{double width = double.infinity,
Color background = Colors.blue,
double radius = 10.0,
required Function function,
required String text,
bool isUpperCase = true}) =>
Container(
height: 40.0,
width: width,
child: MaterialButton(
onLongPress: () {},
onPressed: function(),
child: Text(
isUpperCase ? text.toUpperCase() : text.toLowerCase(),
style: TextStyle(color: Colors.white),
)),
decoration: BoxDecoration(
borderRadius: BorderRadiusDirectional.circular(radius),
color: background,
),
);
Widget defaultFormFeild({
required TextEditingController controller,
required TextInputType type,
Function onSubmit,
Function onChange,
required Function validate,
required var label,
required IconData prefix,
}) =>
TextFormField(
controller: controller,
keyboardType: type,
onFieldSubmitted: onSubmit(),
onChanged: onChange(),
validator: validate(),
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(prefix),
border: OutlineInputBorder()
),
);
and here is the code of the login_screen.dart:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:udemy_flutter/shared/components/components.dart';
class LoginScreen extends StatelessWidget {
var emailController = TextEditingController();
var passController = TextEditingController();
var formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: SingleChildScrollView(
child: Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Login',
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold
),
),
const SizedBox(
height: 40.0,
),
defaultFormFeild(
controller: emailController,
label: 'Email',
prefix: Icons.email,
type: TextInputType.emailAddress,
validate: (String value){
if(value.isEmpty != null){
return 'Email Cannot Be Empty';
}
return null;
}
),
const SizedBox(
height: 15.0,
),
TextFormField(
controller: passController,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
prefixIcon: Icon(
Icons.lock
),
suffixIcon: Icon(
Icons.remove_red_eye,
)
),
onChanged: (value) {
print(value);
},
onFieldSubmitted: (value) {
print(value);
},
validator: (value) {
if(value!.isEmpty){
return 'Password cannot be empty';
}
return null;
},
),
const SizedBox(
height: 10.0,
),
defaultButton(
function: (){
print(emailController.text);
print(passController.text);
},
text: 'Login',
),
const SizedBox(
height: 10.0,
),
defaultButton(
text: 'ReGister',
function: () {
print('You have just clicked on register');
},
background: Colors.red,
isUpperCase: false
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Don\'t you have an account?'),
TextButton(onPressed: () {}, child: const Text(
'Register Now'
))
],
)
],
),
),
),
),
),
);
}
}
Idk if all the problems came from a null-safety feature in a flutter because I'm new in this technology.
Why
The reason this happens is because with null safety enabled, your functions onSubmit and onChange can't be null.
Solution
I would do it this way:
Widget defaultFormFeild({
required TextEditingController controller,
required TextInputType type,
Function? onSubmit, //Add question mark
Function? onChange, //Add question mark
required Function validate,
required var label,
required IconData prefix,
}) =>
TextFormField(
controller: controller,
keyboardType: type,
onFieldSubmitted: onSubmit != null? onSubmit() : null, //do null checking
onChanged: onChange != null? onChange() : null, //do null checking
validator: validate(),
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(prefix),
border: OutlineInputBorder()
),
);

how to get save the value from textfromfield and pass it back to page?

import 'package:flutter/material.dart';
import 'package:mmitra/widgets/header.dart';
import 'home.dart';
class CreateAccount extends StatefulWidget {
#override
_CreateAccountState createState() => _CreateAccountState();
}
class _CreateAccountState extends State<CreateAccount> {
late String username;
final _key = Global Key<FormState>();
#override
Widget build(BuildContext parentContext) {
return Scaffold(
appBar: header(context, titleText: 'Create Account'),
body: ListView(children: [
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(top: 25),
child: Center(
child: Text(
'Create a username',
style: TextStyle(fontSize: 25.0),
),
),
),
Padding(
padding: EdgeInsets.all(16.0),
child: Form(
child: TextFormField(
key: _key,
// controller: myController,
onSaved: (val) => username = val!,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelStyle: TextStyle(fontSize: 15),
labelText: 'Username',
hintText: 'Must be at least 3 Characters'),
),
),
),
GestureDetector(
onTap: () {
_key.currentState!.save();
Navigator.pop(context, username
);
},
child: Container(
height: 50,
width: 300,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(7)),
child: Center(
child: Text(
'Submit',
style:
TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
),
),
),
],
),
),
]),
);
}
}
and I'm getting below shown errors:
Exception caught by gesture
The following Cast Error was thrown while handling a gesture
Null check operator used on a null value
I just want to get the textfromfield value and i want to pass it to the home.dart page in order to create the document in firebase collection
you must define a EditTextControll() ex:textController and set it to TextFormField to controller paramerter , and then get text as textController.text and pass with Navigatoer .
for pass wihtin first screen to two screen
Firstly /
TextEditingController controller = TextEditingController();
Secoundly /
body: Form(
child: TextFormField(
controller: controller,
onTap: (){
//here SettingsScreen() is example
// name is paramerter in the secound screen
Navigator.push(context,
MaterialPageRoute(builder: (context)=>SettingsScreen(name:controller.text),),
);
},
),
),
You added key in TextFormField
Form(
child: TextFormField(
key: _key,
// controller: myController,
onSaved: (val) => username = val!,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelStyle: TextStyle(fontSize: 15),
labelText: 'Username',
hintText: 'Must be at least 3 Characters'),
),
),
),
Remove it from TextFormField and Add it in Form
Just Like:
Form(
key: _key,
child: TextFormField(
// controller: myController,
onSaved: (val) => username = val!,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelStyle: TextStyle(fontSize: 15),
labelText: 'Username',
hintText: 'Must be at least 3 Characters'),
),
),
),
This will Solve your Issue.

How to save int data from TextFormField in Flutter

I made some TextFormField, and I want to save the data in int when I press the FlatButton. When I press FlatButton, I want him to check whether the sum of TextFormField expenses and savings is not greater than TextFormField income. if the sum of the TextTormField expenses and savings is greater, I want to display errortext under the textformfield savings "your expenses and savings are greater than your income"
class BigNotePage extends StatefulWidget {
#override
_BigNotePageState createState() => _BigNotePageState();
}
class _BigNotePageState extends State<BigNotePage> {
final _formKey = GlobalKey<FormState>();
String _income;
String _expenses;
String _savings;
#override
Widget build(BuildContext context) {
return Container(
padding: kPading,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitlePage('Big Note'),
Expanded(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
TxtField(
label: 'Income',
function: (value) => _income = value,
),
TxtField(
label: 'Expenses',
function: (value) => _expenses = value,
),
TxtField(
label: 'Savings',
function: (value) => _savings = value,
),
FlatButton(
onPressed: () {
int.parse(_income) >=
int.parse(_expenses) + int.parse(_savings)
? _formKey.currentState.save()
: print('null');
},
child: Text(
'WRITE THAT',
style: TextStyle(letterSpacing: 1.25),
),
color: Colors.yellow,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
],
),
),
),
Container(
width: 250.0,
child: Text(
'*if you get another income for this mounth, input the income again.',
style: TextStyle(fontSize: 12.0),
),
),
],
),
);
}
}
class TxtField extends StatelessWidget {
TxtField({this.label, this.function});
final String label;
final Function function;
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
onSaved: function,
keyboardType: TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: label,
prefix: Container(
padding: EdgeInsets.all(8.0),
child: Text(
'IDR',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
),
),
),
);
}
}
Replace String values to the controller values
final _incomeController = TextEditingController();
final _expenseController = TextEditingController();
final _savingController = TextEditingController();
Also, add
bool _validate = false;
Convert String value to int of your TextField:
TextField(
controller: _incomeController,
label: 'Income',
decoration: InputDecoration(
errorText: _validate ? 'Your message' : null,
),
),
TextField(
controller: _expenseController ,
label: 'Expenses',
decoration: InputDecoration(
errorText: _validate ? 'Your message' : null,
),
),
TextField(
controller: _savingController,
label: 'Savings',
decoration: InputDecoration(
errorText: _validate ? 'Your message' : null,
),
),
Now FlatButton Logic:
onPressed: () {
String _income = _incomeController.text;
String _expenses = _expenseController.text;
String _savings = _savingController.text;
int.parse(_income) >=
int.parse(_expenses) + int.parse(_savings)
? _formKey.currentState.save()
: print('null');
},
Rest apply your logic wherever you want.