Skip to main content
Input controls allow users to enter data, make selections, and interact with your Flet application. Both Material and Cupertino design systems provide comprehensive input controls.

Text Input

TextField

Material text input field

CupertinoTextField

iOS-style text input field

Material TextField

import flet as ft

def main(page: ft.Page):
    def on_text_change(e):
        print(f"Text changed: {e.control.value}")
    
    def on_submit(e):
        print(f"Submitted: {e.control.value}")
    
    page.add(
        # Basic text field
        ft.TextField(
            label="Name",
            hint_text="Enter your full name",
            helper_text="This will be your display name",
            on_change=on_text_change,
        ),
        # Password field
        ft.TextField(
            label="Password",
            password=True,
            can_reveal_password=True,
        ),
        # Email with validation
        ft.TextField(
            label="Email",
            keyboard_type=ft.KeyboardType.EMAIL,
            autocorrect=False,
            prefix_icon=ft.Icons.EMAIL,
        ),
        # Multiline text
        ft.TextField(
            label="Bio",
            multiline=True,
            min_lines=3,
            max_lines=5,
            max_length=200,
        ),
        # With submit handler
        ft.TextField(
            label="Search",
            suffix_icon=ft.Icons.SEARCH,
            on_submit=on_submit,
        ),
    )

ft.app(target=main)

Cupertino TextField

import flet as ft
from flet import cupertino_icons

def main(page: ft.Page):
    page.add(
        ft.CupertinoTextField(
            placeholder_text="Search",
            prefix=ft.Icon(cupertino_icons.SEARCH),
            clear_button_visibility_mode=ft.OverlayVisibilityMode.EDITING,
        ),
        ft.CupertinoTextField(
            placeholder_text="Username",
            prefix=ft.Icon(cupertino_icons.PERSON),
        ),
        ft.CupertinoTextField(
            placeholder_text="Password",
            password=True,
            prefix=ft.Icon(cupertino_icons.LOCK),
        ),
    )

ft.app(target=main)

TextField Properties

import flet as ft

def validate_email(e):
    field = e.control
    if "@" not in field.value:
        field.error_text = "Please enter a valid email"
    else:
        field.error_text = None
    field.update()

email_field = ft.TextField(
    label="Email",
    on_change=validate_email,
)

Buttons

ElevatedButton

Raised Material button

FilledButton

Filled Material button

OutlinedButton

Outlined Material button

TextButton

Flat text button

IconButton

Button with only an icon

FloatingActionButton

Floating action button

Button Examples

import flet as ft

def main(page: ft.Page):
    def button_clicked(e):
        print(f"Button clicked: {e.control.text}")
    
    page.add(
        # Standard buttons
        ft.ElevatedButton(
            "Elevated",
            icon=ft.Icons.ADD,
            on_click=button_clicked,
        ),
        ft.FilledButton(
            "Filled",
            icon=ft.Icons.SEND,
            on_click=button_clicked,
        ),
        ft.OutlinedButton(
            "Outlined",
            icon=ft.Icons.EDIT,
            on_click=button_clicked,
        ),
        ft.TextButton(
            "Text",
            icon=ft.Icons.INFO,
            on_click=button_clicked,
        ),
        # Icon button
        ft.IconButton(
            icon=ft.Icons.FAVORITE,
            icon_color=ft.Colors.PINK,
            tooltip="Like",
            on_click=lambda e: print("Liked!"),
        ),
        # Disabled button
        ft.ElevatedButton(
            "Disabled",
            disabled=True,
        ),
    )

ft.app(target=main)

Custom Button Styling

import flet as ft

ft.ElevatedButton(
    "Custom Style",
    style=ft.ButtonStyle(
        color=ft.Colors.WHITE,
        bgcolor=ft.Colors.BLUE,
        padding=20,
        shape=ft.RoundedRectangleBorder(radius=10),
    ),
)

Selection Controls

Checkbox

Binary checkbox selection

Radio

Single choice from group

Switch

Toggle switch

Dropdown

Dropdown selection

Checkbox

import flet as ft

def main(page: ft.Page):
    def checkbox_changed(e):
        print(f"Checkbox value: {e.control.value}")
    
    page.add(
        ft.Checkbox(
            label="I agree to the terms",
            value=False,
            on_change=checkbox_changed,
        ),
        ft.Checkbox(
            label="Indeterminate state",
            tristate=True,
            value=None,
        ),
    )

ft.app(target=main)

Radio

import flet as ft

def main(page: ft.Page):
    def radio_changed(e):
        print(f"Selected: {e.control.value}")
    
    page.add(
        ft.RadioGroup(
            content=ft.Column([
                ft.Radio(value="option1", label="Option 1"),
                ft.Radio(value="option2", label="Option 2"),
                ft.Radio(value="option3", label="Option 3"),
            ]),
            on_change=radio_changed,
        )
    )

ft.app(target=main)

Switch

import flet as ft

def main(page: ft.Page):
    def switch_changed(e):
        print(f"Switch: {e.control.value}")
    
    page.add(
        ft.Switch(
            label="Enable notifications",
            value=True,
            on_change=switch_changed,
        ),
        ft.CupertinoSwitch(
            label="iOS Style",
            value=False,
            on_change=switch_changed,
        ),
    )

ft.app(target=main)
import flet as ft

def main(page: ft.Page):
    def dropdown_changed(e):
        print(f"Selected: {e.control.value}")
    
    page.add(
        ft.Dropdown(
            label="Country",
            hint_text="Select your country",
            options=[
                ft.dropdown.Option("US", "United States"),
                ft.dropdown.Option("UK", "United Kingdom"),
                ft.dropdown.Option("CA", "Canada"),
                ft.dropdown.Option("AU", "Australia"),
            ],
            on_change=dropdown_changed,
        )
    )

ft.app(target=main)

Sliders

Slider

Single value slider

RangeSlider

Range selection slider

Slider Example

import flet as ft

def main(page: ft.Page):
    def slider_changed(e):
        slider_value.value = f"Value: {int(e.control.value)}"
        slider_value.update()
    
    slider_value = ft.Text("Value: 50")
    
    page.add(
        ft.Slider(
            min=0,
            max=100,
            value=50,
            divisions=10,
            label="{value}",
            on_change=slider_changed,
        ),
        slider_value,
        ft.CupertinoSlider(
            min=0,
            max=100,
            value=30,
            on_change=lambda e: print(f"iOS Slider: {e.control.value}"),
        ),
    )

ft.app(target=main)

RangeSlider Example

import flet as ft

def main(page: ft.Page):
    def range_changed(e):
        range_text.value = f"Range: {int(e.control.start_value)} - {int(e.control.end_value)}"
        range_text.update()
    
    range_text = ft.Text("Range: 20 - 80")
    
    page.add(
        ft.RangeSlider(
            min=0,
            max=100,
            start_value=20,
            end_value=80,
            divisions=10,
            on_change=range_changed,
        ),
        range_text,
    )

ft.app(target=main)

Date and Time Pickers

DatePicker

Pick a date from calendar

TimePicker

Select time

DatePicker Example

import flet as ft
import datetime

def main(page: ft.Page):
    def date_picked(e):
        selected_date.value = f"Selected: {e.control.value.strftime('%Y-%m-%d')}"
        selected_date.update()
    
    selected_date = ft.Text("No date selected")
    
    date_picker = ft.DatePicker(
        first_date=datetime.datetime(2020, 1, 1),
        last_date=datetime.datetime(2030, 12, 31),
        on_change=date_picked,
    )
    
    page.overlay.append(date_picker)
    
    page.add(
        ft.ElevatedButton(
            "Pick Date",
            icon=ft.Icons.CALENDAR_MONTH,
            on_click=lambda _: date_picker.pick_date(),
        ),
        selected_date,
    )

ft.app(target=main)

TimePicker Example

import flet as ft

def main(page: ft.Page):
    def time_picked(e):
        selected_time.value = f"Selected: {e.control.value}"
        selected_time.update()
    
    selected_time = ft.Text("No time selected")
    
    time_picker = ft.TimePicker(
        on_change=time_picked,
    )
    
    page.overlay.append(time_picker)
    
    page.add(
        ft.ElevatedButton(
            "Pick Time",
            icon=ft.Icons.ACCESS_TIME,
            on_click=lambda _: time_picker.pick_time(),
        ),
        selected_time,
    )

ft.app(target=main)

Forms

Combine multiple input controls into forms:
import flet as ft

def main(page: ft.Page):
    def submit_form(e):
        # Validate all fields
        if not name_field.value:
            name_field.error_text = "Name is required"
            name_field.update()
            return
        
        if not email_field.value or "@" not in email_field.value:
            email_field.error_text = "Valid email is required"
            email_field.update()
            return
        
        # Process form
        print(f"Name: {name_field.value}")
        print(f"Email: {email_field.value}")
        print(f"Subscribe: {subscribe_checkbox.value}")
        
        # Show success
        page.snack_bar = ft.SnackBar(ft.Text("Form submitted!"))
        page.snack_bar.open = True
        page.update()
    
    name_field = ft.TextField(
        label="Name",
        hint_text="Your full name",
        autofocus=True,
    )
    
    email_field = ft.TextField(
        label="Email",
        keyboard_type=ft.KeyboardType.EMAIL,
    )
    
    subscribe_checkbox = ft.Checkbox(
        label="Subscribe to newsletter",
        value=True,
    )
    
    page.add(
        ft.Column([
            ft.Text("Sign Up Form", size=24, weight=ft.FontWeight.BOLD),
            name_field,
            email_field,
            subscribe_checkbox,
            ft.ElevatedButton(
                "Submit",
                on_click=submit_form,
            ),
        ])
    )

ft.app(target=main)

Input Validation Best Practices

Real-time Validation

import re

def validate_email(e):
    email = e.control.value
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    
    if not re.match(pattern, email):
        e.control.error_text = "Invalid email format"
    else:
        e.control.error_text = None
    e.control.update()

ft.TextField(
    label="Email",
    on_change=validate_email,
)

Accessible Labels

# Good: Clear labels and hints
ft.TextField(
    label="Phone Number",
    hint_text="(123) 456-7890",
    helper_text="Enter your 10-digit phone number",
)

Next Steps

API Reference

Detailed documentation:

Build docs developers (and LLMs) love