Files
2026-07-12 10:17:17 -04:00

67 lines
2.8 KiB
Markdown

# Element ID Mismatch Debugging
Recurring class of bugs in ShopProQuote: JavaScript event handlers look for elements by ID,
but the actual HTML uses a slightly different ID. The handler silently gets `null`, no error is
thrown, and the button appears to do nothing.
## Common Patterns
### 1. Fallback chain missing the actual ID
```javascript
// BROKEN — actual ID is 'ai-write-btn-quote', none of these match
const btn = document.getElementById('ai-write-btn-main') ||
document.getElementById('ai-write-btn-fallback');
// FIXED — add the actual ID first
const btn = document.getElementById('ai-write-btn-main') ||
document.getElementById('ai-write-btn-fallback') ||
document.getElementById('ai-write-btn-quote');
```
### 2. Prefix/suffix mismatch (-btn vs no -btn, -settings vs -quote)
| Code looks for | Actual HTML ID | Pattern |
|---------------|----------------|---------|
| `service-edit-save-quote` | `service-edit-save-btn-quote` | Missing `btn` |
| `service-edit-form` | `service-edit-form-quote` | Missing `-quote` suffix |
| `service-edit-name` | `service-edit-name-quote` | Missing `-quote` suffix |
| `custom-service-technician-notes` | `service-edit-technician-notes-quote` | Wrong modal entirely |
### 3. Explanation textarea across different modals
```javascript
// Safe fallback chain covering all modal variants:
const explanation = document.getElementById('service-edit-explanation-quote') || // quote builder
document.getElementById('service-edit-explanation-main') || // main edit
document.getElementById('service-edit-explanation'); // legacy
```
### 4. Technician notes across different modals
```javascript
// Safe fallback chain:
const notes = document.getElementById('service-edit-technician-notes-quote') || // quote edit modal
document.getElementById('service-edit-technician-notes') || // settings edit
document.getElementById('custom-service-technician-notes'); // add custom
```
## Diagnostic Approach
When a button silently does nothing:
1. **Find the handler** — search for `getElementById` calls that should be finding this element
2. **Check the actual HTML ID** — read the HTML to see the real `id` attribute
3. **Compare** — if they don't match, add the real ID to the fallback chain
4. **Verify** — grep for both the code-side ID and the HTML-side ID
## Recurring ID Convention
The codebase uses two modal naming conventions that coexist:
- **Quote builder modals**: `-quote` suffix (e.g., `service-edit-modal-quote`, `ai-write-btn-quote`)
- **Settings modals**: `-settings` suffix (e.g., `service-edit-explanation-settings`)
- **Legacy modals**: no suffix (e.g., `service-edit-modal`, `service-edit-name`)
When writing new handlers, always include ALL THREE variants in the fallback chain.