how to add two textformfields controllers in which int value is given?
when i was doing it showing me error saying that textediting controller can't be int.
child: ok != null ? Text('${okk1+ok1}', style: TextStyle(color: Colors.black, fontSize: 14),) :Text(""),
first textformfield:-
Container(
height: MediaQuery.of(context).size.height/12,
width: MediaQuery.of(context).size.width/3 ,
padding: const EdgeInsets.all(10.0),
child: TextFormField(
controller: _hire,
inputFormatters: [
new LengthLimitingTextInputFormatter(7),
],
keyboardType: TextInputType.text,
onChanged: (str) {
setState(() {
okk = _advance.text as int;
ok1 =int.parse(_hire.text);
});
print(ok1);
},
decoration: const InputDecoration(
labelText: '',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.grey),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.grey),
),
),
onSaved: (String value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
validator: (String value) {
return value.contains('#')
? 'Do not use the # char.'
: null;
},
),
),
second textformfield:-
Container(
height: MediaQuery.of(context).size.height/12,
width: MediaQuery.of(context).size.width/3 ,
padding: const EdgeInsets.all(10.0),
child: TextFormField(
controller: _advance,
inputFormatters: [
new LengthLimitingTextInputFormatter(7),
],
keyboardType: TextInputType.numberWithOptions(),
onChanged: (str) {
setState(() {
ok = _advance.text;
okk1 =int.parse(_advance.text);
});
print(okk1);
},
decoration: const InputDecoration(
labelText: '',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.grey),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.grey),
),
),
onSaved: (String value) {
// This optional block of code can be used to run
// code when the user saves the form
},
validator: (String value) {
return value.contains('#')
? 'Do not use the # char.'
: null;
},
),
),
these are the textformfield controllers for two textformfield in which data is 45 and 5 but in string because controllers text is in string format and i want to add these two controllers and the result would be 50.
You can add them like this.
If x1 and x2 are two textcontrollers.
var result = int.parse(x1.text) + int.parse(x2.text)
Related
I'd like to ask on if there are anyway on how to compare in a conditional statement the two variable. As you can see, couponSalePriceCtrlr and couponOrigPriceCtrlr. I'd like to validate that the user's input in sale price SHOULD not be greater than the original price, but it seems like the validator accepts only the (value) parameter and a String data type.
Widget editCouponSalePriceWidget(couponSalePriceCtrlr, couponOrigPriceCtrlr) {
// converted the variable parameters into double data type
double convertedSalePrice = double.parse(couponSalePriceCtrlr);
double convertedOrigPrice = double.parse(couponOrigPriceCtrlr);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 0.0),
child: TextFormField(
style: const TextStyle(fontFamily: 'Poppins', fontSize: 13),
controller: couponSalePriceCtrlr,
keyboardType: TextInputType.number,
decoration: InputDecoration(
suffixText: "*",
suffixStyle: TextStyle(color: Colors.red),
labelText: 'Sale Price',
labelStyle: const TextStyle(
fontSize: 15, fontFamily: 'Poppins', color: Color(0xFF152C4C)),
isDense: true,
prefixIcon: const Icon(Icons.person),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xFFCECECE)),
borderRadius: BorderRadius.circular(12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: Color(0xFFCECECE)),
),
hintText: 'Orig Price',
fillColor: const Color(0xFFFEFEFE),
filled: true,
),
// however the validator only accepts, a string data type.
validator: (convertedSalePrice,convertedOrigPrice) {
if (convertedSalePrice!.isEmpty ||
!RegExp(r'[0-9]+[,.]{0,1}[0-9]*').hasMatch(convertedSalePrice)) {
return "Please enter a valid original price.";
} else {
return null;
}
},
),
);
}
I assume you have 2 TextFormField, one for original price, another for sale price. Of course it is String type, that's the rule :) Therefore you need to convert it to integer/double type. If your keyboardType is number, it is unnecessary to check user's input is string type, else do it.
TextFormField(
controller: couponOrigPriceCtrlr,
keyboardType: TextInputType.number,
)
TextFormField(
controller: convertedSalePrice,
keyboardType: TextInputType.number,
validator: (saleStr) {
double originalDouble = double.parse(couponOrigPriceCtrlr.text);
double saleDouble = double.parse(saleStr.text);
// check what ever you want here
// ...
}
)
I'm trying to add validation on textfield, i want when i leave any textfield empty it change its border color into red and display a error message, so and when i write something in it then it should hide the border error and message, which is happening but not in efficient way, here is what i'm doing.
i created the custom textfield
Widget textformfieldCustom(context,keyboardType,width,icon, controller,errortext,onchanged, hintText, labelText) {
return Container(
width: width,
child:TextFormField(
keyboardType:keyboardType,
decoration: InputDecoration(
contentPadding:EdgeInsets.symmetric(vertical: 20.0, horizontal: 10.0),
errorText:errortext,
labelText: labelText,
labelStyle: GoogleFonts.montserrat(color: HexColor("#6e6b7b")),
hintStyle: GoogleFonts.montserrat(),
hintText: hintText,
prefixIcon: icon,
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)),borderSide: BorderSide(color: HexColor("#6610f2"))),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.red, width: 1))),
onSaved: (String? value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
onChanged:onchanged,
controller: controller,
));
}
and calling it as like this
bool _validatetex = false;
textformfieldCustom(
context,
TextInputType.number,
MediaQuery.of(context).size.width * 0.9,
Icon(Icons.email,color: iconColor,),
phoneNoController,
_validatetex ? 'This is the required field' : null,
(value) {
setState(() {
phoneNoController.text.isEmpty ? _validatetex = true : _validatetex = false;
});
},
'Enter your phone number',
'Phone number'
),
i'm using a bool type variable in errortext and changing its state in onchanged, so i want to do it in efficient way, like if i have 10 textfields so i have to initialize 10 bool variables so this is not a good way to go. please help how to achieve this in efficient way.
You can use the validator property in `TextField``
validator: (value) {
if (value == null || value.isEmpty) {
return 'This is the required field';
}
return null;
},
Then your code,
Widget textformfieldCustom(context,keyboardType,width,icon, controller,errortext,onchanged, hintText, labelText) {
return Container(
width: width,
child:TextFormField(
keyboardType:keyboardType,
decoration: InputDecoration(
contentPadding:EdgeInsets.symmetric(vertical: 20.0, horizontal: 10.0),
labelText: labelText,
labelStyle: GoogleFonts.montserrat(color: HexColor("#6e6b7b")),
hintStyle: GoogleFonts.montserrat(),
hintText: hintText,
prefixIcon: icon,
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)),borderSide: BorderSide(color: HexColor("#6610f2"))),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.red, width: 1))),
onSaved: (String? value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
onChanged: onchanged,
controller: controller,
// Validator
validator: (value) {
if (value == null || value.isEmpty) {
return 'This is the required field';
}
return null;
},
));
}
I got my answer from this tutorial.
I want to change the background color of the TextFormField
when I selected the TextFormField to enter a value.
default : TextFormField background color is grey
on focus : TextFormField background color is blue.
What should I do?
const _lowColor = Colors.redAccent; // use your own colors
const _highColor = Colors.yellow;
Color _field1Color = _lowColor;
Focus(
onFocusChange: (hasFocus) {
setState(() =>
_field1Color = hasFocus ? _highColor : _lowColor)
);
},
child: TextFormField(
obscureText: (textType == "password") ? true : false,
controller: (controller != null) ? controller : null,
focusNode: _thisFocus,
validator: (value) => (value.isEmpty) ? "Enter the Text" : null,
style: _inputStyle,
onFieldSubmitted: (String v) => {
if (onFieldSubmitted != null) {
onFieldSubmitted(v)
}
},
decoration: InputDecoration(
labelText: placeHolder,
labelStyle: _labelStyle,
filled: true,
fillColor: _field1Color,
contentPadding: EdgeInsets.only(top: 4,bottom: 4,left: 6,right: 6),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xffE8E8E8), width: 1.0),
borderRadius: BorderRadius.circular(10)
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff3FC4FF), width: 1.0),
borderRadius: BorderRadius.circular(10)
)
),
),
),
I have tried to understand your questions and provide you with a better option to design. Do try it out and revert me how do you feel, you can customise it if you like.
Click here to see the design
Container inputBox(String tabName,bool hidePassword){
return Container(
height: 50,
margin: EdgeInsets.symmetric(vertical: 15.0, horizontal: 54.0,),
child: TextField(
obscureText: hidePassword,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xFF579FAF), width: 2.0),
borderRadius: BorderRadius.circular(7.0),
),
labelText: tabName,
labelStyle: TextStyle(color: Colors.white),
contentPadding: EdgeInsets.symmetric(horizontal: 20),
focusedBorder:OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFF579FAF), width: 2.0),
borderRadius: BorderRadius.circular(7.0),
),
),
)
);
}
Resolved the problem.
I modified the background of TextField to change it using focus value.
fillColor: _focusNode.hasFocus ? _focusColor : _normalColor,
I have a TextField widget to add players in a List. But I want the keyboard to stay focus when I add players, and on submit, my keyboard keeps loosing focus.. Any Idea ?
Here is my TextField widget:
TextField(
textCapitalization: TextCapitalization.words,
onChanged: (val) => playerName = val.trim(),
onSubmitted: (val) {
if (playerName != null && playerName != '') {
Provider.of<PlayerProvider>(context, listen: false).addPlayer(playerName);
HapticFeedback.lightImpact();
}
},
maxLength: 19,
autocorrect: false,
decoration: new InputDecoration(
counterText: "",
border: new OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
filled: true,
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
hintStyle: GoogleFonts.rubik(color: Colors.grey[500], fontWeight: FontWeight.bold),
hintText: AppLocalizations.of(context).translate('player_selection_page_hint'),
fillColor: Colors.white),
)
By the way, the autofocus: true works but it kinda unFocus the keyboard and give the focus back instantly... So it's not nice to watch. So If you have another idea please.
I think you should try using FocusNode.
class MyCustomForm extends StatefulWidget {
#override
_MyCustomFormState createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the form.
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
FocusNode myFocusNode;
#override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
#override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return TextField(
focusNode: myFocusNode
textCapitalization: TextCapitalization.words,
onChanged: (val) => playerName = val.trim(),
onSubmitted: (val) {
if (playerName != null && playerName != '') {
Provider.of<PlayerProvider>(context, listen: false).addPlayer(playerName);
HapticFeedback.lightImpact();
}
myFocusNode.requestFocus();
},
maxLength: 19,
autocorrect: false,
decoration: new InputDecoration(
counterText: "",
border: new OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
filled: true,
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
hintStyle: GoogleFonts.rubik(color: Colors.grey[500], fontWeight: FontWeight.bold),
hintText: AppLocalizations.of(context).translate('player_selection_page_hint'),
fillColor: Colors.white),
);
}
}
Well, you can go with FocusNode.
But I have a workaround for this.
I usually set the
autovalidate:true
and in validator always return some text.
So whenever the user clicks on the textfield it never loses the focus.
Thus the flutter always keeps the focus on the text field.
But for this, you've to use TextFormField.
But the correct way is to go with FocusNode.
Here's the Code.
TextFormField (
autovalidate : true
validator: (value) {
return '';
},
textCapitalization: TextCapitalization.words,
onChanged: (val) => playerName = val.trim(),
onSaved: (val) {
if (playerName != null && playerName != '') {
Provider.of<PlayerProvider>(context, listen: false).addPlayer(playerName);
HapticFeedback.lightImpact();
}
},
maxLength: 19,
autocorrect: false,
decoration: new InputDecoration(
counterText: "",
border: new OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
filled: true,
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
hintStyle: GoogleFonts.rubik(color: Colors.grey[500], fontWeight: FontWeight.bold),
hintText: AppLocalizations.of(context).translate('player_selection_page_hint'),
fillColor: Colors.white),
)
and then you can use this to call the onSaved method
_formKey.currentState.save(); // And it will call the onSaved method
Here the _formKey
Form(
key: _formKey,
child: Widget(),
),
Wrap the whole widget tree where your textformfield is present.
I cant get the textfield labeltext to show. anyone can help? and how do I get the border to always showing and not disappear when I click on the text field.
#override
Widget build(BuildContext context) {
return TextFormField(
controller: _controller,
decoration: InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(width: 1)
),
// hintText: _hintText,
labelText: "Label Text",
contentPadding: EdgeInsets.only(left: 15),
// suffixText: _nameLength.toString() + "/ " + _maxLength.toString(),
// suffixStyle: TextStyle(fontSize: 12),
// suffixStyle: TextStyle(color: Theme.of(context).textTheme.bodyText2.color),
// counterText: "",
),
maxLines: _maxLines,
textCapitalization: TextCapitalization.sentences,
cursorRadius: Radius.circular(10),
keyboardType: TextInputType.text,
autofocus: true,
maxLength: _showTextCount ? _maxLength : null,
style: TextStyle(color: AppSetting.textColor1),
validator: (val) {
// if (val.isEmpty) {
// return 'Please enter text.';
// }
// return null;
},
onChanged: (val) {
_onChanged(val);
setState(() {
_inputFieldText = val;
_nameLength = _inputFieldText.length;
});
},
onTap: () => AppSetting.hapticFeeback(),
);
}
}
You should add
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.redAccent,
width: 2.0,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: primaryColor,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black54,
width: 2.0,
),
),
),
Just make sure the default value of labelColor of the input decoration is different from background (the default label color was white in my case). In order to show border when clicked set focusedBorder property.