Turn Any Element Into a Form
Mark any HTML form inside a Composer widget, via the data-atom-form attribute or the Layers panel, to turn it into a managed form that captures submissions, sends emails, and fires webhooks.
Any <form> element inside a Composer widget becomes a Composer-managed form once it's marked as one. UiChemy then intercepts the submission, applies spam protection, and routes it to whichever actions you've configured. No plugin shortcodes, no drag-and-drop builder.
There are two ways to mark a form:
- In the HTML, add
data-atom-form="your-key"directly to the<form>tag. - In the Layers panel, right-click the
formelement and choose Mark as form from the context menu.
Use Cases
- Building a custom contact, quote-request, or booking form with exactly the fields and layout you want, not a generic form-plugin template.
- Routing different forms to different destinations, a contact form to
save_db+email, a lead form tosave_db+webhookfor your CRM. - Adding a form inside a Theme Builder header, footer, or popup, it works the same as on a regular page.
Step 1: Write Your Form in HTML
Open the Composer widget in Developer Mode (Style tab → Edit Code) and write your form in the HTML panel. A basic contact form:
<form data-atom-form="contact">
<div class="field">
<label for="name">Name</label>
<input type="text" name="name" id="name" required>
</div>
<div class="field">
<label for="email">Email</label>
<input type="email" name="email" id="email" required>
</div>
<div class="field">
<label for="message">Message</label>
<textarea name="message" id="message" rows="5"></textarea>
</div>
<button type="submit">Send Message</button>
</form>
The value in data-atom-form is the form's key, it becomes the form name in the submissions dashboard and the identifier used to route the submission to the right actions. Use a short, descriptive slug: contact, newsletter, quote-request.
Prefer not to type the attribute by hand? Open the Layers panel (the layers icon in the canvas toolbar), right-click the form element, and choose Mark as form instead. The same menu offers Mark as loop for repeating elements.
Step 2: Add Your Fields
UiChemy captures every named field in the form. Use any standard HTML form element:
| Element | Example |
|---|---|
| Text input | <input type="text" name="company"> |
| Email input | <input type="email" name="email"> |
| Phone input | <input type="tel" name="phone"> |
| Textarea | <textarea name="message"></textarea> |
| Select dropdown | <select name="service"><option value="web">Web</option></select> |
| Checkbox | <input type="checkbox" name="newsletter" value="yes"> |
| Hidden field | <input type="hidden" name="source" value="homepage"> |
The name attribute is required. Fields without a name attribute aren't captured in the submission.
Name one of your fields email to have it displayed in the Email column of the submissions dashboard and available in email notification templates. Use the HTML required attribute for client-side validation, UiChemy validates on the server side too, but required gives users immediate feedback before they submit.
Step 3: Configure Form Actions
Form actions tell UiChemy what to do when the form is submitted. Select the Composer widget and open its Form panel, "On submit" section, actions are configured per form there, not site-wide, and not in the HTML, keeping sensitive details (email addresses, webhook URLs) out of your page source.
| Action | On-screen label | What it does |
|---|---|---|
save_db | Save to database | Stores the submission in the WordPress database, visible in the Form Submissions dashboard. Toggle on/off. |
email | Email a notification | Sends an email notification with all submitted fields to the address you configure. Toggle on/off, with an optional CC recipient under "More options." |
webhook | Send to a webhook | POSTs the submitted data as JSON to a URL you specify once you toggle it on, for Zapier, Make, CRM integrations, etc. |
You can enable any combination of these for each form key. A contact form might use save_db + email. A CRM lead form might use save_db + webhook.
The same panel also has an "After submit" setting: show an inline success message, or redirect to a URL.
Step 4: Style the Form
Style the form in the CSS panel of the code editor. The CSS is auto-scoped to this widget, so your form styles won't affect other forms or elements on the page.
form {
display: flex;
flex-direction: column;
gap: 1.25rem;
max-width: 480px;
}
.field {
display: flex;
flex-direction: column;
gap: 0.375rem;
}
label {
font-size: 0.875rem;
font-weight: 500;
}
input,
textarea,
select {
padding: 0.625rem 0.75rem;
border: 1px solid #d1d5db;
border-radius: 6px;
font-size: 1rem;
width: 100%;
}
button[type="submit"] {
padding: 0.75rem 1.5rem;
background: #1a1a1a;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 1rem;
}
Step 5: Test the Form
- Click Update in Elementor to publish the page.
- Open the page on the front end (not in the editor).
- Fill in the form and submit it.
- Go to UiChemy → Form Submissions to confirm the submission was captured.
- Check your email if you configured the
emailaction.
Form submissions processed through Elementor's editor preview aren't captured. Submit the form from the published page (or a preview URL) to test properly.
Handling Success and Error States
By default, UiChemy shows its own success or error message inline in the form (a .uich-form-message element that toggles between a success and error state) and, on success, applies whichever "After submit" behavior you set in the Form panel (inline message or redirect).
There's no front-end JavaScript event to hook into for custom success/error handling. If you need server-side custom logic, for example, sending data somewhere beyond the built-in actions, use the uich_form_submitted action hook (fires after a submission is processed) or the uich_form_response filter (lets you adjust the response) in a custom code snippet, not from the widget's JS panel.
Limitations
- Submissions made from Elementor's editor preview aren't captured, only test from the published page.
- Fields without a
nameattribute aren't captured at all. - There's no front-end JavaScript event for custom success/error handling, use the
uich_form_submittedaction hook oruich_form_responsefilter instead.