TextFormField(
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp('[a-zA-Z]')),
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
],
maxLength: 2,
controller: controller,
),
),
I want to prevent the user from entering a number greater than 12 in the TextFormField. It can only write numbers between 1-12(including 12).
CodePudding user response:
You could try with this custom formatter:
TextFormField(
inputFormatters: [
TextInputFormatter.withFunction((oldValue, newValue) {
if (newValue.text == '') return newValue;
final i = int.tryParse(newValue.text);
if (i == null) return oldValue;
if (i > 12) return newValue.copyWith(text: '12', selection: const TextSelection.collapsed(offset: 2));
return newValue;
})
],
maxLength: 2,
)
CodePudding user response:
try This one its one help to you
TextField(
controller: textEditingEventController,
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp('[a-zA-Z]')),
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
],
onChanged: (val) {
if (int.parse(((val.isEmpty) ? '00' : (val))) > 60) {
textEditingEventController.text = '12';
}
textEditingEventController.value = TextEditingValue(
text: textEditingEventController.text,
selection: TextSelection.fromPosition(
TextPosition(
offset: textEditingEventController
.value.selection.baseOffset),
),
);
textEditingEventController.selection =
TextSelection.fromPosition(TextPosition(
offset:
textEditingEventController.text.length));
},
),
CodePudding user response:
You have to define a custom formatter, check this answer
class LimitRangeTextInputFormatter extends TextInputFormatter {
LimitRangeTextInputFormatter(this.min, this.max, {this.defaultIfEmpty = false}) : assert(min < max);
final int min;
final int max;
final bool defaultIfEmpty;
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
int? value = int.tryParse(newValue.text);
String? enforceValue;
if(value != null) {
if (value < min) {
enforceValue = min.toString();
} else if (value > max) {
enforceValue = max.toString();
}
}
else{
if(defaultIfEmpty) {
enforceValue = min.toString();
}
}
// filtered interval result
if(enforceValue != null){
return TextEditingValue(text: enforceValue, selection: TextSelection.collapsed(offset: enforceValue.length));
}
// value that fit requirements
return newValue;
}
}
You can also achieve like this, not sure it is the best way but the idea it to use a dialog to prevent user and force the previous value if it does not fit requirements you want.
onChanged: (String value) async {
if (value.isEmpty || int.tryParse(value) > 12) {
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error '),
content: const Text('must be defined and lower than 12.'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('OK'),
),
],
);
},
);
// force old value
controller.text = oldValue;
return;
}
},
CodePudding user response:
You can still use regex like this one
FilteringTextInputFormatter.allow(RegExp(r'^([1][0-2]?|[1-9])$'))
But it is better to use onChange in text field and create function to check if value is > 12
CodePudding user response:
You can use TextFormField as
TextFormField(
decoration: const InputDecoration(
counterText: "",
),
controller: textEditingController,
maxLength: 2,
)
And TextEditing Controller
final textEditingController = TextEditingController();
@override
void initState() {
super.initState();
EditingController();
}
EditingController() {
textEditingController.addListener(() {
var value =textEditingController.text;
if (int.parse(value) > 12) {
textEditingController.clear();
}
});
}