FormManager Examples

Complete examples of declarative form handling - No JavaScript required!

Example 1: Contact Form (Declarative)

Basic contact form with validation and success message - No JavaScript needed

HTML Code:

<!-- Contact Form - Zero JavaScript! -->
<form
  data-form="contact"
  data-action="api/contact.php"
  data-method="POST"
  data-ajax-submit="true"
  data-reset-after-submit="true"
  data-success-message="Thank you!"
  data-show-success-in-notification="true"
  data-prevent-double-submit="true">

  <fieldset>
    <div>
      <label for="contact_name">Name</label>
      <span class="form-control icon-customer">
        <input type="text" id="contact_name" name="name"
          required minlength="2" maxlength="100"
          data-error-required="Please enter your name">
      </span>
    </div>

    <div>
      <label for="contact_email">Email</label>
      <span class="form-control icon-email">
        <input type="email" id="contact_email" name="email"
          required
          data-error-required="Please enter your email"
          data-error-email="Invalid email address">
      </span>
    </div>

    <div>
      <label for="contact_message">Message</label>
      <span class="form-control icon-comment">
        <textarea id="contact_message" name="message"
          rows="4" required minlength="10"
          data-error-required="Please enter your message"></textarea>
      </span>
    </div>
  </fieldset>

  <fieldset class="form-actions submit right">
    <button type="submit" class="btn btn-primary icon-send">Send</button>
  </fieldset>
</form>

Example 2: Login Form (Zero JavaScript)

Complete login form using exact patterns from dashboard/crm examples - No JavaScript required!

Login Form Pattern (No JavaScript!):

<!-- Complete login form - Zero JavaScript required! -->
<form
  data-form="login"
  class="auth-form"
  novalidate
  action="api/v1/auth/login"
  method="post"
  data-ajax-submit="true"
  data-redirect="/"
  data-auto-fill-intended-url="true">

  <!-- Welcome message -->
  <p class="login-message">Welcome back!</p>

  <fieldset>
    <div>
      <label for="login_username">Username/Email</label>
      <span class="form-control icon-email">
        <!-- data-persist: Remember username in localStorage -->
        <input type="text" id="login_username" name="username"
          autocomplete="username" autofocus
          data-persist="local"
          data-persist-key="login_username"
          data-persist-ttl-days="30">
      </span>
    </div>

    <div>
      <label for="login_password">Password</label>
      <span class="form-control icon-password">
        <input type="password" id="login_password" name="password"
          autocomplete="current-password">
      </span>
    </div>

    <div>
      <div class="input-groups">
        <div class="width50">
          <!-- switch: Toggle style, data-persist: Remember state -->
          <input type="checkbox" id="remember" class="switch"
            name="remember" value="1"
            data-persist="local"
            data-persist-key="login_remember">
          <label for="remember">Remember Me</label>
        </div>
        <div class="width50 right">
          <a href="forgot">Forgot Password</a>
        </div>
      </div>
    </div>
  </fieldset>

  <fieldset class="center">
    <button type="submit" class="btn btn-primary fullwidth large icon-signin">Log in</button>
  </fieldset>
</form>

Login Form Attributes

Attribute Description
data-form="login" Identifies form for FormManager (required)
data-ajax-submit="true" Submit via AJAX instead of page reload
data-redirect="/" Where to redirect on success
data-auto-fill-intended-url="true" Auto-fill hidden field with URL user tried to access
data-persist="local" Persist field value in localStorage
data-persist-key="..." Custom key for localStorage
data-persist-ttl-days="30" Expiry time in days
class="login-message" Styled welcome message
class="switch" Toggle switch style for checkbox
novalidate Disable browser validation, use FormManager instead

Example 3: Validation Types

Demonstrating all built-in validation types with custom error messages

Required & Length Validation
Type Validation
Number Validation
Password Match Validation
Password must be at least 8 characters with uppercase and lowercase letters.

Validation Attributes:

<!-- Required -->
<!-- Required field -->
<div>
  <label for="name">Name</label>
  <span class="form-control icon-customer">
    <input id="name" name="name" required
      data-error-required="This field is required">
  </span>
