Transitioned PDF rendering in `EnvelopeReceiverPage.razor` from `PDF.js` to `DevExpress DxPdfViewer`. Updated code and documentation to reflect the verified API of `DevExpress.Blazor.PdfViewer` v25.2.3, addressing its limitations (e.g., lack of `GoToPageAsync`, `PageNumberChanged`). Implemented `CustomizeToolbar` for navigation/zoom controls and manual state tracking for `_currentPage` and `_viewerZoomLevel`. Replaced JavaScript interop for page count with the `PageCount` property. Retained the custom thumbnail sidebar due to API constraints. Added temporary debug tools for DOM analysis and navigation testing. Updated `TESTING_CHECKLIST.md` and added `DEVEXPRESS_V25_LIMITATIONS.md` to document the new strategy, API limitations, and testing scenarios. Cross-page signature navigation implemented with state updates, though visible page changes remain manual. Prepared for future improvements while ensuring functional migration to `DxPdfViewer`.
8.4 KiB
Debug Tools for DevExpress DxPdfViewer Integration
Purpose
This document describes temporary debug tools added to diagnose DevExpress DOM structure and page navigation issues.
IMPORTANT: TEMPORARY DEBUG CODE
These debug tools are TEMPORARY and should be REMOVED after resolving the page navigation issue.
Debug Tools Added
1. Debug UI Button (Toolbar)
Location: EnvelopeReceiverPage.razor - Toolbar Section
Visual: Orange button with "?" icon in the PDF viewer toolbar
What it does:
- Opens a floating overlay panel showing DevExpress DOM analysis
- Displays all input elements found in DxPdfViewer
- Shows which CSS selectors successfully find the page input
- Provides a "Test: Go to Page 2" button for live testing
Code Location:
@* DEBUG: DevExpress DOM Inspector *@
<div class="pdf-toolbar__section">
<button class="pdf-toolbar__btn" @onclick="ShowDebugUI" ...>
C# Method:
async Task ShowDebugUI()
{
await JSRuntime.InvokeVoidAsync("dxPdfViewerShowDebugUI");
}
2. JavaScript Debug Functions
Location: pdf-viewer.js
Functions Added:
window.dxPdfViewerDebugDOM()
- Console-based debug function
- Logs detailed DOM analysis to browser console
- Returns analysis object for programmatic inspection
window.dxPdfViewerShowDebugUI()
- HTML overlay-based debug function
- Creates visual debug panel without console interaction
- No security warnings (no need to paste code)
How to Use
Step 1: Run Application
dotnet run --project EnvelopeGenerator.Server/EnvelopeGenerator.Server
Step 2: Open Receiver Page
Navigate to: https://localhost:8088/envelope/{EnvelopeKey}
Step 3: Click Debug Button
- Look for the orange "?" button in the PDF toolbar (left side, after thumbnails toggle)
- Click it to open the debug overlay
Step 4: Review Debug Information
The overlay shows:
- Total Inputs: Number of input elements found
- Input Elements: Details of each input (type, class, ID, value)
- Selector Tests: Which CSS selectors work (✓) and which don't (✗)
- Toolbar: Whether toolbar element was found
- DxWidget: Whether DevExpress widget element was found
Step 5: Test Page Navigation
Click the "Test: Go to Page 2" button in the overlay
Step 6: Report Results
Copy the following information:
- Total Inputs: X
- Input Details: (type, className, id for each input)
- Selector Test Results: (which selectors show ✓ FOUND)
- Test Result: Did PDF actually navigate to page 2? (Yes/No)
- Console Messages: Any errors or warnings in F12 console
What to Look For
✓ Success Indicators
- At least one selector shows ✓ FOUND
- "Test: Go to Page 2" button actually changes PDF page
- Console shows:
✓ Found page input with selector: "..."
✗ Problem Indicators
- All selectors show ✗ NOT FOUND
- "Test: Go to Page 2" does nothing
- Console shows:
✗ Page input not found
After Diagnosis
Once the correct selector is identified:
1. Update window.dxPdfViewerGoToPage()
Update the selectors array in pdf-viewer.js to prioritize the working selector:
const selectors = [
'WORKING_SELECTOR_HERE', // ✓ Move this to top
'input[type="number"]',
// ... rest
];
2. Remove Debug Code
Files to clean up:
EnvelopeReceiverPage.razor
Remove:
@* DEBUG: DevExpress DOM Inspector *@
<div class="pdf-toolbar__section">
<button class="pdf-toolbar__btn" @onclick="ShowDebugUI" ...>
</button>
</div>
Remove C# method:
async Task ShowDebugUI() { ... }
pdf-viewer.js
Remove:
// ⚠ AUTO-DEBUG: Display results in HTML overlay
window.dxPdfViewerShowDebugUI = function() { ... }
Keep:
window.dxPdfViewerDebugDOM()- can be useful for future debugging (optional)window.dxPdfViewerGoToPage()- this is permanent (after fixing selector)
Troubleshooting
Debug UI doesn't open
- Check browser console (F12) for JavaScript errors
- Ensure
pdf-viewer.jsis loaded - Verify DxPdfViewer has finished rendering
"Page input not found" error
- DevExpress may not have rendered toolbar yet
- Try waiting 2-3 seconds after page load
- Check if DxPdfViewer is visible on screen
Selector works but page doesn't change
- DevExpress may require different event sequence
- Try adding more events (focus, click, etc.)
- May need to find DevExpress client API instead
SOLUTION: CustomizeToolbar + Manual State Tracking
Identified root cause:
- DevExpress v25.2.3 has no event support
PageNumberChangedevent does not existZoomLevelChangedevent does not existToolbarVisibleproperty does not existGoToPageAsync()method does not exist- Only
CustomizeToolbarevent is available
Verified working API (v25.2.3):
DocumentContentbyte[] – for feeding PDF ✓ZoomLeveldouble – zoom factor (1.5 = 150%) ✓IsSinglePagePreviewbool – single page mode ✓PageCountint (GET only) – replaces JS call ✓ActivePageIndexint (GET only) – current page index ✓CssClass,DocumentName,SizeMode✓
Implemented strategy:
- Create custom navigation/zoom buttons via
CustomizeToolbar - Manual state tracking with
_currentPage,_currentZoom,_viewerZoomLevel - Manually trigger overlay refresh after button clicks
- Replace JS getTotalPages() call with
_totalPages = _pdfViewer.PageCount
Correct code example:
protected void OnCustomizeToolbar(ToolbarModel toolbarModel)
{
toolbarModel.AllItems.Clear();
var prevButton = new ToolbarItem
{
Text = "Previous",
IconCssClass = "dx-icon-chevronprev",
Enabled = _currentPage > 1,
Click = async (args) =>
{
if (_currentPage > 1)
{
_currentPage--;
_viewerZoomLevel = _currentZoom / 100d; // 150 -> 1.5
await InvokeAsync(StateHasChanged);
await RenderSignatureButtonsAsync();
}
}
};
var nextButton = new ToolbarItem
{
Text = "Next",
IconCssClass = "dx-icon-chevronnext",
Enabled = _currentPage < _totalPages,
Click = async (args) =>
{
if (_currentPage < _totalPages)
{
_currentPage++;
_viewerZoomLevel = _currentZoom / 100d; // 150 -> 1.5
await InvokeAsync(StateHasChanged);
await RenderSignatureButtonsAsync();
}
}
};
toolbarModel.AllItems.Add(prevButton);
toolbarModel.AllItems.Add(nextButton);
}
PageCount usage (instead of JS):
// In OnAfterRenderAsync
if (_pdfViewer is not null && _pdfViewer.PageCount > 0)
{
_totalPages = _pdfViewer.PageCount; // JS getTotalPages() no longer needed
_pdfLoaded = true;
await InvokeAsync(StateHasChanged);
}
Known limitations:
- If user scrolls PDF, C# receives no notification, overlays may desync
- Thumbnail navigation only updates state, cannot move viewer
- Cross-page signature navigation limited without programmatic page switching
See: DEVEXPRESS_V25_LIMITATIONS.md – complete verified API reference
Expected Timeline
- ✓ Day 1: Add debug tools (DONE)
- ✓ Day 1: Collect DOM analysis data (DONE)
- ✓ Day 1: Identify root cause (DONE - v25.2.3 has no events)
- ✓ Day 1: Define workaround strategy (DONE - Custom toolbar with manual tracking)
- ✓ Day 1: Implement workaround (DONE)
- ⚠ Day 2: Test and document limitations
- ⚠ Day 2: Consider DevExpress upgrade or accept limitations
Related Files
EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverPage.razorEnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/js/pdf-viewer.jsRECEIVER_PDF_VIEWER_CONTEXT.md(main context document - UPDATED with new strategy)
Notes
- Debug UI uses inline styles to avoid CSS conflicts
- Overlay is positioned at
z-index: 99999to appear above everything - Close button removes overlay from DOM completely
- All debug output also goes to browser console for advanced inspection
- Debug findings led to complete strategy change - see RECEIVER_PDF_VIEWER_CONTEXT.md section 12-14
Remember: This is TEMPORARY debugging code. Delete after completing the new implementation strategy!