widgets

πŸ₯ LocumTele Medical Form System

Last Updated: January 21, 2025
Project Status: Production Ready
Live Demo: GitHub Pages

πŸš€ Quick Start

Generate a Medical Form

cd python-forms
python3 regenerate_complete_form.py

This creates a production-ready medical screening form at surveys/weightloss/GLP1-screener-live.html.

Embed in Your Website

<!-- Copy the entire HTML content from the generated file -->
<!-- Paste into your GHL custom HTML widget or any website -->

πŸ“‹ Project Overview

This is a complete medical form generation system for GHL (GoHighLevel) white-label healthcare businesses. The system generates dynamic, responsive medical screening forms from JSON data with advanced conditional logic, real-time BMI calculation, and comprehensive API integration. It’s designed specifically for telemedicine patient screening and integrates with n8n webhooks for data processing.

🎯 Target Audience

🎯 Project Goals & Business Context

Primary Objectives

  1. Generate medical screening forms for various treatments (GLP1, testosterone, etc.)
  2. Integrate with GHL as embeddable HTML widgets
  3. Stream data to n8n for automated patient processing workflows
  4. Provide conditional logic for medical screening requirements
  5. Calculate BMI and apply form-specific disqualification rules
  6. Handle state-based routing for sync vs async consultations

Target Market

πŸ“ Project Structure

ltGlobalWidgets/
β”œβ”€β”€ README.md                           # This file - Main documentation
β”œβ”€β”€ python-forms/                       # Core form generation system
β”‚   β”œβ”€β”€ enhanced_form_generator.py      # Main form generation engine
β”‚   β”œβ”€β”€ form_data_loader.py            # JSON data parser
β”‚   β”œβ”€β”€ regenerate_complete_form.py    # Form generation script
β”‚   β”œβ”€β”€ surveys/all-forms/             # Shared form sections
β”‚   └── components/                    # Universal form components
β”œβ”€β”€ surveys/                           # Generated forms and form data
β”‚   β”œβ”€β”€ weightloss/GLP1-screener-live.html  # Production form
β”‚   β”œβ”€β”€ weightloss/GLP1-screener.json      # Form data
β”‚   β”œβ”€β”€ hormone/Sermorelin-screener.json   # Hormone form data
β”‚   └── antiaging/NAD-screener.json        # Anti-aging form data
β”œβ”€β”€ docs/                              # Documentation and assets
β”‚   β”œβ”€β”€ api/                          # API documentation
β”‚   β”œβ”€β”€ brand/                        # Brand assets and CSS
β”‚   └── widgets/                      # Widget dashboard docs
β”œβ”€β”€ widget-dashboard.html             # Widget management interface
β”œβ”€β”€ forms-dashboard.html              # Forms management & embed code library
β”œβ”€β”€ api-dashboard.html                # API integration dashboard
└── archive-ignore/                   # Outdated files and old systems

πŸ”§ Technical Architecture

Core Components

1. Enhanced Form Generator (enhanced_form_generator.py)

Purpose: Main form generation engine Key Features:

Critical Methods:

2. Form Data Loader (form_data_loader.py)

Purpose: Intelligent JSON parser and data combiner Key Features:

Critical Methods:

3. Conditional Logic System

Purpose: Dynamic question visibility based on user answers Implementation: JavaScript functions within generated forms

Available Conditions:

Data Flow Architecture

JSON Data Sources β†’ Form Data Loader β†’ Enhanced Form Generator β†’ HTML Form
     ↓                    ↓                      ↓               ↓
surveys/all-forms/  Combines sections    Generates UI      User fills form
surveys/{category}/ Sorts questions      Adds JavaScript   JavaScript validates
                   Creates IDs          Applies styling   Sends to webhook

API Integration

Webhook Endpoint: https://locumtele.app.n8n.cloud/webhook/patient-screener

Data Structure Sent:

{
  "contact": {
    "name": "Patient Name",
    "email": "patient@email.com",
    "phone": "(555) 123-4567",
    "address": "123 Main St",
    "address2": "Apt 1",
    "city": "City",
    "state": "CA",
    "postalCode": "12345",
    "type": "patient"
  },
  "patient": {
    "rxRequested": "GLP1",
    "height": "5'10\"",
    "weight": "180",
    "BMI": "25.8"
  },
  "form": {
    "formType": "screener",
    "category": "Weightloss",
    "screener": "GLP1",
    "timestamp": "2025-01-21T...",
    "formVersion": "1.0",
    "answers": {
      "What is your exercise level?": "moderate",
      "Do you have any allergies?": "no",
      "Do you currently use tobacco or vape?": "no"
    },
    "consultType": "async"
  },
  "clinic": {
    "name": "",
    "id": "",
    "type": "healthcare"
  }
}

πŸ“Š Current Implementation Status

βœ… Completed Features

Core Functionality

User Experience

Medical-Specific Features

Technical Features

