Form Validation
Comprehensive form and input validation patterns in Katlux. Katlux form components feature native semantic validation states (success, warning, error) with custom feedback messaging (validationText), reactive computed rules, debounced async server checks, and full form submission handling.
For enterprise forms with automatic state tracking (dirty, touched, submitting) and Zod / Standard Schema integration with zero boilerplate, use the useKatluxForm Composable.
Required Field Validation
Interactive validation that checks for mandatory non-empty inputs. Try typing or selecting an option.
// Reactive Computed Validation
const reqName = ref('')
const reqNameValidation = computed(() => {
if (!reqName.value.trim()) return 'error'
return 'success'
})
const reqNameValidationText = computed(() => {
if (!reqName.value.trim()) return 'This field is required'
return 'Name is valid'
})
// Template Usage
KTextbox(
v-model="reqName"
:validation="reqNameValidation"
:validationText="reqNameValidationText"
placeholder="e.g. Ada Lovelace"
)
Format & Pattern Matching
Format matching with regex and mask validation. Tests email syntax, website URLs, and masked phone numbers.
// Email Regex with Warning & Error States
const emailVal = ref('')
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const emailValidation = computed(() => {
if (!emailVal.value) return null
if (emailRegex.test(emailVal.value)) return 'success'
if (emailVal.value.includes('@') && !emailVal.value.includes('.')) return 'warning'
return 'error'
})
const emailValidationText = computed(() => {
if (!emailVal.value) return ''
if (emailRegex.test(emailVal.value)) return 'Valid email address format'
if (emailVal.value.includes('@') && !emailVal.value.includes('.')) return 'Incomplete domain (missing top-level domain e.g. .com)'
return 'Please enter a valid email address'
})
Length, Bounds & Numeric Range
Validates character limits, numeric thresholds, and dynamic character counters with warning states.
// Numeric Bounds
const ageVal = ref('25')
const ageValidation = computed(() => {
const num = parseInt(ageVal.value, 10)
if (isNaN(num)) return 'error'
if (num < 18 || num > 65) return 'error'
return 'success'
})
const ageValidationText = computed(() => {
const num = parseInt(ageVal.value, 10)
if (isNaN(num)) return 'Please enter a valid number'
if (num < 18) return 'Must be at least 18 years old'
if (num > 65) return 'Must be 65 or younger'
return 'Age is within acceptable range'
})
Password Strength & Real-Time Confirmation
Real-time password complexity analysis and matching confirmation.
// Password Complexity & Match Confirmation
const passwordVal = ref('')
const confirmPwdVal = ref('')
const confirmPwdValidation = computed(() => {
if (!confirmPwdVal.value) return null
if (confirmPwdVal.value === passwordVal.value) return 'success'
return 'error'
})
const confirmPwdValidationText = computed(() => {
if (!confirmPwdVal.value) return ''
if (confirmPwdVal.value === passwordVal.value) return 'Passwords match'
return 'Passwords do not match'
})
Date Validation (Future Booking)
Date validation verifying that an appointment is scheduled for a future weekday.
const bookingDate = ref('')
const bookingDateValidation = computed(() => {
if (!bookingDate.value) return null
const selected = new Date(bookingDate.value)
const today = new Date()
today.setHours(0, 0, 0, 0)
if (selected < today) return 'error'
const day = selected.getDay()
if (day === 0 || day === 6) return 'warning'
return 'success'
})
Validation Across All Katlux Form Components
Every Katlux form component natively accepts :validation ('success' | 'warning' | 'error' | null) and :validationText.
// All Katlux form components share the same validation prop signature: KTextbox(v-model="value" :validation="state" :validationText="message") KMaskTextbox(v-model="phone" mask="(999) 999-9999" :validation="state" :validationText="message") KTextarea(v-model="comments" :validation="state" :validationText="message") KCombobox(v-model="selected" :dataProvider="provider" :validation="state" :validationText="message") KRadiobox(v-model="tier" value="enterprise" :validation="state" :validationText="message") KCheckbox(v-model="agree" :validation="state" :validationText="message") KDatePicker(v-model="date" :validation="state" :validationText="message")
Semantic States Sandbox
Switch between semantic states and edit the feedback message to observe real-time styling updates across multiple components simultaneously.
Debounced Remote Availability Check
Simulates an asynchronous server verification call (debounced 450ms). Try typing reserved usernames like admin, root, katlux, or test to see rejection, or any other name to see instant confirmation.
// Debounced Async Validation with State Tracking
const asyncUsername = ref('')
const asyncValidation = ref<'success' | 'warning' | 'error' | null>(null)
const asyncValidationText = ref('')
let debounceTimer: ReturnType<typeof setTimeout> | null = null
watch(asyncUsername, (newVal) => {
if (debounceTimer) clearTimeout(debounceTimer)
if (!newVal.trim()) {
asyncValidation.value = null
asyncValidationText.value = ''
return
}
// Pending status
asyncValidation.value = 'warning'
asyncValidationText.value = 'Checking availability with server...'
debounceTimer = setTimeout(async () => {
const reserved = ['admin', 'root', 'katlux', 'support', 'test']
if (reserved.includes(newVal.toLowerCase().trim())) {
asyncValidation.value = 'error'
asyncValidationText.value = `Username "${newVal}" is already taken`
} else {
asyncValidation.value = 'success'
asyncValidationText.value = `Username "${newVal}" is available!`
}
}, 450)
})
Complete Registration Form with Submission Validation
A complete real-world form lifecycle: untracked until submission, atomic validation across all inputs on submit, summary alert banners, and reset capability.
// Real-World Form Validation Handler
const regForm = reactive({
name: '',
email: '',
phone: '',
department: '',
startDate: '',
terms: false
})
const formSubmitted = ref(false)
const formErrors = computed(() => {
const errors: string[] = []
if (!regForm.name.trim()) errors.push('Full Name is required')
if (!regForm.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(regForm.email)) {
errors.push('Valid Email Address is required')
}
if (!regForm.department) errors.push('Department selection is required')
if (!regForm.terms) errors.push('You must accept the terms of service')
return errors
})
function handleFormSubmit() {
formSubmitted.value = true
if (formErrors.value.length === 0) {
// Send payload to API
console.log('Form submitted successfully:', regForm)
}
}
The following attributes are supported by all Katlux form components (KTextbox, KMaskTextbox, KTextarea, KCombobox, KRadiobox, KCheckbox, KDatePicker, KDateTimePicker, KTreePicker).
| Prop Name | Type | Default | Description |
|---|---|---|---|
| validation | 'success' | 'warning' | 'error' | null | null | Semantic validation state. Automatically styles borders, outlines, and icons using the active preset design tokens. |
| validationText | string | '' | Text feedback displayed immediately beneath the component when validation is active. |
| Semantic State | CSS Token | Recommended Use Case |
|---|---|---|
| success | var(--success-500) | Confirms valid input, available username, verified email, or strong password. |
| warning | var(--warning-500) | Incomplete input, approaching character limit, password strength warnings, or asynchronous checks in-flight. |
| error | var(--danger-500) | Required field missing, invalid format, constraint violation, or server conflict. |
| null / default | var(--border-color) | Untouched, neutral clean state before user interaction or evaluation. |