validator

Validator class changes the color of form elements to error or success based on input’s validation rules.

Base Validator

Exported source
validator = SingleValueFactory("validator", "Base validator component for input, select, textarea") # Base validator component
validator_hint = SingleValueFactory("validator-hint", "Base validator hint part for the hint text that appears after the input if it's invalid") # validator_hint component

Validator Test Examples


source

test_validator_basic_examples

 test_validator_basic_examples ()

Test basic validator utilities.

Exported source
def test_validator_basic_examples():
    """Test basic validator utilities."""
    # Basic validator
    assert str(validator) == "validator"
    assert str(validator_hint) == "validator-hint"
    
    # Test with modifiers
    assert str(validator.hover) == "hover:validator"
    assert str(validator.md) == "md:validator"
    assert str(validator.dark) == "dark:validator"

    assert str(validator_hint.hover) == "hover:validator-hint"
    assert str(validator_hint.md) == "md:validator-hint"
    assert str(validator_hint.dark) == "dark:validator-hint"

# Run the tests
test_validator_basic_examples()

source

test_validator_basic_fasthtml_examples

 test_validator_basic_fasthtml_examples ()

Test basic validator example from daisyUI v5 documentation.

Exported source
def test_validator_basic_fasthtml_examples():
    """Test basic validator example from daisyUI v5 documentation."""
    from fasthtml.common import Input
    from cjm_fasthtml_daisyui.components.data_input.text_input import text_input
    
    # Basic validator
    basic_validator = Input(
        type="email",
        required=True,
        placeholder="[email protected]",
        cls=combine_classes(text_input, validator)
    )
    
    # Verify structure
    assert basic_validator.tag == "input"
    assert basic_validator.attrs['type'] == "email"
    assert basic_validator.attrs['required'] == True
    assert basic_validator.attrs['placeholder'] == "[email protected]"
    assert "input" in basic_validator.attrs['class']
    assert "validator" in basic_validator.attrs['class']
    
    return basic_validator

# Run the tests
test_validator_basic_fasthtml_examples()
<input type="email" required placeholder="[email protected]" class="input validator">
test_func = test_validator_basic_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_validator_with_hint_fasthtml_examples

 test_validator_with_hint_fasthtml_examples ()

Test validator with hint from daisyUI v5 documentation.

Exported source
def test_validator_with_hint_fasthtml_examples():
    """Test validator with hint from daisyUI v5 documentation."""
    from fasthtml.common import Input, Div
    from cjm_fasthtml_daisyui.components.data_input.text_input import text_input
    
    # Validator with validator-hint
    email_with_hint = Div(
        Input(
            type="email",
            required=True,
            placeholder="[email protected]",
            cls=combine_classes(text_input, validator)
        ),
        Div(
            "Enter valid email address",
            cls=str(validator_hint)
        )
    )
    
    # Verify structure
    container = email_with_hint
    assert container.tag == "div"
    assert len(container.children) == 2
    
    # Verify input
    input_elem = container.children[0]
    assert input_elem.tag == "input"
    assert input_elem.attrs['type'] == "email"
    assert input_elem.attrs['required'] == True
    assert input_elem.attrs['placeholder'] == "[email protected]"
    assert "input" in input_elem.attrs['class']
    assert "validator" in input_elem.attrs['class']
    
    # Verify hint
    hint_elem = container.children[1]
    assert hint_elem.tag == "div"
    assert hint_elem.attrs['class'] == "validator-hint"
    assert hint_elem.children[0] == "Enter valid email address"
    
    return email_with_hint

# Run the tests
test_validator_with_hint_fasthtml_examples()
<div>
  <input type="email" required placeholder="[email protected]" class="input validator">
  <div class="validator-hint">Enter valid email address</div>
</div>
test_func = test_validator_with_hint_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_validator_password_fasthtml_examples

 test_validator_password_fasthtml_examples ()

Test password requirement validator from daisyUI v5 documentation.

Exported source
def test_validator_password_fasthtml_examples():
    """Test password requirement validator from daisyUI v5 documentation."""
    from fasthtml.common import Input, P, Br, Div
    from cjm_fasthtml_daisyui.components.data_input.text_input import text_input
    
    # Password requirement validator
    password_validator = Div(
        Input(
            type="password",
            required=True,
            placeholder="Password",
            minlength="8",
            pattern="(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}",
            title="Must be more than 8 characters, including number, lowercase letter, uppercase letter",
            cls=combine_classes(text_input, validator)
        ),
        P(
            "Must be more than 8 characters, including",
            Br(),
            "At least one number",
            Br(),
            "At least one lowercase letter",
            Br(),
            "At least one uppercase letter",
            cls=str(validator_hint)
        )
    )
    
    # Verify structure
    container = password_validator
    assert container.tag == "div"
    assert len(container.children) == 2
    
    # Verify password input
    password_input = container.children[0]
    assert password_input.tag == "input"
    assert password_input.attrs['type'] == "password"
    assert password_input.attrs['required'] == True
    assert password_input.attrs['placeholder'] == "Password"
    assert password_input.attrs['minlength'] == "8"
    assert password_input.attrs['pattern'] == "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
    assert password_input.attrs['title'] == "Must be more than 8 characters, including number, lowercase letter, uppercase letter"
    assert "input" in password_input.attrs['class']
    assert "validator" in password_input.attrs['class']
    
    # Verify hint
    hint = container.children[1]
    assert hint.tag == "p"
    assert hint.attrs['class'] == "validator-hint"
    assert hint.children[0] == "Must be more than 8 characters, including"
    assert hint.children[1].tag == "br"
    assert hint.children[2] == "At least one number"
    assert hint.children[3].tag == "br"
    assert hint.children[4] == "At least one lowercase letter"
    assert hint.children[5].tag == "br"
    assert hint.children[6] == "At least one uppercase letter"
    
    return password_validator

# Run the tests
test_validator_password_fasthtml_examples()
<div>
  <input type="password" required placeholder="Password" minlength="8" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" class="input validator" title="Must be more than 8 characters, including number, lowercase letter, uppercase letter">
  <p class="validator-hint">
Must be more than 8 characters, including<br>At least one number<br>At least one lowercase letter<br>At least one uppercase letter  </p>
</div>
test_func = test_validator_password_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_validator_username_phone_fasthtml_examples

 test_validator_username_phone_fasthtml_examples ()

Test username and phone requirement validators from daisyUI v5 documentation.

Exported source
def test_validator_username_phone_fasthtml_examples():
    """Test username and phone requirement validators from daisyUI v5 documentation."""
    from fasthtml.common import Input, P, Br, Div
    from cjm_fasthtml_daisyui.components.data_input.text_input import text_input
    from cjm_fasthtml_tailwind.utilities.typography import tabular_nums
    
    # Username requirement validator
    username_validator = Div(
        Input(
            type="text",
            required=True,
            placeholder="Username",
            pattern="[A-Za-z][A-Za-z0-9\\-]*",
            minlength="3",
            maxlength="30",
            title="Only letters, numbers or dash",
            cls=combine_classes(text_input, validator)
        ),
        P(
            "Must be 3 to 30 characters",
            Br(),
            "containing only letters, numbers or dash",
            cls=str(validator_hint)
        )
    )
    
    # Phone Number requirement validator
    phone_validator = Div(
        Input(
            type="tel",
            required=True,
            placeholder="Phone",
            pattern="[0-9]*",
            minlength="10",
            maxlength="10",
            title="Must be 10 digits",
            cls=combine_classes(text_input, validator, tabular_nums)
        ),
        P(
            "Must be 10 digits",
            cls=str(validator_hint)
        )
    )
    
    # Verify username validator structure
    assert username_validator.tag == "div"
    assert len(username_validator.children) == 2
    
    username_input = username_validator.children[0]
    assert username_input.tag == "input"
    assert username_input.attrs['type'] == "text"
    assert username_input.attrs['required'] == True
    assert username_input.attrs['placeholder'] == "Username"
    assert username_input.attrs['pattern'] == "[A-Za-z][A-Za-z0-9\\-]*"
    assert username_input.attrs['minlength'] == "3"
    assert username_input.attrs['maxlength'] == "30"
    assert username_input.attrs['title'] == "Only letters, numbers or dash"
    assert "input" in username_input.attrs['class']
    assert "validator" in username_input.attrs['class']
    
    username_hint = username_validator.children[1]
    assert username_hint.tag == "p"
    assert username_hint.attrs['class'] == "validator-hint"
    assert username_hint.children[0] == "Must be 3 to 30 characters"
    assert username_hint.children[1].tag == "br"
    assert username_hint.children[2] == "containing only letters, numbers or dash"
    
    # Verify phone validator structure
    assert phone_validator.tag == "div"
    assert len(phone_validator.children) == 2
    
    phone_input = phone_validator.children[0]
    assert phone_input.tag == "input"
    assert phone_input.attrs['type'] == "tel"
    assert phone_input.attrs['required'] == True
    assert phone_input.attrs['placeholder'] == "Phone"
    assert phone_input.attrs['pattern'] == "[0-9]*"
    assert phone_input.attrs['minlength'] == "10"
    assert phone_input.attrs['maxlength'] == "10"
    assert phone_input.attrs['title'] == "Must be 10 digits"
    assert "input" in phone_input.attrs['class']
    assert "validator" in phone_input.attrs['class']
    assert "tabular-nums" in phone_input.attrs['class']
    
    phone_hint = phone_validator.children[1]
    assert phone_hint.tag == "p"
    assert phone_hint.attrs['class'] == "validator-hint"
    assert phone_hint.children[0] == "Must be 10 digits"
    
    return Div(username_validator, phone_validator)

