Form Module
A comprehensive form validation module that provides field management, validation rules, and error handling for your forms.
Installation
bash
npx @zizigy/capsule module add formThis will add the Form module to your @capsule/modules/form directory and automatically import it into your main @capsule/index.js file.
Quick Start
The Form module consists of three main parts:
- CapsuleValidator - The main validation class
- CapsuleRules - Pre-built validation rules
- Form Components -
form-fieldandform-messageweb components
Basic Example
html
<form id="myForm">
<form-field>
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
required
/>
<form-message></form-message>
</form-field>
<form-field>
<label for="password">Password</label>
<input
type="password"
id="password"
name="password"
required
/>
<form-message></form-message>
</form-field>
<button type="submit">Submit</button>
</form>
<script type="module">
import {
CapsuleValidator,
CapsuleRules,
} from '@capsule/modules/form/index.js';
const validator = new CapsuleValidator('#myForm', {
fields: {
email: [CapsuleRules.required(), CapsuleRules.email()],
password: [
CapsuleRules.required(),
CapsuleRules.min(8, 'Password must be at least 8 characters'),
],
},
onSubmit: async (values) => {
console.log('Form submitted with values:', values);
// Handle form submission
},
});
</script>Form Components
form-field
A wrapper component that manages error states for form fields.
html
<form-field>
<label for="username">Username</label>
<input
type="text"
id="username"
name="username"
/>
<form-message></form-message>
</form-field>Attributes:
- Automatically gets error class when validation fails
Methods:
setError(message)- Set error message on the field- Automatically manages error state classes
form-message
A component for displaying validation error messages.
html
<form-message></form-message>Methods:
setMessage(message)- Display an error messageclearMessage()- Clear the error message
Validation Rules
The CapsuleRules class provides many pre-built validation rules:
Basic Rules
javascript
// Required field
CapsuleRules.required('This field is required');
// Email validation
CapsuleRules.email('Please enter a valid email');
// Minimum length
CapsuleRules.min(8, 'Must be at least 8 characters');
// Maximum length
CapsuleRules.max(100, 'Must be less than 100 characters');String Rules
javascript
// URL validation
CapsuleRules.url('Please enter a valid URL');
// Phone number
CapsuleRules.phone('Please enter a valid phone number');
// Password strength
CapsuleRules.password(
'Password must be at least 8 characters with letters and numbers'
);
// Pattern matching
CapsuleRules.pattern(/^[A-Z]/, 'Must start with uppercase letter');
// Alphanumeric only
CapsuleRules.alphaNumeric('Only letters and numbers allowed');Number Rules
javascript
// Minimum value
CapsuleRules.minValue(0, 'Must be at least 0');
// Maximum value
CapsuleRules.maxValue(100, 'Must be at most 100');
// Between values
CapsuleRules.between(1, 100, 'Must be between 1 and 100');
// Integer
CapsuleRules.integer('Must be an integer');
// Positive number
CapsuleRules.positive('Must be a positive number');Custom Rules
javascript
// Custom validation function
const customRule = (value) => {
if (value === 'forbidden') {
return 'This value is not allowed';
}
return true; // Valid
};
// Use in validator
fields: {
customField: [customRule],
}Async Rules
javascript
import { CapsuleRules } from '@capsule/modules/form/index.js';
// Check if username is available
const checkUsername = async (username) => {
const response = await fetch(`/api/check-username?username=${username}`);
const data = await response.json();
return data.available || 'Username is already taken';
};
fields: {
username: [
CapsuleRules.required(),
CapsuleRules.async(checkUsername),
],
}Validator Options
javascript
const validator = new CapsuleValidator('#myForm', {
// Validation rules for each field
fields: {
email: [CapsuleRules.required(), CapsuleRules.email()],
},
// Validate on input events
validateOnInput: true,
// Validate on change events
validateOnChange: false,
// Stop validation on first error (default: true)
bails: true,
// Initial form values
initialValues: {
email: 'user@example.com',
},
// Custom selectors for form components
formFieldSelector: 'form-field',
formMessageSelector: 'form-message',
// Callbacks
onSubmit: async (values, helpers) => {
// Handle successful submission
helpers.reset(); // Reset form
},
onValidate: (result) => {
// Called after validation (valid or invalid)
},
onError: async (errors, helpers) => {
// Handle validation errors
},
onFieldValidate: (fieldName, result) => {
// Called when a field is validated
},
});Complete Example
html
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
href="@capsule/global.css"
/>
<script
type="module"
src="@capsule/index.js"
></script>
</head>
<body>
<form id="registrationForm">
<form-field>
<label for="name">Full Name</label>
<input
type="text"
id="name"
name="name"
/>
<form-message></form-message>
</form-field>
<form-field>
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
/>
<form-message></form-message>
</form-field>
<form-field>
<label for="password">Password</label>
<input
type="password"
id="password"
name="password"
/>
<form-message></form-message>
</form-field>
<form-field>
<label for="confirmPassword">Confirm Password</label>
<input
type="password"
id="confirmPassword"
name="confirmPassword"
/>
<form-message></form-message>
</form-field>
<button type="submit">Register</button>
</form>
<script type="module">
import {
CapsuleValidator,
CapsuleRules,
} from '@capsule/modules/form/index.js';
const validator = new CapsuleValidator('#registrationForm', {
fields: {
name: [
CapsuleRules.required('Name is required'),
CapsuleRules.min(2, 'Name must be at least 2 characters'),
],
email: [
CapsuleRules.required('Email is required'),
CapsuleRules.email('Please enter a valid email'),
],
password: [
CapsuleRules.required('Password is required'),
CapsuleRules.min(8, 'Password must be at least 8 characters'),
CapsuleRules.password('Password must contain letters and numbers'),
],
confirmPassword: [
CapsuleRules.required('Please confirm your password'),
CapsuleRules.match('password', 'Passwords do not match'),
],
},
validateOnInput: true,
onSubmit: async (values, { reset, setErrors, setFieldError }) => {
try {
const response = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
});
if (!response.ok) {
const errors = await response.json();
setErrors(errors);
return;
}
alert('Registration successful!');
reset();
} catch (error) {
setFieldError('email', 'Network error. Please try again.');
}
},
});
</script>
</body>
</html>API Reference
CapsuleValidator
Constructor
javascript
new CapsuleValidator(formSelector, options);formSelector- CSS selector for the form elementoptions- Configuration object (see Validator Options)
Methods
validate()- Validate all fields, returnsPromise<{valid: boolean, values: object, errors: object}>validateField(fieldName)- Validate a single fieldsetFieldError(fieldName, message)- Set error message for a fieldclearError(fieldName)- Clear error for a fielddisplayErrors(errors)- Display multiple errors at oncesetValues(values)- Set form values programmaticallygetValues()- Get current form valuesreset()- Reset form to initial state
Styling
You can style the error states using CSS:
css
form-field.error input {
border-color: var(--capsule-color-error);
}
form-message {
color: var(--capsule-color-error);
font-size: var(--capsule-font-size-sm);
margin-top: 0.25rem;
}