What problem does it solve? Liferay's Data Engine renders form fields (Document Types, Objects, Forms) with unpredictable IDs, async mounting, and non-native controls, making it hard to add client-side behavior like conditional show/hide, live hints, or submit blocking without replacing the editor or writing an OSGi module. ## Core Features & Use Cases - Screen and field targeting: Detect the correct portlet screen via render-request query params, resolve Document Type IDs by externalReferenceCode, and locate rendered fields using tag-restricted ddm$$<fieldName>$ selectors or stable data-qa-id containers. - Robust async behavior: Wait for asynchronously rendered fields with scoped MutationObservers, debounce mutation callbacks, guard against re-entrancy, and parse JSON-encoded values from hidden inputs behind custom comboboxes. - Client-side submit blocking: Intercept form submission with a capture-phase submit listener to block Publish/Save on a condition, without monkey-patching Liferay internals. - Use Case: Add a live format hint to a Document Type field, show or hide one field based on another field's selection, and block the Publish button when a validation condition fails — all from a single type: globalJS Client Extension. ## Quick Start Build a globalJS Client Extension that hides the Category field on a Document Type edit screen unless the Type field is set to a specific value.