Adaptive Mask for TextField - flutter

I've made a TextField that is suppose to update the user's info.
The user has to type either 11 or 14 numbers, so the mask for the textfield has to change if someone types more than 11 numbers. How do I do that?
Masks:
var mascaraCpf = MaskTextInputFormatter(
mask: '###.###.###-##',
filter: {"#": RegExp(r'[0-9]')},
type: MaskAutoCompletionType.lazy);
var mascaraCnpj = MaskTextInputFormatter(
mask: '##.###.###/####-##',
filter: {"#": RegExp(r'[0-9]')},
type: MaskAutoCompletionType.lazy);
TextField:
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
mascaraCpf,
FilteringTextInputFormatter.digitsOnly
],
controller: cpfController,
decoration: InputDecoration(
filled: true,
fillColor: Color(0xffFCF9F4),
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(5))),
hintText: appModel.usuario!.cpf,
),
),

Do you have an StatefulWidget?
If yes, try something like the following:
onChanged: (value) {
if (value.length >= 11) {
setState(() {
//change something
});
} else {
setState(() {
//change back
});
}
}

First, make sure your screen is a stateful widget.
Then replace the textfield with the following code:
TextField(
onChanged: (value) => {
if (value.length >= 11 && value.length <= 14) //changing value if input length is more than 11 and less than 14
{
setState(() {
currentMask = mascaraCnpj;
})
}
else
{
if(currentMask != mascaraCpf) { //rebuilding screen if currentMask != mascaraCpf , otherwise it'll lead to unnecessary rebuilds
setState(() {
currentMask = mascaraCpf;
})
}
}
},
keyboardType: TextInputType.number,
inputFormatters: [currentMask, FilteringTextInputFormatter.digitsOnly],
controller: TextEditingController(),
decoration: InputDecoration(
filled: true,
fillColor: Color(0xffFCF9F4),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5))),
hintText: appModel.usuario!.cpf,
),
),

Related

How to prevent typing after some length in flutter text Field

If item Quantity is 3 then user must have to enter 3 serial # (comma Separated). I want to prevent user to type further if the comma separated string length reaches to 3. Also Backspace should also work if he wants to erase some value. Please guide me on this:
Here is My Code:
TextFormField(
cursorColor: titleTextColor,
decoration: const InputDecoration(
labelText: "Serial #",
labelStyle: TextStyle(color: appBarColor),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: appBarColor),
),
//[focusedBorder], displayed when [TextField, InputDecorator.isFocused] is true
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: appBarColor),
),
),
validator: (val) {
if (val!.isEmpty) {
return 'Required';
}
},
controller: serialsController,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
onChanged: (val) {
if (val.isNotEmpty) {
int len = val.split(",").length;
if (double.parse(len.toString()) > double.parse(itemListOrderDetail[index].LineQuantity.toString())) {
showToast("Stop", FToast().init(context));
}
}
},
)
In this case a good solution is using a mask.
Check this package easy mask
https://pub.dev/packages/easy_mask
So , when you change the qtd number u change the mask too.
Edit.
You can use onChanged prop to control too...
onChanged:(val){
if(val.split(',').length > 3){
yourController.text = val.substring(0,val.length-1);
}
} ,
Change the number 3 by your QTD var or controller

How to restrict user from entering leading spaces and imojis in name field

I have name field in profile page. I want to restrict user from adding leading spaces. But in the process what I did is the user can't put any space now. I want him to simple enter "Arjun Malhotra" and not " space space space Arjun Malhotra"......
This is the code
child: TextFormField(
inputFormatters: [
FilteringTextInputFormatter
.deny(
RegExp('[ ]')),
],
maxLength: 20,
readOnly: !edit,
controller: name,
autovalidateMode:
AutovalidateMode
.onUserInteraction,
autofocus: true,
validator: (value) {
RegExp regex =
RegExp(r'^.{3,}$');
if (value!.isEmpty) {
return ("Name can't be empty");
}
if (!regex
.hasMatch(value)) {
return ("Name can't be empty");
}
if (value.trim() ==
"") {
return ("Name can't be empty");
}
if (value
.trim()
.length <=
2) {
return ("Minimum of 3 characters Required");
}
return null;
},
onSaved: (value) {
name.text = value!;
},
onChanged: (value) {
context
.read<
ProfileDetails>()
.name = value;
},
decoration:
InputDecoration(
counterText: "",
filled: true,
fillColor: const Color(
0xFFC2E3FE),
enabledBorder:
InputBorders
.enabled,
errorBorder:
InputBorders.error,
focusedErrorBorder:
InputBorders.error,
border:
InputBorder.none,
focusedBorder:
InputBorders
.focused,
contentPadding:
const EdgeInsets
.only(
left: 30,
right: 10),
hintText: "Name",
),
),
Above code only allows this format "ArjunMalhotra". How can I achieve what I want and also I dont want user to add emojis. Is there a special keyboard type I need to specify or what?
^\s*: This will match any (*) whitespace (\s) at the beginning (^) of the text
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp(r'^\s*')),
],

TextField actions are not triggered on Android

There is a problem in Android Web Chrome. When Text inputType text or name does not work onsubmit and it is not possible to send a request. But for some reason, if you set the TextInputType.emailAddress parameter, then the submit key on the keyboard becomes a "right arrow" and everything works as it should work. What could be the reason for this behavior?
TextFormField(
enabled: isEnabled ?? true,
obscureText: isObscured ?? false,
controller: controller,
keyboardType: widget.keyboardType,
textInputAction: widget.textInputAction,
minLines: widget.minLines ?? 1,
maxLines: widget.maxLines ?? 1,
decoration: InputDecoration(
fillColor: AppColors.fieldBackground,
filled: true,
hintText: widget.hintText,
contentPadding: const EdgeInsets.only(
top: (Dimens.buttonHeight - 14) / 2,
bottom: (Dimens.buttonHeight - 14) / 2,
left: Dimens.horizontalPadding,
right: Dimens.horizontalPadding,
),
onChanged: (value) {
setState(() {
textLength = value.length;
});
},
focusNode: focusNode,
onFieldSubmitted: (query) {
if (query.length > 2 || query.isEmpty) {
serviceLocator<SearchBloc>().add(
FiltersChanged(query: query),
);
FocusScope.of(context).unfocus();
} else {
Messages.showInfoMessage(
context,
AppLocalizations.of(context)!.searchFieldShortQueryTitle,
AppLocalizations.of(context)!.searchFieldShortQueryMessage);
}
},
);
You can set the input action manually and it should work as expected
TextField(
textInputAction: TextInputAction.go,
)

How to set the value to a TextFormField in flutter

I am trying to set a value to the TextFormField in flutter.
But I couldn't find a way to do that.
this is how my widget looks like:
Widget _showHeadlineField() {
return TextFormField(
textInputAction: TextInputAction.next,
onEditingComplete: () {
FocusScope.of(context).requestFocus(_descriptionNode);
},
controller: _headlineController,
validator: (headline) {
if (headline == null || headline.isEmpty) {
return "Headline cannot be empty";
}
},
decoration: InputDecoration(
labelText: "Headline",
hintText: "Covid-19 new stats",
border: OutlineInputBorder(),
icon: Icon(Icons.add_box),
),
);
}
I even tried initialValue but doesn't work. Can someone help me?
You can use
_headlineController.text = 'Your text';
Or when you create controller :
_headlineController = TextEditingController(text: 'Your text')

How to remove label of textfield?

Would like to ask if it is possible to remove the label "Label" on top left of the text field in Flutter.
Yes, set the floatingLabelBehavior to never in InputDecoration. It worked for me.
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.never,
),
Yes, is it possible. Just remove the hintText and labelText in InputDecoration.
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(5.0),
)),
// hintText: Localization.of(context).accessLevel,
// labelText: Localization.of(context).accessLevel,
),
The following code removes the LabelText when you write anything in the TextField and shows LabelText when you do not write anything in the TextField.
TextEditingController Controller = TextEditingController();
bool ForBool = true;
TextField(
onChanged: (value) {
if (value.length <= 0) {
setState(() {
ForBool = false;
});
} else {
setState(() {
ForBool = true;
});
}
Controller.text = value;
print(value);
Controller.selection = TextSelection.fromPosition(
TextPosition(offset: Controller.text.length));
},
controller: Controller,
decoration: InputDecoration(
hintText: ForBool ? null : "Search...",
),
),
Simply Remove the labelText property in the InputDecoration.