# Run the tests
test_validator_username_phone_fasthtml_examples()
<div>
  <div>
    <input type="text" required placeholder="Username" pattern="[A-Za-z][A-Za-z0-9\-]*" minlength="3" maxlength="30" class="input validator" title="Only letters, numbers or dash">
    <p class="validator-hint">
Must be 3 to 30 characters<br>containing only letters, numbers or dash    </p>
  </div>
  <div>
    <input type="tel" required placeholder="Phone" pattern="[0-9]*" minlength="10" maxlength="10" class="input validator tabular-nums" title="Must be 10 digits">
    <p class="validator-hint">Must be 10 digits</p>
  </div>
</div>
test_func = test_validator_username_phone_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_validator_url_date_number_fasthtml_examples

 test_validator_url_date_number_fasthtml_examples ()

Test URL, date, and number requirement validators from daisyUI v5 documentation.

Exported source
def test_validator_url_date_number_fasthtml_examples():
    """Test URL, date, and number requirement validators from daisyUI v5 documentation."""
    from fasthtml.common import Input, P, Div
    from cjm_fasthtml_daisyui.components.data_input.text_input import text_input
    
    # URL input requirement validator
    url_validator = Div(
        Input(
            type="url",
            required=True,
            placeholder="https://",
            value="https://",
            pattern="^(https?://)?([a-zA-Z0-9]([a-zA-Z0-9-].*[a-zA-Z0-9])?.)+[a-zA-Z].*",
            title="Must be valid URL",
            cls=combine_classes(text_input, validator)
        ),
        P(
            "Must be valid URL",
            cls=str(validator_hint)
        )
    )
    
    # Date input requirement validator
    date_validator = Div(
        Input(
            type="date",
            required=True,
            placeholder="Pick a date in 2025",
            min="2025-01-01",
            max="2025-12-31",
            title="Must be valid URL",
            cls=combine_classes(text_input, validator)
        ),
        P(
            "Must be 2025",
            cls=str(validator_hint)
        )
    )
    
    # Number input requirement validator
    number_validator = Div(
        Input(
            type="number",
            required=True,
            placeholder="Type a number between 1 to 10",
            min="1",
            max="10",
            title="Must be between be 1 to 10",
            cls=combine_classes(text_input, validator)
        ),
        P(
            "Must be between be 1 to 10",
            cls=str(validator_hint)
        )
    )
    
    # Verify URL validator
    assert url_validator.tag == "div"
    assert len(url_validator.children) == 2
    
    url_input = url_validator.children[0]
    assert url_input.tag == "input"
    assert url_input.attrs['type'] == "url"
    assert url_input.attrs['required'] == True
    assert url_input.attrs['placeholder'] == "https://"
    assert url_input.attrs['value'] == "https://"
    assert url_input.attrs['pattern'] == "^(https?://)?([a-zA-Z0-9]([a-zA-Z0-9-].*[a-zA-Z0-9])?.)+[a-zA-Z].*"
    assert url_input.attrs['title'] == "Must be valid URL"
    assert "input" in url_input.attrs['class']
    assert "validator" in url_input.attrs['class']
    
    url_hint = url_validator.children[1]
    assert url_hint.tag == "p"
    assert url_hint.attrs['class'] == "validator-hint"
    assert url_hint.children[0] == "Must be valid URL"
    
    # Verify Date validator
    assert date_validator.tag == "div"
    assert len(date_validator.children) == 2
    
    date_input = date_validator.children[0]
    assert date_input.tag == "input"
    assert date_input.attrs['type'] == "date"
    assert date_input.attrs['required'] == True
    assert date_input.attrs['placeholder'] == "Pick a date in 2025"
    assert date_input.attrs['min'] == "2025-01-01"
    assert date_input.attrs['max'] == "2025-12-31"
    assert date_input.attrs['title'] == "Must be valid URL"
    assert "input" in date_input.attrs['class']
    assert "validator" in date_input.attrs['class']
    
    date_hint = date_validator.children[1]
    assert date_hint.tag == "p"
    assert date_hint.attrs['class'] == "validator-hint"
    assert date_hint.children[0] == "Must be 2025"
    
    # Verify Number validator
    assert number_validator.tag == "div"
    assert len(number_validator.children) == 2
    
    number_input = number_validator.children[0]
    assert number_input.tag == "input"
    assert number_input.attrs['type'] == "number"
    assert number_input.attrs['required'] == True
    assert number_input.attrs['placeholder'] == "Type a number between 1 to 10"
    assert number_input.attrs['min'] == "1"
    assert number_input.attrs['max'] == "10"
    assert number_input.attrs['title'] == "Must be between be 1 to 10"
    assert "input" in number_input.attrs['class']
    assert "validator" in number_input.attrs['class']
    
    number_hint = number_validator.children[1]
    assert number_hint.tag == "p"
    assert number_hint.attrs['class'] == "validator-hint"
    assert number_hint.children[0] == "Must be between be 1 to 10"
    
    return Div(url_validator, date_validator, number_validator)

