Component Name: formInput¶
Last Updated: 2025-09-29 Source Code: https://bitbucket.org/i2cinc/i2c.salesforce.metadata/src/STAGING/force-app/main/default/lwc/formInput
API Name: c-formInput Type: Form Component Target: Not exposed (internal reusable component)
Business Purpose¶
This reusable form input component provides consistent validation, styling, and error handling across all forms in the AANP application. It supports text, email, and password input types with built-in validation patterns, required field checking, and external error message support. The component also supports multi-line textarea mode.
User Interface¶
Visual Description¶
- Layout: Vertical label-input-error stack
- Key UI Elements: Label (with * for required), input/textarea, error message, hint text
- Responsive: Full-width input adapts to container
Component Structure¶
Files¶
formInput.html- TemplateformInput.js- Controller (195 lines)formInput.js-meta.xml- Metadata (not exposed)classnames.js- Utility for CSS class management
HTML Template Structure¶
<template>
<div class="form-group">
<slot name="label">
<label>{label}<template if:true={required}> * </template></label>
</slot>
<slot name="description">
<span>{description}</span>
</slot>
<template lwc:if={multiline}>
<textarea rows={rows} cols={cols} ...>{value}</textarea>
</template>
<template lwc:else>
<input type={type} ... />
</template>
<slot name="error-message">
<div lwc:if={hasError}>{errorMessage}</div>
<div lwc:elseif={hasExternalError}>{externalErrorMessage}</div>
</slot>
<slot name="hint">
<div>{hint}</div>
</slot>
</div>
</template>
Key Template Features: - Slots for label, description, error-message, hint (customizable) - Conditional textarea vs. input rendering - Dynamic CSS classes for error states - Support for all standard input attributes
JavaScript Controller¶
Properties (API)¶
@api label¶
- Type:
String - Default: 'Label'
- Description: Input field label
@api description¶
- Type:
String - Description: Secondary help text
@api id, name, type¶
- Type:
String - Defaults: undefined, undefined, 'text'
- Description: Standard input attributes
@api value¶
- Type:
String - Default: ''
- Description: Input value (two-way binding via events)
@api required¶
- Type:
Boolean - Default: false
- Description: Whether field is required
@api errorKey¶
- Type:
String - Default: 'default'
- Description: Key for error message lookup
@api hint¶
- Type:
String - Description: Hint message below input
@api labelClass, inputClass, errorMessageClass, etc.¶
- Type:
String - Description: CSS class overrides
@api placeholder, autoComplete, pattern¶
- Type:
String - Description: Standard HTML input attributes
@api disabled¶
- Type:
Boolean - Default: false
@api min, max, minLength, maxLength¶
- Type:
String - Description: Validation attributes
@api multiline¶
- Type:
Boolean - Default: false
- Description: Render as textarea instead of input
@api rows, cols¶
- Type:
String - Defaults: '3', '50'
- Description: Textarea dimensions
Public Methods¶
@api validateInput()¶
validateInput() {
const inputElement = this.multiline ?
this.template.querySelector('textarea') :
this.template.querySelector('input');
this.isDirty = true;
this.checkForError(inputElement);
return !this.hasError && !this.hasExternalError;
}
@api setError({ message, condition })¶
setError({ message, condition = true }) {
this.hasExternalError = condition;
this.externalErrorMessage = message;
}
@api clearError()¶
Purpose: Clear external error state Called By: Parent componentsEvent Handlers¶
handleChange(event)¶
Triggered By: Input change event Action: Sets isDirty, validates, dispatches inputchange event
handleBlur(event)¶
Triggered By: Input blur event Action: Validates if isDirty, dispatches inputblur event
handleInput(event)¶
Triggered By: Input input event (every keystroke) Action: Dispatches cinput event
handleFocus(event)¶
Triggered By: Input focus event Action: Dispatches focus event
Private Methods¶
checkForError(inputElement)¶
Purpose: Validates input based on type and pattern Validations: - Required field check - Email format regex - Password strength regex (8+ chars, upper, lower, number, special) - Custom pattern matching
setInternalError({ message, condition })¶
Purpose: Sets internal validation error state
Events¶
Events Dispatched¶
inputchange¶
When Fired: User changes input value (on blur/change) Usage:<c-form-input oninputchange={handler}>
inputblur¶
When Fired: User leaves input fieldcinput¶
When Fired: Every keystroke (input event)focus¶
When Fired: User focuses inputStyling (CSS)¶
Custom CSS Classes¶
.form-group: Container.error-label: Label when error (text-danger).is-invalid: Input border red- Computed classes use classNames utility
SLDS Classes¶
None
Dependencies¶
Apex Classes¶
None
Custom Utilities¶
classnames.js: CSS class concatenation utility
Configuration¶
Not exposed - internal component
User Interactions¶
Actions Available to Users¶
- Type in field: Triggers cinput on every keystroke
- Leave field: Triggers validation on blur (if dirty)
- Change value: Triggers validation and inputchange
Validation & Error Handling¶
Built-in Validations:
- Required field
- Email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
- Password: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?":{}|<>]).{8,}$/
- Custom pattern via pattern attribute
Error Messages: - "Field is required" - "Please enter a valid email address" - "Password is not valid" - "Please enter a valid value" (pattern mismatch)
Error Display: - Red text below input - Red border on input - Red label text
Data Flow¶
Input Data Flow¶
Output Data Flow¶
Performance Considerations¶
- Uses getters for computed CSS classes
- Validation only runs when dirty (after first interaction)
- Event debouncing could improve performance for cinput event
Accessibility (a11y)¶
ARIA Labels: - Label properly associated via for attribute - Error messages need aria-describedby link
Keyboard Navigation: - Standard input behavior - Tab order follows DOM
Screen Reader Support: - Labels announced - Error messages announced (could be improved with aria-live)
Testing¶
Jest Tests¶
None
Manual Testing¶
- [ ] Required validation
- [ ] Email validation
- [ ] Password validation
- [ ] Custom pattern validation
- [ ] External error setting
- [ ] Multiline mode
- [ ] All props work
- [ ] Event dispatching
Usage Examples¶
Basic Text Input¶
<c-form-input
id="firstName"
name="firstName"
label="First Name"
type="text"
value={firstName}
required={true}
oninputchange={handleChange}>
</c-form-input>
Email with Validation¶
<c-form-input
id="email"
name="email"
label="Email Address"
type="email"
value={email}
required={true}
oninputchange={handleChange}>
</c-form-input>
Textarea¶
<c-form-input
name="comments"
label="Comments"
multiline={true}
rows="5"
value={comments}
oninputchange={handleChange}>
</c-form-input>
Programmatic Validation¶
// In parent component
handleSubmit() {
const input = this.template.querySelector('c-form-input');
if (!input.validateInput()) {
// Show error
return;
}
// Submit form
}
// Set external error
input.setError({
message: 'Username already exists',
condition: true
});
Changes & History¶
- 2025-09-29: Latest version
⚠️ Pre-Go-Live Concerns¶
CRITICAL - Fix Before Go-Live¶
None
HIGH - Address Soon After Go-Live¶
- No unit tests: Zero coverage for widely-used validation component
- Email regex too permissive: Allows
a@b.cwhich may not be desired - Password requirements not documented to user: Validation regex requires 8+ chars, upper, lower, number, special but user doesn't see requirements
- No aria-describedby: Error messages should be linked to input for screen readers
- Events flood parent on typing: cinput fires on every keystroke without debouncing
MEDIUM - Future Enhancement¶
- Add show/hide password toggle: For password inputs
- Add character counter: For maxLength inputs
- Add debouncing to cinput: Reduce event frequency
- Add custom validators: Allow parent to pass validation function
- Add async validation: Support server-side validation
LOW - Monitor¶
- classnames utility: Could use standard library or LWC utility
- Hard-coded error messages: Should use custom labels for i18n
- No loading state: For async validation scenarios
Maintenance Notes¶
Complexity: Medium Recommended Review Schedule: Quarterly
Key Maintainer Notes: - Used extensively across all forms in application - Password regex is very strict - document requirements for users - Email regex may need tightening for production use - Component supports external error setting - useful for server-side validation - isDirty flag prevents validation on untouched fields (good UX) - Supports both single-line and multi-line text entry - All events include fieldName and value for easy parent handling - Consider adding debouncing to cinput event if performance issues arise
Browser Compatibility: - Chrome: Latest - Firefox: Latest - Safari: Latest - Mobile: iOS 12+, Android 8+