So i am making a chat app and i want user to submit username which should not be uppercase and have space, i can accept the name and change it later in onchanged feature but i want user to know it as well
Flutter's TextField or TextFormField has attribute named inputFormatters which takes a list of TextInputFormatter.
an example of TextInputFormatters that is useful in your case.
FilteringTextInputFormatter.allow(RegExp("[a-z]"))
TextField(
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp("[a-z]")),
],
)
you can see TextInputFormatters API docs here : Reference
(before flutter 1.20):
WhitelistingTextInputFormatter(RegExp("[a-z]")),
TextField(
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter(RegExp("[a-z]")),
],
)
you can take those as reference if it's not clear enough : Reference 2, Reference 3.
Also check out this SOF Question: Reference 4
In regards to changing the text, try doing the following:
Let's say 's' is the username:
String s = ""
onChange(val) {
s = val.trim().toLowerCase()
}
If you want to notify the user, perhaps use an alert dialog with some text letting them know the username should not be uppercase and contain no spaces. Regardless, you can't assume the user will conform to what they "should do".
You can use a Form and then notify the user using the error field (Validator)
TextFormField(
validator: (name) {
Pattern pattern = r'^[a-z]+$'; // Regex for lowercase only
RegExp regex = new RegExp(pattern);
if (!regex.hasMatch(name))
return 'Username must be lowercase, this will be changed when saved';
else
return null;
},
),
FlatButton(
child: Text('Save'),
onPressed: () {
_formKey.currentState.validate(); // just check if its valid and notify user
// Other code to save the and change the value
print('Saving Username');
},
)
Dart Pad Example
Related
I am trying to make a otp field which I can fill manually and validate later. I am using the Pinput package in flutter as it is quite popular. I am facing following problems-
The pin does not start typing unless I enter a . / , in the first field
The Pinput() fields are cleared as soon as I enter the last digit.
How to use this pin and validate it later?
My code is-
Pinput(
length: 6,
keyboardType: TextInputType.number,
controller: pinController,
defaultPinTheme: defaultPinTheme,
focusedPinTheme: focusedPinTheme,
submittedPinTheme: submittedPinTheme,
pinputAutovalidateMode: null,
textInputAction: TextInputAction.next,
showCursor: true,
validator: (s) {
print('validating code: $s');
},
onCompleted: null,
),
Please help!!
Use onCompleted like this not null
onCompleted: (pin) => print(pin),
This onCompleted method do like if entering input got finish do something like navigation or check thing
When you entered last digit this will print
You need to use regex to validate just search and get what you need
// In validator you can check
Int validDigit = 1234; // this is test digit
Validator: (input){
return s == validDigit ? null : 'Pin is incorrect';
}
Validator works like if your input digit was not like the pattern you need, in this case if the input digit was not equal to the code that you send to user, you need to return error otherwise return null it means code is correct.
in above e.g the validDigit comes from api or somewhere else
And finally set auto validate like here not null:
pinputAutovalidateMode: PinputAutovalidateMode.onSubmit,
I hope it works, sorry they are not in order of your question.
While the inputFormatters is realy well explained here and works like a charm I want to let the user know about what happened to his input.
A simple snackBar or other dialog should be shown that prompts the user: "Your code has been trimmed because of unallowed signs. You are only allowed to enter numbers and letters!"
my example code shows the limitation to numbers and letters:
TextFormField( inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.allow( RegExp("[0-9a-zA-Z]"), ), ],
If the user paste a string that contains other signs they will be deleted automaticly but the user might not see that so I want to show a warning to him.
I appriciate all help.
Thanks for your answeres but I solved it on my own as follows:
The inputFormatter blocks all unallowed signs and won't show them in onChanged value of the textController but the onChanged function is triggered and stays even. So I added the following code to the onChanged: function:
onChanged: (val) {
if (count == val.length) {
showSnackBar(
context,
'You entered an unallowed sign!',
icon: Icons.warning_outlined, // this is from my own class showSnackBar which shows a Row with an optional Icon
);
}
count = val.length;
Everytime the user types an unallowed sign this warning pops up because the textcontroller changed but the value of it stays the same.
If there are parts I can do better please comment and I'll correct them.
The complete Code of the TextFormField including the inputFormatters:
First i created a variabel int count = 0;
TextFormField(
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(
RegExp("[0-9a-zA-Z]"),
),
],
obscureText: false,
controller: _controller,
decoration: InputDecoration(
labelText:
'title',
),
onChanged: (val) {
if (count == val.length) {
showSnackBar(
context,
'Unallowd sign typed in!',
icon: Icons.warning_outlined,
);
}
model.textChanged(val);
count = val.length;
},
),
Thanks
I can do something like this:
double.parse(myString)
That's fine when I have "1.1" but if I have "1.1.1" it fails with Invalid double. Could I detect this somehow in advance?
I'd need this for input validations
Working with
double.tryParse(myString)
As written above, use double.tryParse() or wrap double.parse() with try catch
An alternative, if you need to do input validation could be filter away "bad" input already when the user inputs the number.
You could change keyboard type and use input formatters on a TextField / TextFormFiel
TextField(
decoration: new InputDecoration(labelText: "Enter your number"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter> [
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
),
You could write something like this
if(!myString.contains(<someregex>)) {
double.parse(myString);
}
Where the regex is validating that the string is a valid double, the value of doing this over using tryParse is that you can include your business rule validation alongside your datatype validation.
Simple question that I'm not finding an answer to--I have a TextField that's multi-line but I don't want to allow newlines in the text. E.g., if the user is typing and hits [Enter], I don't want a newline to register in the TextField. How do I do that?
I tried catching it in the onChanged event, but got weird rendering results:
onChanged: (value) {
if (value.endsWith('\n')) {
_textController.text = value.trim();
}
},
You should try using BlacklistingTextInputFormatter in inputFormatters.
inputFormatters: [
FilteringTextInputFormatter.deny(new RegExp(r"\n"))
],
What if you use following parameters:
TextField(keyboardType: TextInputType.text, maxLines: 3,);
I've got Text field which updateds a value variable to double format in onChange... I want the TextField only display the updated the value variable.. I don't want the textfield to display any string value or values which are not in double format by pressing wrong keyboard key. Even with numeric keyboard with decimal enabled we can press decimal key multiple times which I don't want to display in the TextField.
TextFormField(
decoration: InputDecoration(labelText: 'Value'),
onChanged: (s) {
if (double.tryParse(s) != null)
setState(() {
value = double.parse(s);
});
},
)
How can I display only parsed value in TextField?
Please add below attribute to TextFormField Widget
TextFormField(
keyboardType:TextInputType.numberWithOptions(decimal: true),
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,2}'))
],
);
#user8773560 was correct however RegExp for decimal number was wrong and not working so the correct answer is
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'(^\d*\.?\d*)'))
]
Also answered in my other question Regex for double numbers in dart
Answer based on #delmin's answer, but allows negative numbers as well.
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'(^-?\d*\.?\d*)'))
]
Hello you can not use onChange for this purpose because its called only once TextField has changed.
You should try this.
TextFormField(
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(12), //max length of 12 characters
WhitelistingTextInputFormatter.digitsOnly,//Only numbers
BlacklistingTextInputFormatter.singleLineFormatter,//No line break
WhitelistingTextInputFormatter(RegExp("[0-9]+.[0-9]")) //only double values
],
)
Lear more here or Official doc