ChargeForms
Developers

Custom Field Types

Register a new field type across the builder, renderer, and submission handler.

Three places a field type lives

A field type isn't real until it's implemented in all three of these layers — adding it to just one gives you a field that looks right but doesn't actually work:

  1. assets/src/builder/fields.js — the field-type registry. This makes the type draggable in the builder and defines its default config, but doesn't render or validate anything by itself.
  2. public/class-shortcode.php — the front-end renderer. Add a case to the field-type switch that outputs the actual HTML markup visitors fill in.
  3. public/class-submission-handler.php — validation and storage. Add handling for how the submitted value is validated, sanitized, and stored in the entry's response JSON.

A minimal example

A new "Star Count" field type (a plain number input styled as a star count) would need:

// fields.js
export function createField(type) {
  if (type === 'star_count') {
    return { type, label: 'Rating', maxStars: 5 };
  }
  // ...
}
// class-shortcode.php
case 'star_count':
    printf(
        '<input type="number" name="%s" min="0" max="%d">',
        esc_attr( $name ),
        (int) $field['maxStars']
    );
    break;
// class-submission-handler.php
// No special-casing needed here if the field is a plain number input —
// it falls through to the generic sanitize_text_field() + required-check
// path already used for simple fields.

Live preview in the builder

assets/src/builder/components/Canvas.js has its own switch statement for rendering a field's live preview while editing — this is separate from the front-end renderer in class-shortcode.php and needs its own case for the field to show correctly on the canvas rather than falling back to a generic placeholder.