</div>

<!-- Length validation -->
<div>
  <label for="username">Username</label>
  <span class="form-control">
    <input id="username" name="username"
      minlength="3" maxlength="20"
      data-error-minlength="Minimum 3 characters"
      data-error-maxlength="Maximum 20 characters">
  </span>
</div>

<!-- Email validation -->
<div>
  <label for="email">Email</label>
  <span class="form-control icon-email">
    <input type="email" id="email" name="email"
      data-error-email="Invalid email">
  </span>
</div>

<!-- Number range -->
<div>
  <label for="age">Age</label>
  <span class="form-control">
    <input type="number" id="age" name="age"
      min="18" max="100"
      data-error-min="Must be at least 18"
      data-error-max="Must be no more than 100">
  </span>
</div>

<!-- Password with confirm -->
<div class="input-groups">
  <div class="width50">
    <label for="password">Password</label>
    <span class="form-control icon-password">
      <input type="password" id="password" name="password"
        data-element="password"
        data-password-strength="bar">
    </span>
  </div>
  <div class="width50">
    <label for="confirm">Confirm</label>
    <span class="form-control icon-password">
      <input type="password" id="confirm" name="confirm"
        data-target-password="password"
        data-error-match="Passwords do not match">
    </span>
  </div>
</div>

Example 4: Confirmation Dialog

Form that asks for confirmation before submitting

Warning: This action will permanently delete your account and all associated data.

Confirmation Attribute:

<form
  data-form="delete-account"
  data-method="DELETE"
  data-ajax-submit="true"
  data-confirm="Are you sure? This cannot be undone."
  data-success-message="Account deleted"
  data-redirect="/">

  <fieldset>
    <div class="alert alert-warning">
      <span class="icon-warning"></span>
      <span>Warning: This action is permanent.</span>
    </div>

    <div>
      <label for="delete_confirm">Type "DELETE" to confirm</label>
      <span class="form-control">
        <input type="text" id="delete_confirm" name="confirmation"
          required pattern="^DELETE$"
          data-error-required="Please type DELETE"
          data-error-pattern="Please type exactly: DELETE">
      </span>
    </div>
  </fieldset>

  <fieldset class="submit right">
    <button type="button" class="btn" onclick="history.back()">Cancel</button>
    <button type="submit" class="btn btn-danger icon-trash">Delete</button>
  </fieldset>
</form>

Example 5: URL Parameters Loading

Load form values from URL query parameters (e.g., password reset links)

Try adding ?token=abc123&uid=42 to the URL to see auto-fill in action!

URL Parameters Attributes:

<!-- URL: /reset-password?token=abc123&uid=42 -->
<form
  data-form="reset-password"
  data-ajax-submit="true"
  data-load-url-params="true"
  data-url-params-required="true"
  data-url-params-required-fields="token,uid">

  <!-- Hidden fields auto-filled from URL params -->
  <input type="hidden" name="token" data-attr="value:token">
  <input type="hidden" name="uid" data-attr="value:uid">

  <fieldset>
    <div class="input-groups">
      <div class="width50">
        <label for="reset_password">New Password</label>
        <span class="form-control icon-password">
          <input type="password" id="reset_password" name="password"
            required minlength="8"
            data-element="password"
            data-password-strength="bar">
        </span>
      </div>
      <div class="width50">
        <label for="reset_confirm">Confirm Password</label>
        <span class="form-control icon-password">
          <input type="password" id="reset_confirm" name="confirm"
            required
            data-target-password="reset_password"
            data-error-match="Passwords do not match">
        </span>
      </div>
    </div>
  </fieldset>

  <fieldset class="submit right">
    <button type="submit" class="btn btn-primary icon-save">Reset Password</button>
  </fieldset>
</form>

Example 6: Edit Profile (API Integration)

Advanced form with API data loading and file upload

This example requires a backend API endpoint. See documentation for API response format.
Supported: jpg, jpeg, png, webp (max 5MB)
Password must be at least 8 characters long and contain at least one uppercase letter and one lowercase letter.

API Integration Attributes:

