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)
}