Form Integration
How to integrate rut.ts with form libraries and validation.
Vanilla JavaScript
<!DOCTYPE html>
<html>
<body>
<input type="text" id="rut-input" placeholder="12.345.678-5" />
<span id="error-message"></span>
<script type="module">
import { format, validate } from 'rut.ts'
const input = document.getElementById('rut-input')
const error = document.getElementById('error-message')
input.addEventListener('input', (e) => {
const value = e.target.value
// Format as user types
const formatted = format(value, { incremental: true })
// Update input if different (avoid cursor jump)
if (formatted !== value) {
e.target.value = formatted
}
// Show validation
if (validate(formatted)) {
error.textContent = ''
input.classList.remove('invalid')
} else {
error.textContent = 'RUT inválido'
input.classList.add('invalid')
}
})
</script>
</body>
</html>React Hook Form
import { useForm } from 'react-hook-form'
import { validate } from 'rut.ts'
type FormData = {
rut: string
name: string
}
function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>()
const onSubmit = (data: FormData) => {
console.log('Valid RUT:', data.rut)
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
{...register('rut', {
required: 'RUT is required',
validate: (value) =>
validate(value) || 'RUT is invalid'
})}
placeholder="12.345.678-5"
/>
{errors.rut && <span>{errors.rut.message}</span>}
<button type="submit">Submit</button>
</form>
)
}Zod Schema Validation
import { z } from 'zod'
import { validate } from 'rut.ts'
const userSchema = z.object({
name: z.string(),
rut: z.string().refine(
(val) => validate(val),
{ message: 'Invalid RUT' }
),
email: z.string().email()
})
// Usage
const result = userSchema.safeParse({
name: 'Juan Pérez',
rut: '12.345.678-5',
email: 'juan@example.com'
})
if (result.success) {
console.log('Valid data:', result.data)
}Formik
import { Formik, Form, Field, ErrorMessage } from 'formik'
import { validate, format } from 'rut.ts'
function MyForm() {
return (
<Formik
initialValues={{ rut: '' }}
validate={(values) => {
const errors: any = {}
if (!validate(values.rut)) {
errors.rut = 'Invalid RUT'
}
return errors
}}
onSubmit={(values) => {
console.log('Submitted:', values)
}}
>
{({ values, setFieldValue }) => (
<Form>
<Field
name="rut"
placeholder="12.345.678-5"
onChange={(e: any) => {
const formatted = format(e.target.value, {
incremental: true
})
setFieldValue('rut', formatted)
}}
/>
<ErrorMessage name="rut" component="div" />
<button type="submit">Submit</button>
</Form>
)}
</Formik>
)
}Next.js Server Actions
'use server'
import { validate, clean } from 'rut.ts'
import { z } from 'zod'
const formSchema = z.object({
rut: z.string().refine((val) => validate(val), 'Invalid RUT')
})
export async function createUser(formData: FormData) {
const data = {
rut: formData.get('rut') as string
}
// Validate
const result = formSchema.safeParse(data)
if (!result.success) {
return { error: result.error.flatten() }
}
// Clean for storage
const cleanedRut = clean(data.rut)
// Save to database
await db.users.create({
data: { rut: cleanedRut }
})
return { success: true }
}Yup Schema
import * as yup from 'yup'
import { validate } from 'rut.ts'
const schema = yup.object({
rut: yup
.string()
.required('RUT is required')
.test('is-valid-rut', 'Invalid RUT', (value) => {
return value ? validate(value) : false
})
})
// Usage
try {
await schema.validate({ rut: '12.345.678-5' })
console.log('Valid!')
} catch (error) {
console.error(error.message)
}Custom Hook (React)
import { useState, useCallback } from 'react'
import { format, validate } from 'rut.ts'
function useRutInput(initialValue = '') {
const [value, setValue] = useState(initialValue)
const [isValid, setIsValid] = useState(false)
const handleChange = useCallback((input: string) => {
const formatted = format(input, { incremental: true })
setValue(formatted)
setIsValid(validate(formatted))
}, [])
return {
value,
isValid,
handleChange,
props: {
value,
onChange: (e: React.ChangeEvent<HTMLInputElement>) =>
handleChange(e.target.value)
}
}
}
// Usage
function MyComponent() {
const rut = useRutInput()
return (
<div>
<input {...rut.props} placeholder="12.345.678-5" />
{!rut.isValid && rut.value && (
<span className="error">Invalid RUT</span>
)}
</div>
)
}Last updated on