πŸ“Š Form Statistics

πŸ§ͺ Complete Testing Checklist

βœ… Functional Testing

  1. Phone number formatting and validation: Auto-formats, prevents letters, validates 10 digits
  2. Female gender β†’ pregnancy question appears: Conditional logic working
  3. Height/weight β†’ BMI calculates automatically: Real-time calculation
  4. BMI under 25 β†’ can proceed to see value: Form-specific disqualification rules
  5. Tobacco β€œyes” β†’ follow-up question appears: Tobacco conditional logic
  6. Disqualifying answers β†’ modern styled messages appear: Professional messaging
  7. Form submission β†’ complete data sent to webhook: API integration working
  8. State selection β†’ proper async/sync routing: State-based logic
  9. File uploads β†’ validation and visual feedback: Upload handling
  10. Form persistence β†’ remembers progress across sessions: Local storage working

βœ… UI/UX Testing

βœ… Integration Testing

πŸ”„ Development Workflow

Current Process

  1. Update JSON data: Modify files in surveys/all-forms/ or surveys/{category}/
  2. Update generator: Modify enhanced_form_generator.py for UI/logic changes
  3. Regenerate form: Run python3 regenerate_complete_form.py
  4. Test: Open surveys/weightloss/GLP1-screener-live.html in browser
  5. Deploy: Copy HTML content to GHL widget

Key Files to Modify

πŸ“š Documentation Index

πŸ₯ Core System Documentation

πŸŽ›οΈ Dashboard & Interface Documentation

πŸ”Œ API & Integration Documentation

πŸ“‹ Quick Reference

πŸ“š Knowledge Base

Critical Implementation Details

Conditional Logic Patterns

The system uses string matching in JavaScript to implement conditional logic:

// Example: Tobacco follow-up
if (condition === 'if_tobacco_yes' || condition === 'if_tobacco_use_yes') {
    const tobaccoInputs = document.querySelectorAll('input[type="radio"][value="yes"]:checked');
    for (let input of tobaccoInputs) {
        const questionText = input.closest('.question-container').querySelector('label[class*="question-label"]')?.textContent;
        if (questionText && (questionText.toLowerCase().includes('tobacco') || questionText.toLowerCase().includes('vape'))) {
            shouldShow = true;
            break;
        }
    }
}

BMI Calculation & Disqualification

BMI is calculated in real-time and displayed in the Patient Profile section. Disqualification logic is form-specific:

// BMI calculation
function calculateBMI() {
    const feet = parseInt(feetInput.value) || 0;
    const inches = parseInt(inchesInput.value) || 0;
    const weight = parseFloat(weightInput.value) || 0;

    if (feet > 0 && weight > 0) {
        const totalInches = (feet * 12) + inches;
        const heightInMeters = totalInches * 0.0254;
        const weightInKg = weight * 0.453592;
        const bmi = weightInKg / (heightInMeters * heightInMeters);

        // Display BMI
        bmiValueElement.textContent = bmi.toFixed(1);

        // Check disqualification (only for GLP1 forms)
        if (category === 'Weightloss' && form_name === 'GLP1' && bmi < 25) {
            // Show disqualification message
        }
    }
}

API Data Structure Logic

The webhook data building function dynamically finds form inputs and structures data:

// Build comprehensive form answers object with question text as keys
const formAnswers = {};
const contactFields = ['name', 'email', 'phone', 'address', 'city', 'state', 'postal'];

const allInputs = document.querySelectorAll('input, select, textarea');
allInputs.forEach(input => {
    if (input.name && input.value) {
        // Get question text
        const questionWrapper = input.closest('.question-wrapper');
        let questionText = questionWrapper?.querySelector('label')?.textContent?.trim() || input.name;

        // Remove asterisk from required fields
        questionText = questionText.replace('*', '').trim();

        // Skip contact info fields - they're already in contact section
        const isContactField = contactFields.some(field =>
            questionText.toLowerCase().includes(field) ||
            (field === 'name' && questionText.toLowerCase().includes('full name'))
        );

        if (!isContactField) {
            // Add to answers object
            formAnswers[questionText] = input.value;
        }
    }
});

Sync-Only States Logic

Certain states only support synchronous consultations:

