Search for a command to run...
Last updated June 9, 2026
This section provides technical integration patterns for common validation scenarios using the ctrovalidate-browser controller.
Pattern for a standard registration flow including password confirmation as a dependency.
<form id="auth-form" novalidate>
<div class="field-group">
<label>Email</label>
<input name="email" data-ctrovalidate-rules="required|email" />
<div class="error-container"></div>
</div>
<div class="field-group">
<label>Password</label>
<input
type="password"
name="password"
id="password"
data-ctrovalidate-rules="required|strongPassword"
/>
<div class="error-container"></div>
</div>
<div class="field-group">
<label>Confirm Password</label>
<input
type="password"
name="confirm_password"
data-ctrovalidate-rules="required|sameAs:password"
/>
<div class="error-container"></div>
</div>
<button type="submit">Execute Registration</button>
</form>import { Ctrovalidate } from 'ctrovalidate-browser';
const validator = new Ctrovalidate(document.querySelector('#auth-form'), {
realTime: true,
errorClass: 'input-invalid',
errorMessageClass: 'error-container'
});
document.querySelector('#auth-form').addEventListener('submit', async (e) => {
e.preventDefault();
const isValid = await validator.validate();
if (isValid) {
// Process validated form data
const data = new FormData(e.target);
await submitRegistration(data);
}
});Pattern for inter-field dependencies where the visibility and validation of a field depend on a selection.
<form id="checkout-form" novalidate>
<label>Client Type</label>
<select name="type">
<option value="consumer">Consumer</option>
<option value="corporate">Corporate</option>
</select>
<div class="field-group">
<label>Corporate Tax ID</label>
<input
name="tax_id"
data-ctrovalidate-rules="required|alphaNum|exactLength:12"
data-ctrovalidate-if="type:value=corporate"
/>
<div class="error-container"></div>
</div>
</form>Integration pattern for server-side availability checks with automatic race-condition management.
import { Ctrovalidate } from 'ctrovalidate-browser';
Ctrovalidate.addAsyncRule(
'isAvailable',
async (value, params, element, signal) => {
const response = await fetch(`/api/validate?field=alias&val=${value}`, { signal });
const { available } = await response.json();
return available;
},
'The requested identifier is not available.'
);
const validator = new Ctrovalidate(document.querySelector('#setup-form'), {
pendingClass: 'state-validating'
});<form id="setup-form" novalidate>
<div class="field-group">
<label>Alias</label>
<input
name="alias"
data-ctrovalidate-rules="required|alphaDash|isAvailable"
/>
<div class="loading-state">Validating identifier...</div>
<div class="error-container"></div>
</div>
</form>/* Display logic for pending states */
.state-validating ~ .loading-state {
display: block;
}
.loading-state {
display: none;
font-size: 12px;
color: #666;
}Configuration for automatic ARIA management and visual feedback.
/* State-based styling using ARIA attributes */
[aria-invalid='true'] {
border: 1px solid #d32f2f;
}
[aria-invalid='false'] {
border: 1px solid #2e7d32;
}
.error-container {
color: #d32f2f;
min-height: 18px;
}[!NOTE] The controller automatically updates
aria-invalidon the input element. Ensure error containers are logically positioned near the input for optimal screen reader flow.