import { createRoot } from 'react-dom/client' import { fetchPublishedForms } from '@epicformbuilder/public/services/api' import ConfigurationLoader from '@epicformbuilder/common/services/ConfigurationLoader' import './public.css' import App from './App' import PickAForm from './scenes/PickAForm' import NoForm from './scenes/NoForm' function init() { const widgets = document.querySelectorAll('.epicforms:not( [data-initialized="true"] )') if (0 !== widgets.length) { if (!window.__EPICFORMBUILDER__) { window.__EPICFORMBUILDER__ = { __WP_API__: window?.wpApiSettings } } // Grab all the application elements on a page and render all of them widgets.forEach( async element => { try { // Set a flag to avoid double initialization. element.setAttribute( 'data-initialized', 'true' ) const id = element.dataset?.id || null if ( ! id ) { throw new Error( `No Form is assigned to this widget.` ) } const root = createRoot( element ) root.render( ) } catch ( error ) { const root = createRoot( element ) // In Elementor editor mode, show the form picker to select a form. if ( window?.elementorFrontend?.isEditMode() ) { // We have to load the configuration because the API endpoint and the Router are both stored there. await ConfigurationLoader.load( "public" ) let options = [], loadError = null try { options = await fetchPublishedForms() } catch ( e ) { loadError = e?.message || 'The list of forms could not be loaded.' } root.render( ({ value: form.uid, label: form.title }) ) } error={ loadError } onChange={ ( form_id ) => { // The widget renders inside the editor's preview iframe, but the // Elementor editor app and its command bus ($e) live in the parent // window. Resolve this specific widget's container by its Elementor // element id and change the setting through the command pipeline so // the widget re-renders, persists, and records undo history — a raw // model.setSetting() updates the value silently but never re-renders. const editor = window.elementor ?? window.parent?.elementor const commands = window.$e ?? window.parent?.$e const elementId = element.closest( '.elementor-element' )?.dataset?.id const container = elementId ? editor?.getContainer?.( elementId ) : null if ( container && commands ) { commands.run( 'document/elements/settings', { container, settings: { form_id }, // The change originates on the canvas, not from the panel // control, so mark it external — otherwise the "Form to // display" select keeps its old displayed value. options: { external: true }, } ) } }} /> ) // In non-editor mode, show the error message. } else { root.render( ) } } } ) } } // Elementor editor's iframe. if (window?.jQuery && window?.elementorFrontend && elementorFrontend.isEditMode()) { jQuery(window).on( 'elementor/frontend/init', () => { elementorFrontend.hooks.addAction('frontend/element_ready/epicforms.default', init) } ) // Elementor preview/view mode. } else { document.addEventListener('DOMContentLoaded', init) }