TextFormField not resetting when exiting page - flutter

I made the TextFormField Widget to be able to use it wherever needed. The codes are as follows;
Widget TextFormFieldWidget(
TextEditingController controller,
Icon icon,
String hintText,
bool obscureText,
BuildContext context,
) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ThemeData().colorScheme.copyWith(
primary: Colors.red,
),
),
child: TextFormField(
obscureText: obscureText,
controller: controller,
decoration: InputDecoration(
hintText: hintText,
prefixIcon: icon,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
),
);
}
I'm having a problem. Here's the problem: I'm making a registration page. When the user exits the page and enters back, the values ​​entered in the TextFormField are not reset. For example, let me give an example that the user gives up after entering their e-mail address. When you leave the page and enter back, the e-mail address is not deleted.
How can I solve the problem? Thanks for help.

Please clear the text controllers value when you exit the page.

Dispose the controller
Clear the Conroler.
ElevatedButton(
onPressed: (){
controller.clear();
},
child: Text("Send")
)

In case you use one (a shared) TextController an the one TextController gets passed in to each TextFormFieldWidget, the the single controller will have a single state.
Thus, it keeps its value when getting attached to a new TextFormFieldWidget.
Please use different TextEditingController for different fields.

The issue with creating a function to return a Widget is such. If you're making a custom widget for your app, let's say reusable custom text field, It is suggested to be made into a separate StatefulWidget.
When you use stateful widget, you make a new instance of the same widget as per needed.
Use the below mentioned code to create the same for yours.
import "package:flutter/material.dart";
class CustomTextFormField extends StatefulWidget {
const CustomTextFormField(
{required this.icon,
required this.hintText,
required this.obscureText,
super.key});
final Icon icon;
final String hintText;
final bool obscureText;
#override
State<CustomTextFormField> createState() => _CustomTextFormFieldState();
}
class _CustomTextFormFieldState extends State<CustomTextFormField> {
late TextEditingController controller;
#override
void initState() {
controller = TextEditingController();
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ThemeData().colorScheme.copyWith(
primary: Colors.red,
),
),
child: TextFormField(
obscureText: widget.obscureText,
controller: controller,
decoration: InputDecoration(
hintText: widget.hintText,
prefixIcon: widget.icon,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
),
);
}
}

Related

Change textfield value with firebase realtime database value

I want to change two textfields value via firebase realtime database value in Flutter not sure how to do it
this is my code I am using Getx controller that is why a little confused
i am a beginner so ignore bad code
for Firebase :
static void readData() async
{
DatabaseReference dataRef = FirebaseDatabase.instance
.ref()
.child("test");
dataRef.once().then((snap)
{
if(snap.snapshot.value != null)
{
dataModelInfo = DataModel.fromSnapshot(snap.snapshot);
BlockController().fheight = dataModelInfo!.height.toString();
BlockController().flength = dataModelInfo!.length.toString();
print("height ="+ dataModelInfo!.height.toString());
print("length ="+ dataModelInfo!.length.toString());
}
});
}
For Textfields :
class BlockController extends GetxController{
final WallheightController = TextEditingController();
final WalllengthController = TextEditingController();
}
want to update text field data after retrieving from firebase
class SidesField extends StatelessWidget {
SidesField({
Key? key,
required this.labelText,
required this.controller, required Map Function(dynamic text) onChanged,
}) : super(key: key);
final String labelText;
final TextEditingController controller;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
controller: controller,
decoration: InputDecoration(
labelText: labelText,
labelStyle: const TextStyle(color: kPurpleColor),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: kPurpleColor,
width: 3,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator:(value){
if(value!.isEmpty){
return "Enter This Field";
}
return null;
},
),
);
}
}
Please tell my how to change value of text field after taking data from firebase realtime database

How can i change TextField on hover in flutter?