# Run the tests
test_validator_url_date_number_fasthtml_examples()
<div>
  <div>
    <input type="url" required placeholder="https://" value="https://" pattern="^(https?://)?([a-zA-Z0-9]([a-zA-Z0-9-].*[a-zA-Z0-9])?.)+[a-zA-Z].*" class="input validator" title="Must be valid URL">
    <p class="validator-hint">Must be valid URL</p>
  </div>
  <div>
    <input type="date" required placeholder="Pick a date in 2025" min="2025-01-01" max="2025-12-31" class="input validator" title="Must be valid URL">
    <p class="validator-hint">Must be 2025</p>
  </div>
  <div>
    <input type="number" required placeholder="Type a number between 1 to 10" min="1" max="10" class="input validator" title="Must be between be 1 to 10">
    <p class="validator-hint">Must be between be 1 to 10</p>
  </div>
</div>
test_func = test_validator_url_date_number_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_validator_checkbox_toggle_select_fasthtml_examples

 test_validator_checkbox_toggle_select_fasthtml_examples ()

Test checkbox, toggle, and select requirement validators from daisyUI v5 documentation.

Exported source
def test_validator_checkbox_toggle_select_fasthtml_examples():
    """Test checkbox, toggle, and select requirement validators from daisyUI v5 documentation."""
    from fasthtml.common import Input, P, Div, Form, Select, Option, Button
    from cjm_fasthtml_daisyui.components.data_input.checkbox import checkbox
    from cjm_fasthtml_daisyui.components.data_input.toggle import toggle
    from cjm_fasthtml_daisyui.components.data_input.select import select
    from cjm_fasthtml_daisyui.components.actions.button import btn
    
    # Checkbox requirement validator
    checkbox_validator = Div(
        Input(
            type="checkbox",
            required=True,
            title="Required",
            cls=combine_classes(checkbox, validator)
        ),
        P(
            "Required",
            cls=str(validator_hint)
        )
    )
    
    # Toggle requirement validator
    toggle_validator = Div(
        Input(
            type="checkbox",
            required=True,
            title="Required",
            cls=combine_classes(toggle, validator)
        ),
        P(
            "Required",
            cls=str(validator_hint)
        )
    )
    
    # Select requirement validator
    select_validator = Form(
        Select(
            Option("Choose:", disabled=True, selected=True, value=""),
            Option("Tabs"),
            Option("Spaces"),
            required=True,
            cls=combine_classes(select, validator)
        ),
        P(
            "Required",
            cls=str(validator_hint)
        ),
        Button(
            "Submit form",
            type="submit",
            cls=str(btn)
        )
    )
    
    # Verify checkbox validator
    assert checkbox_validator.tag == "div"
    assert len(checkbox_validator.children) == 2
    
    checkbox_input = checkbox_validator.children[0]
    assert checkbox_input.tag == "input"
    assert checkbox_input.attrs['type'] == "checkbox"
    assert checkbox_input.attrs['required'] == True
    assert checkbox_input.attrs['title'] == "Required"
    assert "checkbox" in checkbox_input.attrs['class']
    assert "validator" in checkbox_input.attrs['class']
    
    checkbox_hint = checkbox_validator.children[1]
    assert checkbox_hint.tag == "p"
    assert checkbox_hint.attrs['class'] == "validator-hint"
    assert checkbox_hint.children[0] == "Required"
    
    # Verify toggle validator
    assert toggle_validator.tag == "div"
    assert len(toggle_validator.children) == 2
    
    toggle_input = toggle_validator.children[0]
    assert toggle_input.tag == "input"
    assert toggle_input.attrs['type'] == "checkbox"
    assert toggle_input.attrs['required'] == True
    assert toggle_input.attrs['title'] == "Required"
    assert "toggle" in toggle_input.attrs['class']
    assert "validator" in toggle_input.attrs['class']
    
    toggle_hint = toggle_validator.children[1]
    assert toggle_hint.tag == "p"
    assert toggle_hint.attrs['class'] == "validator-hint"
    assert toggle_hint.children[0] == "Required"
    
    # Verify select validator
    assert select_validator.tag == "form"
    assert len(select_validator.children) == 3
    
    select_elem = select_validator.children[0]
    assert select_elem.tag == "select"
    assert select_elem.attrs['required'] == True
    assert "select" in select_elem.attrs['class']
    assert "validator" in select_elem.attrs['class']
    
    # Check select options
    assert len(select_elem.children) == 3
    option1 = select_elem.children[0]
    assert option1.tag == "option"
    assert option1.attrs['disabled'] == True
    assert option1.attrs['selected'] == True
    assert option1.attrs['value'] == ""
    assert option1.children[0] == "Choose:"
    
    option2 = select_elem.children[1]
    assert option2.tag == "option"
    assert option2.children[0] == "Tabs"
    
    option3 = select_elem.children[2]
    assert option3.tag == "option"
    assert option3.children[0] == "Spaces"
    
    select_hint = select_validator.children[1]
    assert select_hint.tag == "p"
    assert select_hint.attrs['class'] == "validator-hint"
    assert select_hint.children[0] == "Required"
    
    submit_button = select_validator.children[2]
    assert submit_button.tag == "button"
    assert submit_button.attrs['type'] == "submit"
    assert submit_button.attrs['class'] == "btn"
    assert submit_button.children[0] == "Submit form"
    
    return Div(checkbox_validator, toggle_validator, select_validator)

# Run the tests
test_validator_checkbox_toggle_select_fasthtml_examples()
<div>
  <div>
    <input type="checkbox" required class="checkbox validator" title="Required">
    <p class="validator-hint">Required</p>
  </div>
  <div>
    <input type="checkbox" required class="toggle validator" title="Required">
    <p class="validator-hint">Required</p>
  </div>
<form enctype="multipart/form-data"><select required class="select validator"><option disabled selected>Choose:</option><option>Tabs</option><option>Spaces</option></select>    <p class="validator-hint">Required</p>
<button type="submit" class="btn">Submit form</button></form></div>
test_func = test_validator_checkbox_toggle_select_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()