Product EngineeringFeaturesLab FormsFrontendlivehealth-frontend

Form Capturing (AOE Modal)

AOE modal architecture, rendering pipeline, field prop preparation, skip logic, and multi-section navigation.

๐Ÿ‘ค Ritu Kataria๐Ÿ“… Updated: Mar 13, 2026๐Ÿท๏ธ feature

Form Capturing โ€” AOE Modal

The AOE Modal (AOEModal) is the primary capture interface for Ask at Order Entry forms during the billing workflow. It handles multi-form, multi-section navigation, conditional skip logic, prefilling, confirmation messages, and validation.


6.1 AOE Modal Architecture

Component: src/components/reusable/Billing/components/AOE/AOEModal.tsx

Props:

  • aoeForms: AOEForm[] โ€” array of forms to capture
  • oldPatientData: JsonObject โ€” existing patient data used for prefilling
  • closeHandler() โ€” callback invoked on save/close

Redux State (from GENERIC slice):

  • activeAOEFormIndex โ€” which form is currently active
  • activeAOEFormSectionIndex โ€” which section within the active form
  • activeAOEFormMeta โ€” computed metadata for the active section: { process, subprocess, questions, testDetails }

6.2 Form Rendering Pipeline

aoeForms (source data)
    โ”‚
    โ–ผ
prepareActiveAOEFormDetails()
    โ”‚ Reads activeAOEFormIndex + activeAOEFormSectionIndex
    โ”‚ Resolves active form โ†’ active subprocess โ†’ ordered questions
    โ”‚
    โ–ผ
activeAOEFormMeta: { process, subprocess, questions, testDetails }
    โ”‚
    โ–ผ
AOEForm component
    โ”‚ Iterates questions[]
    โ”‚
    โ–ผ For each question:
    โ”‚
    โ”œโ”€โ”€ getLabFormInputComponent(type, field_type) โ†’ React Component
    โ”‚     Priority: Date types โ†’ LabFormDatePicker
    โ”‚               Signature โ†’ CustomSignature
    โ”‚               Others โ†’ getInputComponent(field_type) via inputMapper
    โ”‚               Fallback โ†’ CustomInput
    โ”‚
    โ””โ”€โ”€ prepareLabFormFieldProps() โ†’ Full prop object
          Includes: type, label, value, onChange, validation, errors
          โ–ผ
    <InputComponent {...fieldProps} />

6.3 Field Prop Preparation

prepareLabFormFieldProps() is the master prop builder that adapts each question's configuration into props for the input component:

Field Type FamilySpecial Prop Handling
Text / TextArea / Email / BarcodeStandard value, onChange, placeholder, maxLength
Number / Floatmin, max, step, number validation
CheckBox / RadioButtonisChecked computed from stored value, options
CheckBoxGroup / RadioGroup / Selectoptions array, multi-select handling
AddresssingleLineAddress mode, Google Places integration
Date / DateTime / TimedateFormat, timeFormat, minDate/maxDate from validation attrs
File / UploadS3 presigned URL generation, upload callbacks, allowedFileTypes
SignatureSignature pad rendering, S3 upload, bucketPath validation
CameraWebcam capture, S3 upload

onChange Callback Chain:


6.4 Value Storage

Values live in Redux.GENERIC.aoeFormValues with a nested structure:

aoeFormValues = {
  billLevel: {
    [processId: number]: {
      [questionId: number]: string | any
    }
  },
  testLevel: {
    [testId: number]: {
      [processId: number]: {
        [questionId: number]: string | any
      }
    }
  }
}

Determining Level:

  • testDetails === null โ†’ bill-level โ†’ aoeFormValues.billLevel[processId][questionId]
  • testDetails !== null โ†’ test-level โ†’ aoeFormValues.testLevel[testId][processId][questionId]

6.5 Prefilling

setPrefillingValue() runs on form initialization, iterating all questions:

  1. Today's Date Prefill: If todays_date attribute is true โ†’ sets moment() formatted by the question's date format.

  2. Source-Based Prefill: If allow_prefilling is true:

    • Reads prefilling_source (Patient, Bill, Home Collection)
    • Reads prefilling_options.source_field โ€” a dot-path (e.g., "patient.dob")
    • Traverses the source data using the dot-path to extract the value
    • Handles date format conversion if the source value is a date
    • Falls back to default_value attribute if source value is empty

6.6 Skip-To Logic (Conditional Navigation)

The skip-to system allows questions to redirect form navigation based on the answer given.

Configuration (stored as a serialized string in question attributes):

{
  "skip_to_conditions": "[{\"value\": \"Yes\", \"skip_type\": \"Process\", \"target_id\": 42}]"
}

Skip Types:

Skip TypeBehavior
ProcessJump to a specific process (form), removing intermediate forms
SubProcessJump to a specific section, removing intermediate sections
End ProcessEnd the current form, move to next (or finish)

Execution Flow:

Data cleanup during skip:

  • Intermediate forms removed from aoeForms
  • Intermediate sections removed from targeted forms
  • Questions below trigger point removed from current section
  • All affected values removed from aoeFormValues

Skip-to navigation physically modifies the aoeForms array in-memory โ€” removing intermediate forms, sections, and questions. This is a destructive operation on runtime state; it does not affect the persisted configuration.


6.7 Confirmation Messages

When a question has requires_confirmation_message: true and the user enters a value:

  1. afterFieldOnChange() detects the flag
  2. Shows AOEQuestionValueConfirmationModal with the configured message (HTML-rendered)
  3. Confirm & Proceed โ†’ continues (triggers skip-to if also configured)
  4. Cancel โ†’ removeQuestionValueOnCancelConfirmation() clears the entered value

6.8 Form-Level Validation

Field-Level Validation via labFormQuestionValidatorMapper(field_type, attributes):

Field TypeValidation
text, textarea, address, phonenumberMin/max length
numberMin/max integer value
floatMin/max value + max decimal places
date, datetimePast/future date constraints
timePast/future time constraints
signaturebucketPath must exist
OthersNo validation beyond mandatory check

Form-Level Validation via checkIsValidFormSection() / checkIsAOEFormValid():

  • Iterates all questions in the current section (or all forms)
  • For each question: checks if mandatory + empty, then runs the type-specific validator
  • Returns false on first error โ†’ disables the Next/Save button

6.9 Multi-Section / Form Navigation

Navigation Functions:

FunctionBehavior
goToNextSectionOrForm()Increment section index. If last section โ†’ increment form index, reset section to 0
goToPreviousSectionOrForm()Decrement section index. If first section โ†’ decrement form index, set section to last of previous form
isFirstSectionOfFirstForm()Returns true if at [formIndex=0, sectionIndex=0] โ†’ hides Previous button
isLastSectionOfLastForm()Returns true if at last form's last section โ†’ changes Next to "Save & Close"

Footer Behavior:

  • Previous: Hidden on first section of first form
  • Next: Calls handleNextClick(), which validates the current section before navigating
  • Save & Close: Shown on last section of last form โ†’ calls closeHandler()

File Reference: src/components/reusable/Billing/components/AOE/utils.ts (1726 lines โ€” navigation, validation, field props, skip logic, prefilling)

On this page