Skip to content

Conversation

@TDannhauer
Copy link
Contributor

Fix: JavaScript ReferenceError in Turba Contact Form Tabs

Problem

Users experienced a ReferenceError: sections_Turba_View_Contact is not defined error when clicking tabs in the Turba contact form. All tabs except the default "personal" tab were unclickable.

Root Cause

The issue was a JavaScript timing problem:

  1. The form_sections.js script was loaded in the HTML header via Horde_PageOutput::addScriptFile()
  2. The sections_Turba_View_Contact variable was initialized in the footer via Horde_PageOutput::addInlineScript()
  3. The HTML tabs with onclick handlers were rendered in the body, immediately after header() was called
  4. When users clicked tabs, the variable didn't exist yet because it was only initialized in the footer

Error sequence:

  • Header: Script loaded (but may not be executed yet)
  • Body: Tabs rendered with onclick="sections_Turba_View_Contact.toggle(...)"
  • Footer: Variable initialized (too late)

Solution

Approach

Instead of loading the script in the header and initializing the variable in the footer, we:

  1. Embed the script inline in the body (before tabs are rendered)
  2. Initialize the variable directly in the body (immediately after tabs are rendered)

This guarantees synchronous execution order: Script → Tabs → Variable

Implementation

File: vendor/horde/form/lib/Horde/Form/Renderer.php

Changes:

  • Removed $page->addScriptFile('form_sections.js', 'horde') call
  • Added inline script embedding: Read form_sections.js from filesystem and output directly in body
  • Moved variable initialization from footer to body (right after tabs HTML)

Code Flow:

// 1. Embed script inline in body (lines 157-169)
$script_path = $GLOBALS['registry']->get('jsfs', 'horde') . 'form_sections.js';
if (file_exists($script_path)) {
    $script_content = file_get_contents($script_path);
    echo '<script type="text/javascript">' . "\n";
    echo '//<![CDATA[' . "\n";
    echo $script_content . "\n";
    echo '//]]>' . "\n";
    echo '</script>' . "\n";
}

// 2. Render tabs HTML (lines 171-189)
// ... tabs with onclick handlers ...

// 3. Initialize variable in body (lines 191-197)
echo '<script type="text/javascript">' . "\n";
echo '//<![CDATA[' . "\n";
echo $var_script . "\n";
echo '//]]>' . "\n";
echo '</script>' . "\n";

Why This Works

Why Scripts in Header Don't Work

Even though scripts in the header are loaded synchronously (without async or defer attributes), there can be timing issues:

  1. Browser parsing behavior: The browser may start parsing the body while header scripts are still executing
  2. PHP execution flow: When _renderSectionTabs() is called after header(), the header scripts may not have finished executing yet
  3. Variable dependency: The variable initialization in the body requires the script to be fully executed, but this isn't guaranteed when relying on header scripts

Why Inline Scripts Are Necessary

Guaranteed execution order:

  • Inline scripts in the body execute synchronously in document order
  • The script is embedded directly before the variable initialization, ensuring Horde_Form_Sections exists when needed

Execution sequence:

  1. Script inline in body → Horde_Form_Sections class is defined
  2. Tabs HTML rendered → with onclick handlers
  3. Variable initialization → sections_Turba_View_Contact is created

Benefits:

  • ✅ No timing issues: Script executes before variable initialization
  • ✅ No race conditions: Guaranteed sequential execution
  • ✅ Immediate availability: Variable is ready when tabs are rendered

Testing

Before fix:

  • ReferenceError: sections_Turba_View_Contact is not defined
  • ❌ Tabs other than default tab were unclickable

After fix:

  • ✅ No JavaScript errors
  • ✅ All tabs are clickable and functional
  • ✅ Tab switching works correctly

Technical Details

Before/After Comparison

Aspect Before After
Script loading Header (addScriptFile()) Inline in body
Variable initialization Footer (addInlineScript()) Directly in body
Execution order Unpredictable Guaranteed: Script → Variable
Timing issues Yes (race condition) No (synchronous)

Files Modified

  • vendor/horde/form/lib/Horde/Form/Renderer.php
    • Modified _renderSectionTabs() method
    • Removed header script loading
    • Added inline script embedding
    • Moved variable initialization to body

Related Issues

  • Fixes: Uncaught ReferenceError: sections_Turba_View_Contact is not defined
  • Fixes: Tabs in Turba contact form not clickable

Refactor JavaScript inclusion for form sections to ensure synchronous loading and immediate availability of variables.
@amulet1
Copy link
Collaborator

amulet1 commented Dec 16, 2025

The proper fix to the issue is in horde/turba#20.

@TDannhauer
Copy link
Contributor Author

fixed by horde/turba#20.

at least my ugly workaround PR led to a proper expert fix ;)

@TDannhauer TDannhauer closed this Dec 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants