19. Creating Custom Field Types | Form Forge - Build Forms with AI in Seconds
Download Log in

19. Creating Custom Field Types

Developer Guide

A complete guide to building custom field types from scratch.

Step 1: Register the Type

php
add_filter( 'formforge_field_types', function( $types ) {
    $types['signature'] = [
        'label'    => 'Signature Pad',
        'icon'     => 'edit',
        'category' => 'advanced',
    ];
    return $types;
} );

Step 2: Render the Field

php
add_filter( 'formforge_field_render', function( $html, $field ) {
    if ( ( $field['type'] ?? '' ) !== 'signature' ) {
        return $html;
    }

    $name = 'formforge_field_' . ( $field['id'] ?? '' );
    $label = esc_html( $field['label'] ?? 'Signature' );
    $req_mark = ! empty( $field['required'] )
        ? ' <span class="formforge-required">*</span>' : '';
    $required = ! empty( $field['required'] ) ? 'required' : '';

    $html  = '<div class="formforge-field formforge-field--signature">';
    $html .= '<label class="formforge-label">' . $label . $req_mark . '</label>';
    $html .= '<canvas id="' . esc_attr( $name ) . '_canvas" width="400" height="150"'
           . ' style="border:1.5px solid #e2e8f0;border-radius:8px;cursor:crosshair;'
           . 'background:#fafafa;"></canvas>';
    $html .= '<input type="hidden" name="' . esc_attr( $name ) . '"'
           . ' id="' . esc_attr( $name ) . '" ' . $required . '>';
    $html .= '<button type="button" class="ff-clear-signature"'
           . ' onclick="clearSignature('' . esc_js( $name ) . '')">'
           . 'Clear</button>';
    $html .= '</div>';

    return $html;
}, 10, 2 );

Step 3: Handle Sanitization

php
add_filter( 'formforge_sanitize_field', function( $value, $field ) {
    if ( ( $field['type'] ?? '' ) === 'signature' ) {
        if ( strpos( $value, 'data:image/png;base64,' ) === 0 ) {
            if ( strlen( $value ) > 700000 ) {
                return '';
            }
            return $value;
        }
        return '';
    }
    return $value;
}, 10, 2 );

Step 4: Enqueue Frontend JavaScript

php
add_action( 'wp_enqueue_scripts', function() {
    if ( ! class_exists( 'FORMFORGE_Core' ) ) return;

    wp_enqueue_script(
        'ff-signature-field',
        get_template_directory_uri() . '/js/signature-field.js',
        [ 'formforge-frontend' ],
        '1.0.0',
        true
    );
} );
javascript
// js/signature-field.js
document.addEventListener( 'DOMContentLoaded', function() {
    document.querySelectorAll( '.formforge-field--signature canvas' ).forEach( function( canvas ) {
        var ctx = canvas.getContext( '2d' );
        var drawing = false;
        var hiddenInput = canvas.parentElement.querySelector( 'input[type="hidden"]' );

        canvas.addEventListener( 'mousedown', function() { drawing = true; ctx.beginPath(); } );
        canvas.addEventListener( 'mousemove', function( e ) {
            if ( ! drawing ) return;
            var rect = canvas.getBoundingClientRect();
            ctx.lineTo( e.clientX - rect.left, e.clientY - rect.top );
            ctx.stroke();
        } );
        canvas.addEventListener( 'mouseup', function() {
            drawing = false;
            hiddenInput.value = canvas.toDataURL( 'image/png' );
        } );
    } );
} );

function clearSignature( name ) {
    var canvas = document.getElementById( name + '_canvas' );
    var ctx = canvas.getContext( '2d' );
    ctx.clearRect( 0, 0, canvas.width, canvas.height );
    document.getElementById( name ).value = '';
}

Forge AI Assistant Online

Hi! I'm the Form Forge AI assistant. Ask me anything about the plugin — setup, features, troubleshooting, or development.

Just now
Powered by Forge AI · Browse docs