Component Name: registerAccountForm¶
Last Updated: 2025-10-22 Source Code: .temp-staging-flows/force-app/main/default/lwc/registerAccountForm/
API Name: c-register-account-form Type: Form Component Target: lightningCommunity__Page, lightningCommunity__Default
Business Purpose¶
The registerAccountForm component provides a comprehensive self-service user registration experience for AANP's member portal, handling account creation, user profile setup, and automatic login. It supports international address validation, phone number formatting, avatar uploads, reCAPTCHA verification, and comprehensive data collection for member onboarding. This is the primary entry point for new AANP members who haven't yet purchased a membership but want to create a portal account.
User Interface¶
Visual Description¶
- Layout: Single-page registration form with multiple sections, card-based design
- Key UI Elements:
- Personal information fields (name, credentials, suffix)
- Email and password fields with validation feedback
- Address form with country/state dropdowns
- Phone number input with international validation
- Avatar/profile photo upload with preview
- Communication preference checkboxes
- reCAPTCHA verification
- Submit button with loading state
- Responsive: Mobile-optimized with stacked layout, touch-friendly inputs
Screenshots¶
- Desktop view: Wide form with multi-column layout for name fields
- Mobile view: Single-column stacked form with full-width inputs
Component Structure¶
Files¶
registerAccountForm.html- Template/markupregisterAccountForm.js- JavaScript controller (711 lines)registerAccountForm.css- StylingregisterAccountForm.js-meta.xml- Metadata configurationutils.js- Helper utilities for region mapping (58 lines)__tests__/- Test directory
HTML Template Structure¶
<template>
<div class="register-form-container">
<form onsubmit={handleSubmit}>
<!-- Personal Information Section -->
<div class="section-personal-info">
<c-form-input label="First Name" name="firstName" required></c-form-input>
<c-form-input label="Middle Name" name="middleName"></c-form-input>
<c-form-input label="Last Name" name="lastName" required></c-form-input>
<c-form-input label="Suffix" name="suffix" type="dropdown"></c-form-input>
<c-form-input label="Credentials" name="credentials"></c-form-input>
</div>
<!-- Email & Password Section -->
<div class="section-auth">
<c-form-input label="Email" name="email" type="email" required></c-form-input>
<c-form-input label="Confirm Email" name="emailConfirm" type="email" required></c-form-input>
<c-form-input label="Password" name="password" type="password" required></c-form-input>
<c-form-input label="Confirm Password" name="confirmPassword" type="password" required></c-form-input>
</div>
<!-- Address Section -->
<div class="section-address">
<c-form-input label="Country" name="countryCode" type="dropdown" required></c-form-input>
<c-form-input label="State/Province" name="stateCode" type="dropdown" required={requiredState}></c-form-input>
<c-form-input label="Province Name" name="provinceName" if:false={requiredState}></c-form-input>
<c-form-input label="Address" name="address" required></c-form-input>
<c-form-input label="City" name="city" required></c-form-input>
<c-form-input label="Postal Code" name="postalCode" required></c-form-input>
<c-form-input label="Company Name" name="companyName"></c-form-input>
</div>
<!-- Phone Section -->
<div class="section-phone">
<c-intl-tel-input onchange={handlePhoneChange}></c-intl-tel-input>
</div>
<!-- Avatar Upload -->
<div class="section-avatar">
<input type="file" accept="image/*" onchange={handleAvatarUpload} />
<template if:true={account.avatar.previewLink}>
<img src={account.avatar.previewLink} alt="Avatar Preview" />
</template>
</div>
<!-- Communication Preferences -->
<div class="section-preferences">
<input type="checkbox" name="excludeFromThirdPartySolicitations" onchange={handleCheckboxChange} />
<label>Opt out of third-party solicitations</label>
<input type="checkbox" name="preferredMethodCommunicationText" onchange={handleCheckboxChange} />
<label>Receive text message communications</label>
</div>
<!-- reCAPTCHA -->
<template if:true={showReCaptcha}>
<c-re-captcha oncaptchaverified={handleCaptchaVerified}></c-re-captcha>
</template>
<!-- Submit Button -->
<button type="submit" disabled={!isCaptchaChecked || formWasSent}>
{submitButtonLabel}
</button>
<!-- Error Message -->
<template if:true={formHasErrors}>
<div class="error-message">{formErrorMessage}</div>
</template>
</form>
</div>
</template>
Key Template Features: - Uses custom c-form-input component for consistent input styling and validation - c-intl-tel-input for international phone validation - c-re-captcha for spam prevention - Conditional rendering for state vs province fields - File input for avatar upload with preview - Real-time validation feedback - Loading states and error messages
JavaScript Controller¶
Properties (API)¶
This component has no @api properties - standalone form component.
Tracked Properties¶
@track account¶
- Type:
Object(complex nested object) - Purpose: Stores all form data for registration
- Updated When: User types in form fields
- Key Properties:
- firstName, middleName, lastName, suffix, credentials
- email, emailConfirm, password, confirmPassword
- countryCode, stateCode, provinceName, city, address, postalCode, companyName
- phoneNumber
- excludeFromThirdPartySolicitations, preferredMethodCommunicationText
- avatar: { filename, base64, previewLink }
@track countryOptions, @track stateOptions, @track allRegionOptions¶
- Type:
Array - Purpose: Country and state picklist options for dropdowns
- Updated When: Wire adapter loads picklist values
- Sorting: US and CA prioritized at top of country list
@track requiredState¶
- Type:
Boolean - Purpose: Determines if state field is required based on country
- Updated When: Country selection changes
@track isCaptchaChecked¶
- Type:
Boolean - Purpose: Tracks reCAPTCHA verification status
- Updated When: User completes reCAPTCHA
@track showReCaptcha¶
- Type:
Boolean - Purpose: Controls reCAPTCHA display
- Updated When: renderedCallback (set to true)
formHasErrors, formErrorMessage, formWasSent¶
- Type:
Boolean/String - Purpose: Form-level error tracking and submission state
- Updated When: Form validation, API errors, submission
Wire Adapters¶
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })¶
Purpose: Retrieves Account object metadata for record type ID Error Handling: Console error logging
@wire(getPicklistValues, { recordTypeId, fieldApiName: COUNTRY_CODE_FIELD })¶
Purpose: Fetches country picklist values Post-Processing: Sorts with US/CA at top, rest alphabetical
@wire(getPicklistValues, { recordTypeId, fieldApiName: STATE_CODE_FIELD })¶
Purpose: Fetches state/region picklist values Post-Processing: Uses mapRegionCodes utility to create country-to-states mapping
Public Methods¶
No @api public methods.
Event Handlers¶
handleSubmit¶
async handleSubmit(event) {
event.preventDefault();
// Validates form
// Checks email uniqueness
// Calls registerUser Apex
// Auto-login with new credentials
// Redirects to home page
}
Triggered By: Form submission Event Type: submit Action: 1. Validates all required fields 2. Checks password match and strength 3. Verifies email uniqueness (isEmailExisting Apex) 4. Calls registerUser() Apex with account data 5. Automatically logs in user (login Apex) 6. Redirects to home page with success toast
handleInputChange¶
handleInputChange(event) {
const { name, value } = event.detail || event.target;
this.account[name] = value;
}
Triggered By: Input field changes Event Type: Custom event from c-form-input or native input change Action: Updates account object property
handleCountryChange¶
handleCountryChange(event) {
this.account.countryCode = event.detail.value;
this.account.stateCode = '';
this.updateStateOptions();
}
Triggered By: Country dropdown selection Action: 1. Updates country code 2. Clears state selection 3. Updates state options based on country 4. Sets requiredState flag
handlePhoneChange¶
Triggered By: Phone input change from c-intl-tel-input Event Type: Custom event with phone number detail Action: Updates account.phoneNumber
handleAvatarUpload¶
handleAvatarUpload(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = () => {
this.account.avatar.base64 = reader.result;
this.account.avatar.filename = file.name;
this.account.avatar.previewLink = reader.result;
};
reader.readAsDataURL(file);
}
}
Triggered By: File input change Event Type: change Action: 1. Reads selected image file 2. Converts to base64 data URL 3. Stores in account.avatar 4. Shows preview
handleCheckboxChange¶
handleCheckboxChange(event) {
const { name, checked } = event.target;
this.account[name] = checked;
}
Triggered By: Checkbox clicks Event Type: change Action: Updates boolean fields in account object
handleCaptchaVerified¶
Triggered By: reCAPTCHA verification success Event Type: Custom event from c-re-captcha Action: Enables submit button
Private Methods¶
updateStateOptions¶
Purpose: Updates state dropdown options based on selected country Called By: Country change handler Logic: Filters allRegionOptions by country code, sets requiredState flag
validateForm¶
Purpose: Validates all form fields before submission Returns: Boolean indicating validity Logic: Checks required fields, email format, password strength, email match, password match
Events¶
Events Dispatched¶
ShowToastEvent¶
this.dispatchEvent(new ShowToastEvent({
title: 'Success',
message: 'Registration successful! Logging you in...',
variant: 'success'
}));
Purpose: Success/error notifications When Fired: After registration success or on validation errors
Events Handled¶
oncaptchaverified (from c-re-captcha)¶
Purpose: Enables form submission after CAPTCHA verification Handler: handleCaptchaVerified
Custom events from c-form-input¶
Purpose: Receives input changes from child form components Handler: handleInputChange
Styling (CSS)¶
Custom CSS Classes¶
.register-form-container: Main container styling.section-*: Section containers with spacing.error-message: Error message styling- Uses Bootstrap/SLDS classes for grid and form styling
Responsive Breakpoints¶
- Mobile (<768px): Single-column stacked layout
- Tablet/Desktop: Multi-column layout for name fields
Dependencies¶
Lightning Web Components (Base)¶
lightning/platformShowToastEvent: Toast notificationslightning/uiObjectInfoApi: getObjectInfo, getPicklistValues
Custom LWC Components¶
c-form-input: Reusable form input component with validationc-intl-tel-input: International telephone input with validationc-re-captcha: reCAPTCHA component for spam prevention
Apex Classes¶
AccountController.isEmailExisting(): Validates email uniquenessAccountController.registerUser(): Creates Account and User recordsSelfRegisterController.login(): Authenticates newly registered user
Salesforce Objects & Fields¶
Account: Person Account with all profile fieldsUser: Community user record created during registration
External Libraries/Modules¶
utils.js: mapRegionCodes helper for state/country mapping- FileReader API: For avatar image processing
Configuration¶
Component Meta XML¶
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>Register Account Form</masterLabel>
<targets>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
</LightningComponentBundle>
Available On: - Experience Cloud pages - Experience Cloud default pages
Design Properties¶
No configurable properties.
User Interactions¶
Actions Available to Users¶
- Fill Registration Form - Enter personal information, address, contact details
- Upload Avatar - Select and upload profile photo with preview
- Verify reCAPTCHA - Complete CAPTCHA to enable submission
- Submit Registration - Create account and automatically log in
- Toggle Communication Preferences - Opt in/out of marketing communications
Validation & Error Handling¶
Client-Side Validation: - All name fields: Required, character limits - Email: Required, valid format, must match confirmation, uniqueness check - Password: Required, minimum length, must match confirmation, strength requirements - Address: Country, city, postal code required; state required for applicable countries - Phone: Valid international format - Avatar: Image file type and size validation (if implemented) - reCAPTCHA: Must be completed
Error Messages: - Email uniqueness: "An account with this email already exists" - Password mismatch: "Passwords do not match" - Required field: "This field is required" - Email format: "Please enter a valid email address" - Generic error: Displays API error message or generic failure message
Loading States: - Submit button shows spinner and disables during processing - Form disabled during submission
Data Flow¶
Input Data Flow¶
Component Load
↓
@wire adapters fetch picklist values
↓
User fills form fields
↓
handleInputChange updates account object
↓
User completes reCAPTCHA
↓
isCaptchaChecked set to true, enables submit
Output Data Flow¶
User clicks Submit
↓
validateForm() checks all fields
↓
isEmailExisting() checks uniqueness
↓
registerUser() Apex → Creates Account and User
↓
login() Apex → Authenticates user
↓
Navigate to home page
↓
Show success toast
Performance Considerations¶
Render Optimization: - Conditional rendering for state vs province - reCAPTCHA lazy-loaded in renderedCallback
Data Volume: - Single form submission (no pagination needed) - Country/state picklists cached by wire adapter
API Call Optimization: - Email uniqueness check on submit (not real-time) - Single registration API call - Auto-login uses cached credentials
Accessibility (a11y)¶
ARIA Labels: - Form inputs have associated labels - Error messages should use aria-describedby - Submit button has descriptive text
Keyboard Navigation: - Tab order follows natural form flow - Submit can be triggered with Enter key
Screen Reader Support: - Labels properly associated with inputs - Error messages announced (if implemented) - Loading state announced (if implemented)
Color Contrast: - Form styling should meet WCAG AA standards
Testing¶
Jest Tests¶
Test File: __tests__/registerAccountForm.test.js may exist
Coverage: Unknown
Recommended Test Scenarios: - Component renders correctly - Form validation works - Email uniqueness check functions - Country/state dropdown population - Password match validation - Avatar upload works - reCAPTCHA integration - Form submission and auto-login - Error handling
Manual Testing Checklist¶
- [ ] Desktop browsers (Chrome, Firefox, Safari, Edge)
- [ ] Mobile browsers (iOS Safari, Android Chrome)
- [ ] Tablet view
- [ ] Accessibility (screen reader, keyboard-only)
- [ ] Email with existing account (should error)
- [ ] Password mismatch (should error)
- [ ] International addresses (various countries)
- [ ] Avatar upload (various file types and sizes)
- [ ] reCAPTCHA verification
- [ ] Auto-login after registration
- [ ] Communication preference checkboxes
Usage Examples¶
In App Builder¶
- Navigate to Experience Builder
- Create or edit registration page
- Drag "Register Account Form" component to page
- Publish page
- Assign to /register URL route
In Parent Component¶
Not designed for embedding. Standalone form component.
Changes & History¶
Features: - International address support with country/state validation - Avatar upload functionality - reCAPTCHA integration - Auto-login after registration - Communication preference management
Known Technical Debt: - Code overlap with membershipWizard component (40-50% duplication) - Avatar upload uses base64 (should stream to server) - Password validation rules hardcoded (should be dynamic) - Should use custom form component library for consistency
Pre-Go-Live Concerns¶
CRITICAL - Fix Before Go-Live¶
- Password policy exposed: Client-side validation reveals password requirements to attackers
- Avatar security: File uploads need server-side validation (type, size, malware scan)
- Email enumeration: isEmailExisting may enable account discovery attacks
- Auto-login security: Verify session hijacking prevention
HIGH - Address Soon After Go-Live¶
- No email verification: Users not required to verify email address
- Server-side validation: All client validation must be duplicated on server
- Error messages: May leak too much system information
- Testing coverage: Needs comprehensive automated tests
MEDIUM - Future Enhancement¶
- Component refactoring: Consolidate with membershipWizard to reduce duplication
- Multi-step wizard: Break form into steps for better UX
- Password strength meter: Visual feedback for password strength
- Email verification: Send confirmation email before activation
LOW - Monitor¶
- reCAPTCHA accessibility: Ensure CAPTCHA is accessible
- Console logging: Remove debug statements
- Performance: Monitor form completion time
- Browser compatibility: Test in all target browsers
Maintenance Notes¶
Complexity: High Recommended Review Schedule: Monthly during active development, quarterly maintenance
Key Maintainer Notes: - Code duplication: Shares logic with membershipWizard - refactor together - Apex dependencies: registerUser and login methods are critical - test thoroughly - reCAPTCHA: External dependency - monitor for API changes - Auto-login: Session management must be secure - Avatar storage: Understand file storage implementation before changes
Browser Compatibility: - Chrome: 90+ - Firefox: 88+ - Safari: 14+ - Edge: 90+ - FileReader API required (IE11 not supported)
Security Considerations: - Email verification workflow should be added - Server-side validation must match client-side - Avatar uploads need malware scanning - Rate limiting on registration to prevent spam - Password policy should be enforced server-side
Recommended Next Steps: 1. Immediate: Add email verification workflow 2. Short-term: Comprehensive test suite 3. Medium-term: Refactor to share code with membershipWizard 4. Long-term: Multi-step wizard UI redesign