Skip to content

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/markup
  • registerAccountForm.js - JavaScript controller (711 lines)
  • registerAccountForm.css - Styling
  • registerAccountForm.js-meta.xml - Metadata configuration
  • utils.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

handlePhoneChange(event) {
    this.account.phoneNumber = event.detail.phoneNumber;
}

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

handleCaptchaVerified() {
    this.isCaptchaChecked = true;
}

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 notifications
  • lightning/uiObjectInfoApi: getObjectInfo, getPicklistValues

Custom LWC Components

  • c-form-input: Reusable form input component with validation
  • c-intl-tel-input: International telephone input with validation
  • c-re-captcha: reCAPTCHA component for spam prevention

Apex Classes

  • AccountController.isEmailExisting(): Validates email uniqueness
  • AccountController.registerUser(): Creates Account and User records
  • SelfRegisterController.login(): Authenticates newly registered user

Salesforce Objects & Fields

  • Account: Person Account with all profile fields
  • User: 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

  1. Fill Registration Form - Enter personal information, address, contact details
  2. Upload Avatar - Select and upload profile photo with preview
  3. Verify reCAPTCHA - Complete CAPTCHA to enable submission
  4. Submit Registration - Create account and automatically log in
  5. 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

  1. Navigate to Experience Builder
  2. Create or edit registration page
  3. Drag "Register Account Form" component to page
  4. Publish page
  5. 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