const syncOnlyStates = ['AL', 'AK', 'AR', 'ID', 'IA', 'KS', 'KY', 'LA', 'ME', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NM', 'ND', 'OK', 'SC', 'SD', 'TN', 'UT', 'VT', 'WV', 'WY'];

if (syncOnlyStates.includes(selectedState)) {
    finalConsultType = 'sync';
} else {
    finalConsultType = consultType; // Use original consult type
}

πŸš€ Deployment & Integration

Forms Dashboard

The Forms Dashboard (forms-dashboard.html) provides a comprehensive management interface for medical forms:

πŸ“Š Dashboard Tab - Embed Code Library

πŸ“ Forms Tab - Form Management

πŸŽ›οΈ Control Panel Tab - Automation

⚠️ Note: HTML generation and embed code creation buttons were removed due to JavaScript template literal syntax issues. HTML files must be generated manually using the Python scripts in the python-forms/ directory.

πŸ”§ JavaScript Issue: Template literals (backticks with ${}) cause severe syntax errors when used within HTML content. Always use string concatenation ('string' + variable + 'string') instead of template literals when building HTML content or complex strings within HTML files.

For GHL Integration

  1. Generate form: cd python-forms && python3 regenerate_complete_form.py
  2. Extract HTML: Copy entire content from surveys/weightloss/GLP1-screener-live.html
  3. Embed in GHL: Paste as custom HTML widget
  4. Test webhook: Verify data reaches n8n endpoint at https://locumtele.app.n8n.cloud/webhook/patient-screener

For Client Deployment

  1. Open Forms Dashboard: forms-dashboard.html
  2. Navigate to Dashboard tab: Embed Code Library
  3. Search/filter forms: Use category toggles and search bar
  4. Copy embed code: Click β€œπŸ“‹ Copy” button for desired form
  5. Paste in client website: Embed code is ready for deployment

Local Development & Testing

# Navigate to project
cd /Users/tatyanagomez/Projects/ltGlobalWidgets/python-forms/

# Generate latest form
python3 regenerate_complete_form.py

# Open for testing
open surveys/weightloss/GLP1-screener-live.html

# Monitor network tab in browser dev tools to verify API calls

πŸ”§ Configuration & Customization

Key Configuration Points

Webhook URL

const response = await fetch('https://locumtele.app.n8n.cloud/webhook/patient-screener', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
});

Local Storage Key Format

const storageKey = `medicalForm_${form_name}_${category}`;
// Example: "medicalForm_GLP1_Weightloss"

BMI Disqualification Rules

// Only applies to GLP1 Weightloss forms with BMI < 25
if (category === 'Weightloss' && form_name === 'GLP1' && bmi < 25) {
    // Show disqualification
}

Styling Variables

/* Main theme colors */
:root {
    --primary-color: #333;
    --secondary-color: #555;
    --accent-color: #e74c3c;
    --background-gradient: linear-gradient(135deg, #fff 0%, #fef7f7 100%);
}

πŸ› οΈ Troubleshooting Guide

Common Issues & Solutions

Radio Buttons Pre-selecting

Issue: Radio buttons showing as selected on page load Solution: Clear localStorage for the form

localStorage.removeItem('medicalForm_GLP1_Weightloss');

Phone Validation Not Working

Issue: Phone field accepting letters or not validating Solution: Check formatPhoneInput() function and validation logic

Conditional Logic Not Triggering

Issue: Follow-up questions not appearing Solution:

  1. Check question text matching in JavaScript
  2. Verify property_show_condition in JSON data
  3. Ensure condition is added to checkQuestionVisibility() function

API Data Issues

Issue: Webhook not receiving expected data Solution:

  1. Check browser console for errors
  2. Verify webhook URL is accessible
  3. Check data structure in buildWebhookData() function

BMI Calculation Not Working

Issue: BMI not calculating or displaying Solution:

  1. Check height/weight input selectors
  2. Verify BMI calculation formula
  3. Ensure calculateBMI() is called on input changes

πŸ“ˆ Future Development Roadmap

Immediate Priorities

  1. Additional forms: Create testosterone, erectile dysfunction, other treatment forms
  2. Enhanced validation: Add more sophisticated medical validation rules
  3. Better error handling: More granular error messages and recovery
  4. Performance optimization: Reduce form load time and improve responsiveness

Medium-term Goals

  1. Form builder UI: Visual interface for creating new forms without coding
  2. Advanced conditional logic: More complex branching logic patterns
  3. Multi-language support: Spanish and other language translations
  4. Analytics integration: Track form completion rates and drop-off points

Long-term Vision

  1. AI-powered form optimization: Machine learning for form improvement
  2. Advanced medical algorithms: More sophisticated medical screening logic
  3. Integration marketplace: Connect with more healthcare platforms
  4. White-label customization: Client-specific branding and customization

πŸ“ž Contact & Support

Key Personnel

Documentation Locations

Repository Information

πŸ“… Project Timeline & Milestones

Development History

Recent Achievements (Latest Session)

πŸ” Code Quality & Standards

Coding Standards

Testing Standards

Maintenance Standards

πŸ†˜ Support & Contact

Getting Help

Key Personnel

Documentation Locations

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is part of the LocumTele GHL widget system for white-label healthcare businesses.

πŸ”„ Version History


Document Status: βœ… Complete and Current
Next Review Date: [To be scheduled]
Version: 1.0 (January 21, 2025)

This document serves as the definitive reference for the LocumTele Medical Form System project. It should be updated whenever significant changes are made to the system architecture, features, or configuration.

Built with ❀️ for healthcare providers