<form
  data-form="editprofile"
  data-action="api/v1/form/update"
  data-load-api="api/v1/form"
  data-ajax-submit="true">

  <!-- Fields with data-attr bind to API response -->
  <input name="name" data-attr="value:name">
  <input name="email" data-attr="value:email">

  <!-- Select with dynamic options -->
  <select name="gender" data-options-key="genders">
    <option value="">Select...</option>
  </select>

  <!-- File upload with preview -->
  <input type="file" name="avatar"
    data-preview="true"
    data-allow-remove-existing="true">

  <!-- Hidden ID field -->
  <input type="hidden" name="id" data-attr="value:id">
</form>

Recommended HTML Structure

Follow these HTML patterns for proper form styling and JavaScript integration

Basic Field Structure
We'll never share your email.
Side-by-Side Fields (input-groups)
Special Elements (data-element)
Password must be at least 8 characters.

Structure Patterns:

<!-- ===== FORM CONTAINER ===== -->
<form data-form="formId" data-ajax-submit="true">

  <!-- ===== FIELDSET: Groups related fields ===== -->
  <fieldset>
    <legend>Section Title</legend>

    <!-- SINGLE FIELD PATTERN -->
    <div>
      <label for="fieldId">Label</label>
      <span class="form-control icon-name">
        <input type="text" id="fieldId" name="fieldName">
      </span>
      <div class="comment">Help text</div>
    </div>

  </fieldset>

  <!-- ===== SIDE-BY-SIDE FIELDS ===== -->
  <fieldset>
    <div class="input-groups">
      <div class="width50">  <!-- 50% width -->
        <label>First Field</label>
        <span class="form-control">
          <input type="text" name="field1">
        </span>
      </div>
      <div class="width50">  <!-- 50% width -->
        <label>Second Field</label>
        <span class="form-control">
          <input type="text" name="field2">
        </span>
      </div>
    </div>
  </fieldset>

  <!-- ===== SUBMIT ACTIONS ===== -->
  <fieldset class="submit right">
    <button type="reset" class="btn">Reset</button>
    <button type="submit" class="btn btn-primary">Save</button>
  </fieldset>

</form>

HTML Structure Reference

Pattern Description Usage
<fieldset> Groups related form fields Wrap sections of related inputs
<legend> Section title inside fieldset Label for field groups
fieldset.submit Submit button container Wrap submit/reset buttons
.right Align content to right Add to .submit for right alignment
span.form-control Input wrapper (REQUIRED) Wrap every input/select/textarea
.icon-{name} Input icon Add to form-control for icons
.input-groups Side-by-side container Flexbox container for columns
.width50 50% width column Use inside input-groups
.width33 33% width column For 3-column layouts
.comment Help/hint text below field Place after form-control span
id="result_{fieldId}" Error message container FormError displays errors here

data-element Attribute

The data-element attribute enables JavaScript-enhanced functionality for specific input types:

Element Type Additional Attributes Description
data-element="password" data-password-strength="bar"
data-password-criteria-list="true"
data-target-password="fieldId"
Password with strength meter and/or confirmation matching
data-element="file" data-preview="true"
data-allow-remove-existing="true"
data-file-reference="url"
File upload with preview and remove functionality
data-element="autocomplete" data-options-key="keyName"
data-api="endpoint"
Autocomplete input with API or predefined options

Quick Reference: Form Data Attributes

Attribute Description Example
data-form Form ID (required) "contact"
data-ajax-submit Submit via AJAX "true"
data-confirm Confirmation dialog "Are you sure?"
data-reset-after-submit Reset form after success "true"
data-success-message Success notification "Saved!"
data-redirect Redirect after success "/dashboard"
data-load-url-params Load values from URL "true"
data-prevent-double-submit Prevent duplicate submissions "true"
Input Attribute Description Example
data-error-required Custom required message "Please fill this"
data-error-email Custom email error "Invalid email"
data-error-minlength Minimum length error "Too short"
data-error-pattern Pattern mismatch error "Invalid format"
data-target-password ID of password to match "password"
data-attr Bind to API data "value:fieldname"