Demonstrates multiple field types and validation Async
<form id=""
class="pydantic-form needs-validation"
style=""
method="POST"
action="/user"
novalidate>
<div class="mb-3"><label for="username"><i class="bi bi-person"></i> Username *</label>
<input name="username" id="username" class="form-control" value="alex_johnson" required="required" minlength="3" maxlength="11" placeholder="Choose a username" pattern="\d{3}-\d{2}-\d{4}" inputmode="numeric" autocomplete="off" type="text" />
<div class="form-text">Your unique username (3-50 characters)</div></div>
<div class="mb-3"><label for="email"><i class="bi bi-envelope"></i> Email Address *</label>
<input name="email" id="email" class="form-control" value="alex.johnson@example.com" required="required" placeholder="your.email@example.com" inputmode="email" type="email" />
<div class="form-text">Your email address for account verification</div></div>
<div class="mb-3"><label for="password"><i class="bi bi-lock"></i> Password *</label>
<input name="password" id="password" class="form-control" value="SecurePass123!" required="required" minlength="8" placeholder="Create a strong password" autocomplete="new-password" type="password" />
<div class="form-text">Password must be at least 8 characters</div></div>
<div class="mb-3"><label for="confirm_password"><i class="bi bi-lock"></i> Confirm Password *</label>
<input name="confirm_password" id="confirm_password" class="form-control" value="SecurePass123!" required="required" placeholder="Confirm your password" autocomplete="new-password" type="password" />
<div class="form-text">Re-enter your password to confirm</div></div>
<div class="mb-3"><label for="age"><i class="bi bi-calendar"></i> Age</label>
<input name="age" id="age" class="form-control" value="28" placeholder="Your age (optional)%" min="0" max="100" step="0.1" inputmode="numeric" type="number" />
<div class="form-text">Your age in years</div></div>
<div class="mb-3"><div class="mb-3">
<label for="role" class="form-label">Account Type</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-bi bi-shield"></i></span>
<select name="role" id="role" class="form-select"><option value="user" selected>👤 User</option>
<option value="admin">🔑 Admin</option>
<option value="moderator">🛡️ Moderator</option></select>
</div>
<div class="form-text">Select your account type</div>
</div></div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<script>
(function() {
document.addEventListener('DOMContentLoaded', function() {
// Prevent Enter key from submitting forms unless on submit button
const forms = document.querySelectorAll('form.pydantic-form');
forms.forEach(function(form) {
form.addEventListener('keydown', function(e) {
// Check if Enter key is pressed
if (e.key === 'Enter' || e.keyCode === 13) {
const target = e.target;
// Allow Enter in textareas (for multi-line input)
if (target.tagName === 'TEXTAREA') {
return;
}
// Allow Enter on submit buttons
if (target.tagName === 'BUTTON' && target.type === 'submit') {
return;
}
// Allow Enter on input type="submit"
if (target.tagName === 'INPUT' && target.type === 'submit') {
return;
}
// Prevent form submission for all other cases
e.preventDefault();
return false;
}
});
});
});
})();
</script>
class UserRegistrationForm(FormModel):
"""User registration form with username, email, and password."""
username: str = FormField(
title="Username",
input_type="text",
placeholder="Choose a username",
help_text="Your unique username (3-50 characters)",
icon="person",
min_length=3,
max_length=50
)
email: EmailStr = FormField(
title="Email Address",
input_type="email",
placeholder="your.email@example.com",
help_text="Your email address for account verification",
icon="email"
)
password: str = FormField(
title="Password",
input_type="password",
placeholder="Create a strong password",
help_text="Password must be at least 8 characters",
icon="lock",
min_length=8
)
confirm_password: str = FormField(
title="Confirm Password",
input_type="password",
placeholder="Confirm your password",
help_text="Re-enter your password to confirm",
icon="lock"
)
age: Optional[int] = FormField(
None,
title="Age",
input_type="number",
placeholder="Your age (optional)",
help_text="Your age in years",
icon="calendar",
min_value=13,
max_value=120
)
role: UserRole = FormField(
UserRole.USER,
title="Account Type",
input_type="select",
options=[
{"value": "user", "label": "👤 User"},
{"value": "admin", "label": "🔑 Admin"},
{"value": "moderator", "label": "🛡️ Moderator"}
],
help_text="Select your account type",
icon="shield"
)
@field_validator("username")
@classmethod
def validate_username(cls, v):
if not v.strip():
raise ValueError("Username cannot be empty")
if not v.replace('_', '').replace('-', '').isalnum():
raise ValueError("Username can only contain letters, numbers, hyphens, and underscores")
return v.strip()
@field_validator("confirm_password")
@classmethod
def validate_passwords_match(cls, v, info):
if 'password' in info.data and v != info.data['password']:
raise ValueError("Passwords do not match")
return v
{
"$defs": {
"UserRole": {
"description": "User roles.",
"enum": [
"user",
"admin",
"moderator"
],
"title": "UserRole",
"type": "string"
}
},
"description": "User registration form with username, email, and password.",
"properties": {
"username": {
"autofocus": false,
"description": "Your unique username (3-50 characters)",
"disabled": false,
"help_text": "Your unique username (3-50 characters)",
"icon": "person",
"input_type": "text",
"maxLength": 50,
"minLength": 3,
"placeholder": "Choose a username",
"readonly": false,
"title": "Username",
"type": "string"
},
"email": {
"autofocus": false,
"description": "Your email address for account verification",
"disabled": false,
"format": "email",
"help_text": "Your email address for account verification",
"icon": "email",
"input_type": "email",
"placeholder": "your.email@example.com",
"readonly": false,
"title": "Email Address",
"type": "string"
},
"password": {
"autofocus": false,
"description": "Password must be at least 8 characters",
"disabled": false,
"help_text": "Password must be at least 8 characters",
"icon": "lock",
"input_type": "password",
"minLength": 8,
"placeholder": "Create a strong password",
"readonly": false,
"title": "Password",
"type": "string"
},
"confirm_password": {
"autofocus": false,
"description": "Re-enter your password to confirm",
"disabled": false,
"help_text": "Re-enter your password to confirm",
"icon": "lock",
"input_type": "password",
"placeholder": "Confirm your password",
"readonly": false,
"title": "Confirm Password",
"type": "string"
},
"age": {
"anyOf": [
{
"maximum": 120,
"minimum": 13,
"type": "integer"
},
{
"type": "null"
}
],
"autofocus": false,
"default": null,
"description": "Your age in years",
"disabled": false,
"help_text": "Your age in years",
"icon": "calendar",
"input_type": "number",
"placeholder": "Your age (optional)",
"readonly": false,
"title": "Age"
},
"role": {
"$ref": "#/$defs/UserRole",
"autofocus": false,
"default": "user",
"description": "Select your account type",
"disabled": false,
"help_text": "Select your account type",
"icon": "shield",
"input_type": "select",
"options": [
{
"label": "\ud83d\udc64 User",
"value": "user"
},
{
"label": "\ud83d\udd11 Admin",
"value": "admin"
},
{
"label": "\ud83d\udee1\ufe0f Moderator",
"value": "moderator"
}
],
"readonly": false,
"title": "Account Type"
}
},
"required": [
"username",
"email",
"password",
"confirm_password"
],
"title": "UserRegistrationForm",
"type": "object"
}{
"username": {
"required": true,
"type": "string",
"minLength": 3,
"maxLength": 50
},
"email": {
"required": true,
"type": "string",
"format": "email"
},
"password": {
"required": true,
"type": "string",
"minLength": 8
},
"confirm_password": {
"required": true,
"type": "string"
},
"age": {
"required": false
},
"role": {
"required": false
}
}{
"errors": {},
"data": {
"username": "alex_johnson",
"email": "alex.johnson@example.com",
"password": "SecurePass123!",
"confirm_password": "SecurePass123!",
"age": 28,
"role": "user"
}
}