Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Validations in TextField #631

Closed
ipritom opened this issue Nov 25, 2022 · 11 comments · Fixed by #2101
Closed

Dynamic Validations in TextField #631

ipritom opened this issue Nov 25, 2022 · 11 comments · Fixed by #2101

Comments

@ipritom
Copy link

ipritom commented Nov 25, 2022

How can I add validations in a TextField?

My Use cases:
TextField for username which won't allow space in a text.

TextField for number input which won't allow non-numeric input.

@ndonkoHenri
Copy link
Contributor

@FeodorFitsner
Copy link
Contributor

There is no built-in validation mechanism into TextField control, but you can implement that in your program using TextField.on_change or TextField.on_blur events and set TextField.error_text into non-empty string to make it red.

@ndonkoHenri
Copy link
Contributor

Onchange is called after the keyboard value has been inserted into the field.

It will look ugly to let the user see his text be inputted, then see it removed.

Think of it...we need in-built validators or the ability to overwrite the method of TextField inserting the the text.

See kivy example: https://kivy.org/doc/stable/api-kivy.uix.textinput.html#filtering

@JWDT
Copy link

JWDT commented Dec 7, 2022

@ndonkoHenri - I've tried a quick implementation of a filter by using on_change, and it appears to be almost fast enough (at least in a test case) that it doesn't render the character to the screen before removing it.

The problem I had though was changing the control.value then doing page.update() would move the cursor back to the start of the text input, so for example, if "a" was being filtered out, typing the word "bad" would result in "db" instead of "bd".

Validation in the same way web browsers tend to do it, i.e. allowing you to type anything you want into the box, then checking it and simply complaining (as @FeodorFitsner is suggesting), and perhaps blocking any type of "submit" action looks to be a workable solution that users might be more familiar with.

I know I would be more frustrated with an app for ignoring my input -- or worse, changing something I pasted in -- than it telling me the input isn't valid and letting me fix it (or even having a button to filter it for me after I've typed what I want).

@ndonkoHenri
Copy link
Contributor

That's right.
That approach sounds better to me now, after reading your comment.

@FeodorFitsner
Copy link
Contributor

I know I would be more frustrated with an app for ignoring my input -- or worse, changing something I pasted in...

Yeah, you are trying to type something into the field and it doesn't respond and then after a few minutes you like "oh, it's a numeric field!". Agree, showing validation errors on blur or submit is more user friendly.

@wpritom
Copy link

wpritom commented Dec 10, 2022

@ndonkoHenri - I've tried a quick implementation of a filter by using on_change, and it appears to be almost fast enough (at least in a test case) that it doesn't render the character to the screen before removing it.

@JWDT, would you please share your implementation with us?

@JWDT
Copy link

JWDT commented Dec 10, 2022

@wpritom

import flet as ft

def main(page: ft.Page):
    def text_filter(e):
        bad_chars = "1234567890"
        output = ""
        for char in e.control.value:
            if char not in bad_chars:
                output += char
        e.control.value = output
        page.update()

    page.add(ft.TextField(helper_text="No numbers!", on_change=text_filter))

ft.app(target=main)

Not sure on the efficiency of it since it's looping through the whole text value every time, but I didn't notice it leave the number characters in long enough to be able to read it.

Again, this still shoots the cursor back to the start (only if it changes the e.control.value, though), which means it will mess up the whole sentence if there's a number (or any other bad character) in there.

@AleHS-99
Copy link

AleHS-99 commented Aug 11, 2023

def control_notas1(e):
try:
nota_1 = self.continer.content.controls[0].content.controls[7].controls[1].value
if nota_1[-1].isdigit():
if int(nota_1)>25:
self.continer.content.controls[0].content.controls[7].controls[1].value = '25'
self.continer.content.controls[0].content.controls[7].controls[1].update()
else:
nota_1 = nota_1[:-1]
if nota_1 == "":
self.continer.content.controls[0].content.controls[7].controls[1].value = ""
self.continer.content.controls[0].content.controls[7].controls[1].update()
else:
self.continer.content.controls[0].content.controls[7].controls[1].value = nota_1
self.continer.content.controls[0].content.controls[7].controls[1].update()
except Exception as i:
print("Se produjo un error:", i)

My TextField
TextField(label='Cumplimiento y calidad del contenido de trabajo (25 ptos):',width=int((self.ancho-500)/2-95),color='white',
border_color='primary',border_radius=8, on_change=control_notas1),
I’m trying to implement the on change method in my TextField. When I enter the values it does what it’s supposed to do but it blocks the window and finally closes it after a few seconds. I also tried with page.update but it doesn’t work.

@ndonkoHenri
Copy link
Contributor

ndonkoHenri commented Aug 16, 2023

This is from chatgpt, what do you think @FeodorFitsner? :

To achieve this in Flutter, you can use an inputFormatters property with a list of TextInputFormatter objects.

Here's how you can prevent users from entering numbers in a text field:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // Import for TextInputFormatter

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Input Filtering Example')),
        body: MyForm(),
      ),
    );
  }
}

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextFormField(
          inputFormatters: [FilteringTextInputFormatter.deny(RegExp(r'\d'))], // Deny numbers
          decoration: InputDecoration(labelText: 'Text without Numbers'),
        ),
      ],
    );
  }
}

In this example, the TextFormField is configured with an inputFormatters property that takes a list of TextInputFormatter objects. The FilteringTextInputFormatter.deny(RegExp(r'\d')) is used to deny any input that matches the regular expression \d, which represents numbers.

This way, when the user tries to enter a number in the text field, it will be automatically filtered out and won't be accepted.

You can adjust the regular expression or use different formatters based on your specific filtering needs. The TextInputFormatter class provides various formatter options for different use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants