How to use Pinput widget in flutter? - flutter

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.

Related

How to achieve the best UX with Flutter form AutovalidateMode

I am trying to achieve the best UX on Flutter using AutovalidateMode.onUserInteraction.
Option 1
When I set the validation on the form key, when a user tries to type one one texField the whole form goes red with errors.
child: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
Option 2
When I set AutovalidateMode.onUserInteraction on each text field I end up getting the error on each textfield when the user tries to type and it disappears when they complete the input.
RoundedPasswordResetField(
validator: (value) {
if (value.isEmpty) {
return 'Please Re-enter Password';
}
if (password != confirmpassword) {
return "Password does not match";
}
//
return null;
},
autovalidateMode: AutovalidateMode.onUserInteraction,
hintText: "Please Re-enter Password",
onChanged: (value) {
confirmpassword = value;
},
),
Option 3
When I set it to autovalidateMode: AutovalidateMode.disabled,, when the user tries to submit the fields when they are empty, the errors appear, but when they key in the specific correct details the errors don't clear out
RoundedPasswordResetField(
validator: (value) {
if (value.isEmpty) {
return 'Please Re-enter Password';
}
if (password != confirmpassword) {
return "Password does not match";
}
//
return null;
},
autovalidateMode: AutovalidateMode.disabled,
hintText: "Please Re-enter Password",
onChanged: (value) {
confirmpassword = value;
},
),
How can I use setState, so that when the user starts typing the errors wont be shown immediately, and shown when they complete inputting wrong details - and achieve the best UX?
This is something I implemented in one of my Android projects two years ago. Although, it was Kotlin, still I opened my Github and looked for it.
First, let's understand your question: The question says that Autovalidate mode shouldn't be there or should be left to default (AutovalidateMode.disabled) to not do the validation whenever user starts typing which is obviously a bad UX. But, it should work only after the user stops with enough delay to consider it as completion of typing which means whenever there is a brief stoppage in the input data stream.
Now, for this, PublishProcessor.debounce() of RxJava is a good option in Kotlin, which can be used in dart using packages like rxdart. What it does is it prevents continuous execution of a function and only executes the function after a certain delay, if the function is triggered again, it resets the delay. So, the funtion executes only once and that too, only after a certain delay imitating the effect of user stopped typing.
Use this - Just Debounce It package, it's not as over-kill as RxDart but still, there are many alternatives.
Implement it as
void function validateForm() {
Debounce.seconds(2, //2 means run this function only after 2 second delay.
() => formKey.currentState.validate()) //This is a function passed as a Callback which is executed only when it crosses the delay.
}
And call this function from onChanged as:
onChanged: (val) => validateForm()
That's it. Now, your form will only be validated if the user stops typing. This is the go-to way, not just good UX but good logic. There are hacks to make this work with booleans and postDelayed but that's bad code.

value.isEmpty is throwing error in when i try to compile the code

TextFormField(
obscureText: true,
decoration: InputDecoration(
hintText: "Enter password",
labelText: "Password",
),
validator: (value) {
if (value.isEmpty) {
return "Password can't be empty";
}
null;
},
),
I am watching a tutorial of flutter and i know its too basic but seems like , I can't fix this error I tried to search it but there is no proper guide to fix can someone help me in fixing this
when its working fine on tutorial but not for me , and i don't get it yet its showing The property 'isEmpty' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!').
this error
This is because value is of type String? and can be null. In you case you have to check if value is null.
TextFormField(
obscureText: true,
decoration: InputDecoration(
hintText: "Enter password",
labelText: "Password",
),
validator: (String? value) {
if (value!.isEmpty) {
return "Password can't be empty";
}
null;
},
),
Welcome to stackoverflow and flutter. Recently flutter has been updated to flutter 2.0, which has a great feature called null safety. It is a little annoying to get started with, but has huge benefits I am sure you can find better listed elsewhere. Since null safety has recently come out, its not in most tutorials. Its job is to ensure that whenever there is a chance for a value to be null, it asks you to either say
A. Check if the value is becoming null. If it is, give an error and cancel the function
B. Allow the value to be null because you are going to be keeping track.\
In your case, the variable value in the onchanged method may be null because the flutter people who wrote it, used the B part mentioned above for their internal building. So, what you have to do is, the A part, that is checking if the value is null or not. You can simply do that with the help of an !. Now, you have to be careful on how to use this. Whenever a variable can be null and you have to perform a function on it or assign it to a variable which cannot be null, you just put an exclamation mark after it. Like value!\
I would recommend watching a good video on null safety in flutter and learn about it since I doubt you will find a good tutorial as of now that includes null safety (except the docs ofc). if you need any help please feel free to leave a comment and I'll be happy to help in any way possible

Flutter: detect if a string can be converted to double

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.

Validator text too long. Only parts of it showing

I am trying to add validation too my password text form field in my app in flutter. The problem is that my validator text is too long so only parts of it shows on the screen. Is there any way to make the text form field below it automatically slide down so the whole validation text is shown?
The text form fields are placed in a column inside a form.
Appreciate any help,
Cheers!
This code will work for you.
TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
validator: (value) {
print(value);
return null;
},
),

Allow Only lowercase with no space Input Textfield Flutter

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