TDom
Central DOM access and manipulation class. ALL CSS and DOM operations in Framework components MUST go through TDom. Provides viewport tracking, element manipulation, event handling, and deferred execution.
Overview
TDom is the single point of access for all DOM manipulation in the Appzoola Framework. This is an absolute rule - components must NEVER call JavaScript DOM methods directly. TDom handles nil checks internally, provides consistent error handling, and enables viewport tracking for responsive layouts.
Unit & Declaration
UNIT Obj.App.DomAccess;
TDom = CLASS(TComponent)
// Can be instantiated or used via class methods
Key Design Principles
- Nil Safety - TDom handles nil ElementHandle checks internally
- Centralized - Single point for all DOM access enables consistent behaviour
- Deferred Execution - RequestAnimationFrame and ExecuteDeferred for TMS async timing
- Viewport Tracking - Device mode detection (desktop/tablet/mobile)
- Event Management - Consistent event listener attachment/removal
CSS Style Methods (Class Methods)
Sets a CSS style property on an element or control. Handles nil checks internally.
TDom.SetStyle(MyButton.ElementHandle, 'background-color', '#4285f4');
TDom.SetStyle(MyDiv, 'display', 'flex');
Removes a CSS style property from an element or control.
TDom.RemoveStyle(MyDiv, 'height'); // Let CSS handle height
Gets the current value of a CSS style property.
CSS Class Methods
Adds a CSS class to an element or control.
TDom.AddClass(MyCard, CssClassDashboardCard);
Removes a CSS class from an element or control.
Checks if an element has a specific CSS class.
Toggles a CSS class on an element.
Element Access Methods
Returns the document body element.
Returns the parent element of the given element.
Returns the bounding rectangle of an element (position and size).
Returns the offset height/width of an element including borders.
Event Methods
Adds an event listener to a control's element.
Tries to add an event listener. Returns False if element is nil or attachment fails.
Removes an event listener from a control's element.
Adds an event listener to the document (useful for mousemove/mouseup during drag).
Removes an event listener from the document.
Prevents default browser action and stops event propagation.
Gets mouse event coordinates and button from a mouse event.
Deferred Execution Methods
Schedules a callback for the next animation frame. Use for CSS updates that need to happen after layout.
TDom.RequestAnimationFrame(
PROCEDURE
BEGIN
ApplyStyles;
END);
Executes a callback after a short delay (typically one RAF cycle). Use for operations that must happen after TMS Web Core's async element creation.
TDom.ExecuteDeferred(@UpdatePosition);
Viewport/Device Mode Tracking
Starts viewport size monitoring. Must be called in component's Loaded method.
Returns current device mode based on viewport width.
| Mode | Viewport Width |
|---|---|
| dmMobile | < 768px |
| dmTablet | 768px - 1023px |
| dmDesktop | ≥ 1024px |
Event fired when device mode changes due to viewport resize.
FDom := TDom.Create(Self);
FDom.OnDeviceModeChanged := HandleDeviceModeChange;
FDom.InitializeViewportTracking;
PROCEDURE TMyComponent.HandleDeviceModeChange(Sender: TObject; NewMode: TDeviceMode);
BEGIN
CASE NewMode OF
dmMobile: ApplyMobileLayout;
dmTablet: ApplyTabletLayout;
dmDesktop: ApplyDesktopLayout;
END;
END;
ResizeObserver Methods
Creates a ResizeObserver for an element. Used by TCoreGridPanel for responsive layout.
Disconnects and destroys a ResizeObserver.
Adds a window resize event listener.
Usage Examples
Setting Multiple Styles
TDom.SetStyle(Card.ElementHandle, 'position', 'absolute');
TDom.SetStyle(Card.ElementHandle, 'top', '10px');
TDom.SetStyle(Card.ElementHandle, 'left', '20px');
TDom.SetStyle(Card.ElementHandle, 'width', '200px');
TDom.SetStyle(Card.ElementHandle, 'height', '150px');
Using with Controls (Preferred)
// Can pass TControl directly - TDom extracts ElementHandle
TDom.SetStyle(MyButton, 'background-color', Theme.PrimaryColor);
TDom.AddClass(MyPanel, 'card-highlighted');
Deferred Initialization
PROCEDURE TMyComponent.Loaded;
BEGIN
INHERITED;
{$IFDEF PAS2JS}
// Defer CSS application until DOM is ready
TDom.RequestAnimationFrame(
PROCEDURE
BEGIN
ApplyStyles;
InitializeEvents;
END);
{$ENDIF}
END;
Event Handling Pattern
// In component fields:
FMouseDownHandler: TJSEventHandler;
// In constructor:
FMouseDownHandler := @HandleMouseDown;
// In Loaded:
TDom.ExecuteDeferred(@AttachEventListeners);
// Attach procedure:
PROCEDURE TMyComponent.AttachEventListeners;
BEGIN
IF NOT TDom.TryAddEventListener(DragHandle, 'mousedown', FMouseDownHandler) THEN
console.log('Failed to attach event listener');
END;
// Cleanup in destructor:
TDom.RemoveEventListener(DragHandle, 'mousedown', FMouseDownHandler);
Common Patterns
Component Styling (NO nil checks needed)
PROCEDURE TMyCard.ApplyStyles;
BEGIN
// TDom handles nil checks internally - just call it
TDom.SetStyle(ElementHandle, 'background', '#ffffff');
TDom.SetStyle(ElementHandle, 'border-radius', '8px');
TDom.SetStyle(ElementHandle, 'box-shadow', '0 2px 4px rgba(0,0,0,0.1)');
END;
DO NOT DO THIS
// WRONG - Direct DOM access
IF Assigned(ElementHandle) THEN
ElementHandle.style.setProperty('background', '#ffffff');
// WRONG - Checking nil before TDom
IF ElementHandle <> NIL THEN
TDom.SetStyle(ElementHandle, 'background', '#ffffff');
// CORRECT - Just use TDom
TDom.SetStyle(ElementHandle, 'background', '#ffffff');
See Also
- TCoreDiv - Base component using TDom
- TMultiContainer - Uses TDom for responsive layout
- TCoreGridPanel - Uses TDom for CSS Grid
- Golden Rules - Coding standards