Hi i'm trying to change the background color of my TextField Widget in flutter when the user focus on it. But it kinda seems there is no way to do it. If anybody has any idea please let me know ^^.
Here's the Widget itself:
TextField(
controller: emailController,
style: TextStyle(
color: Colors.white, fontSize: 18, height: 0.8),
textAlign: TextAlign.center,
decoration: InputDecoration(
focusColor: AppColors.inputBackgroundDarkFocus,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Color(color)),
),
filled: true,
fillColor: Color(0xff25282C),
hintText: 'Email',
hintStyle:
TextStyle(fontSize: 18, color: Colors.white),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
Thks <3
Hover & focus are two different things, so this might not answer your question, but the below can change field color "on focus" (the cursor is in the field).
If you're implementing purely for Flutter web and you want to handle "hover" you could do the below with a MouseRegion wrapper instead of Focus. Info on MouseRegion.
By wrapping a form field in a Focus widget, you can listen/capture focus changes on that field using the onFocusChange constructor argument (of Focus).
It takes a Function(bool).
Here's an example of an onFocusChange handler function:
onFocusChange: (hasFocus) {
if (hasFocus) {
print('Name GAINED focus');
setState(() {
bgColor = Colors.purple.withOpacity(.2);
});
}
else {
print('Name LOST focus');
setState(() {
bgColor = Colors.white;
});
}
},
If you wrap your field in a Container, you can give the Container a color and change that color using a Focus widget described above.
Here's a full page example (stolen from another answer of mine on a similar topic):
import 'package:flutter/material.dart';
class TextFieldFocusPage extends StatefulWidget {
#override
_TextFieldFocusPageState createState() => _TextFieldFocusPageState();
}
class _TextFieldFocusPageState extends State<TextFieldFocusPage> {
Color bgColor = Colors.white;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// ↓ Add this wrapper
Focus(
child: Container(
color: bgColor,
child: TextField(
autofocus: true,
decoration: InputDecoration(
labelText: 'Name'
),
textInputAction: TextInputAction.next,
// ↓ Handle focus change via Software keyboard "next" button
onEditingComplete: () {
print('Name editing complete');
FocusScope.of(context).nextFocus();
},
),
),
canRequestFocus: false,
// ↓ Focus widget handler, change color here
onFocusChange: (hasFocus) {
if (hasFocus) {
print('Name GAINED focus');
setState(() {
bgColor = Colors.purple.withOpacity(.2);
});
}
else {
print('Name LOST focus');
setState(() {
bgColor = Colors.white;
});
}
},
),
TextField(
decoration: InputDecoration(
labelText: 'Password'
),
),
],
),
),
),
);
}
}
I think you can repeat this for each field you need colored.
Hovering can be managed using the hoverColor property of InputDecoration:
Full source code:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Hover TextField Demo',
home: HomePage(),
),
);
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: TextField(
decoration: InputDecoration(
filled: true,
hoverColor: Colors.indigo.shade200,
hintText: 'Email',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
),
);
}
}
Almost every style property can be changed by decoration property, which requires an InputDecoration object.
To handle the hover style, this object provides only the hoverColor property, which overwrite the filledColor when the mouse is hovering the widget. The filled property needs to be true for this to work.
InputDecoration(
filled: true,
hoverColor: Colors.red,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
The problem is when you want to change others style properties like the border for example.
In that case you need to make your widget Statefull and add a state boolean like isHover.
Then you could wrap your widget inside MouseRegion and handle the hovering like in this example:
return MouseRegion(
onEnter: (_)=>setState(()=>isHover = true),
onExit: (_)=>setState(()=>isHover = false),
child: YourWidget(),
);
Once isHover is available you can use wherever you want to change the UI according to the hover state.
Example with border:
TextField(
decoration: InputDecoration(
filled: true,
hoverColor: Colors.red,
border: isHover? OutlineInputBorder(
borderSide: BorderSide(
color: Colors.green,
width: 1.5,
),
borderRadius: BorderRadius.circular(8.0),
) : null,
//By leaving null, the component will use the default value
),
),
I think the limitation is due to the fact that the hover behaviour is more web/desktop related. I hope flutter is going to implement better properties to handle this inside InputDecoration.

should Bloc pattern be used for flutter textfield and if yes how?

So I'm new to Bloc but I understand how it works from previously working on native android development, but what I'm trying to understand is should it be implemented to create something like a TextField. Now, keep in mind that I am trying to reuse this TextField multiple times and I want the bloc pattern to dynamically validate the input but should I implement it completely like handle the text inputted by the user?
what I've done is I've created a simple bloc pattern for the text field to handle the user input but it does not save the values from time to time it overwrites the previous value and the cursor keeps moving to the beginning of the text
import 'dart:math';
import 'package:competitionapp/data_model/events/formTextFieldEvent.dart';
import 'package:competitionapp/data_model/states/formTextFieldState.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
FormTextFieldBloc bloc = FormTextFieldBloc();
class FormTextFieldBloc extends Bloc<FormTextFieldEvent, FormTextFieldState> {
void onChanged(String value) {
if (value == null || value.isEmpty)
// todo change to handle errors
this.add(TextChangedEvent("error"));
else
this.add(TextChangedEvent(value));
}
#override
FormTextFieldState get initialState => FormTextFieldState.initState();
#override
Stream<FormTextFieldState> mapEventToState(FormTextFieldEvent event) async* {
if (event is TextChangedEvent) {
print("value received: ${event.eventText}");
yield FormTextFieldState(event.eventText);
}
}
}
import 'package:competitionapp/data_model/blocModels/formTextFieldBloc.dart';
import 'package:competitionapp/data_model/states/formTextFieldState.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class FormTextField extends StatelessWidget {
final TextEditingController _controller;
final String hint;
final IconData iconData;
final TextInputType inputType;
final int maxLines;
final int maxLength;
final EdgeInsetsGeometry padding;
final FormTextFieldBloc formTextFieldBloc;
FormTextField(this._controller, this.formTextFieldBloc,
{this.hint,
this.iconData,
this.inputType: TextInputType.text,
this.maxLines: 1,
this.maxLength,
this.padding: const EdgeInsets.fromLTRB(15, 5, 15, 5)});
#override
Widget build(BuildContext context) {
return Padding(
padding: padding,
child: BlocBuilder(
bloc: formTextFieldBloc,
builder: (context, FormTextFieldState state) {
if (state.text.isNotEmpty && state.text != null) {
_controller.text = state.text;
print("state text: ${state.text}");
}
return TextField(
onChanged: (value) {
print(value);
formTextFieldBloc.onChanged(_controller.text);
},
onEditingComplete: (){
print(_controller.text);
},
maxLength: maxLength ?? maxLength,
maxLines: maxLines,
keyboardType: inputType,
controller: _controller,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent, width: 0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent, width: 0)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent, width: 0)),
hintText: hint,
hintStyle:
Theme.of(context).textTheme.caption.copyWith(fontSize: 18),
filled: true,
fillColor: Theme.of(context).cardColor,
prefixIcon: Icon(
iconData,
size: 16,
color: Theme.of(context).hintColor,
),
),
);
},
),
);
}
}
The issue here happens because the value on TextField is always overridden on _controller.text = state.text; and continuously updated on onChanged(). One way to approach this is to only update the TextField values when the entry is submitted i.e. on onFieldSubmitted()
You can check for a similar approach here. While it doesn't use a Stream to listen for changes, the TextField value needs to be updated with a desired format.

Is it possible in Flutter to reuse TextEditingController?

In my application, there is a lot of TextFields like more than 50.
class BoxFieldItem extends StatelessWidget {
BuildContext context;
final String title;
final String subtitle;
TextEditingController textControler;
BoxFieldItem(this.title,this.subtitle,){
textControler=new TextEditingController();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
textInputAction: TextInputAction.next,
controller: textControler,
/* onChanged: (String e) {
},*/
decoration: InputDecoration(
fillColor: Colors.lightBlue[40],
filled: true,
prefixIcon: Icon(Icons.person),
labelText: title,
hintText: subtitle,
hintStyle: TextStyle(fontSize: 12),
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
),
);
}
}
I have this Widget class ,trouble is when i use it like: BoxFieldItem('Title','sub'), text entered disapiar if i scroll or click next?
What im doing wrong
Depending on your implementation. I would create a widget that wrap the TextField and its controller then in your page you just need use the created widget and provide different configurations via constructor.
To listen for changes in the TextField you can just provide a callback to be used in your page.

Create custom textformfield

I am trying to create custom textformfield so I can easily style only in one place. But currently I am stuck on how to pass validation and save process. Can someone give me a working example of custom widget textformfield that I can use? I have been searching it for whole day and cannot find one. Thank you for help.
Example here is on raised button:
import 'package:flutter/material.dart';
import 'package:wkndr/resources/constants.dart';
class CustomButton extends StatelessWidget {
CustomButton({#required this.text, #required this.onPressed});
final String text;
final GestureTapCallback onPressed;
#override
Widget build(BuildContext context) {
return RaisedButton(
color: colorPrimary,
child: Text(text, style: TextStyle(fontSize: 17.0, color: colorWhite)),
onPressed: onPressed,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
);
}
}
Calling custom raised button:
final _signUpButton = Container(
child: CustomButton(
text: sign_up,
onPressed: () {
_signUp();
}),
);
Instead of making custom textformfield you can make common InputDecoration for styling
class CommonStyle{
static InputDecoration textFieldStyle({String labelTextStr="",String hintTextStr=""}) {return InputDecoration(
contentPadding: EdgeInsets.all(12),
labelText: labelTextStr,
hintText:hintTextStr,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
);}
}
Example:-
TextFormField(
controller: usernameController,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
focusNode: userFocus,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(passFocus);
},
validator: (value) => emptyValidation(value),
decoration: CommonStyle.textFieldStyle(labelTextStr:"Username",hintTextStr:"Enter Username"),
)
You can define InputDecorationTheme in your app theme to set global style for text fields.
MaterialApp(
title: title,
theme: ThemeData(
brightness: Brightness.dark,
...
inputDecorationTheme: InputDecorationTheme(
fillColor: Colors.blue,
filled: true,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
hintStyle: TextStyle(color: Colors.white.withAlpha(80)),
),
)
);
You can also change theme properties for a particular widget using Theme widget:
Theme(
data: Theme.of(context).copyWith(inputDecorationTheme: /*new decoration theme here*/),
child: Scaffold(
body: ...,
),
);
See more information about themes in Flutter docs.
You can try custom TextFormField.
You can make easily common TextFormField for customizing TextFormField.
You can try like this.
Step 1: First create one dart class i.e EditTextUtils
Step 2: Create a function or method i.e getCustomEditTextArea
class EditTextUtils {
TextFormField getCustomEditTextArea(
{String labelValue = "",
String hintValue = "",
bool validation,
TextEditingController controller,
TextInputType keyboardType = TextInputType.text,
TextStyle textStyle,
String validationErrorMsg}) {
TextFormField textFormField = TextFormField(
keyboardType: keyboardType,
style: textStyle,
controller: controller,
validator: (String value) {
if (validation) {
if (value.isEmpty) {
return validationErrorMsg;
}
}
},
decoration: InputDecoration(
labelText: labelValue,
hintText: hintValue,
labelStyle: textStyle,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5.0))),
);
return textFormField;
}
}
Example: You can try like this
EditTextUtils().getCustomEditTextArea(
labelValue: 'label',
hintValue: 'hint',
validation: true,
controller: controller_name,
keyboardType: TextInputType.number,
textStyle: textStyle,
validationErrorMsg: 'error_msg')