← Back to Documentation

Hooks Reference

PHP Filters

Row Configuration

gfr_max_rows

Override the maximum number of rows for a group.

add_filter( 'gfr_max_rows', function( int $default, $field, array $form ): int {
    if ( $field->gfr_group_name === 'passengers' ) {
        return 10;
    }
    return $default;
}, 10, 3 );

Default: 3 | Returns: int


gfr_min_rows

Override the minimum number of rows for a group.

add_filter( 'gfr_min_rows', function( int $default, $field, array $form ): int {
    return 2;
}, 10, 3 );

Default: 1 | Returns: int


gfr_add_text

Override the Add button label.

add_filter( 'gfr_add_text', function( string $default, $field, array $form ): string {
    return 'Add Passenger';
}, 10, 3 );

Default: 'Add' | Returns: string


gfr_remove_text

Override the Remove button label.

add_filter( 'gfr_remove_text', function( string $default, $field, array $form ): string {
    return 'Delete';
}, 10, 3 );

Default: 'Remove' | Returns: string


gfr_copy_text

Override the Copy button label.

add_filter( 'gfr_copy_text', function( string $default, $field, array $form ): string {
    return 'Duplicate';
}, 10, 3 );

Default: 'Copy' | Returns: string


Rendering

gfr_group_open_attrs

Inject HTML attributes onto the .gfr-repeat-group wrapper div.

add_filter( 'gfr_group_open_attrs', function( string $attrs, $field, array $form ): string {
    return $attrs . ' data-custom="value"';
}, 10, 3 );

Default: '' | Returns: string (attribute string)


gfr_group_inner_start

Inject HTML at the start of the group wrapper (inside row 0).

add_filter( 'gfr_group_inner_start', function( string $html, $field, array $form ): string {
    return $html . '<div class="my-custom-header">Custom content</div>';
}, 10, 3 );

gfr_sticky_row_inner_start

Inject HTML at the start of each server-rendered sticky row.

add_filter( 'gfr_sticky_row_inner_start', function( string $html, string $group_name, array $form ): string {
    return $html . '<div class="sticky-row-badge">Re-submitted</div>';
}, 10, 3 );

gfr_is_field_hidden

Override field visibility for repeater rows during sticky row rendering and validation.

add_filter( 'gfr_is_field_hidden', function( bool $hidden, $field, array $form, array $row_values ): bool {
    // Always show field 5 regardless of conditional logic
    if ( (int) $field->id === 5 ) {
        return false;
    }
    return $hidden;
}, 10, 4 );

Parameters:


File Uploads

gfr_upload_file

Process file uploads for repeater row fields. Used by the File Upload handler internally.

add_filter( 'gfr_upload_file', function( $result, int $form_id, $field, ?array $file_entry, string $post_key ) {
    // Custom file processing
    return $url; // Return URL, rejection sentinel, or null
}, 10, 5 );

Returns: URL string, __gfr_file_rejected__|{filename}, or null


PHP Actions

Row Rendering

gfr_row_header

Output content inside the .gfr-row-header section of each row.

add_action( 'gfr_row_header', function( string $group_name, array $form, int $row_index ): void {
    echo '<span class="my-row-badge">Row ' . ( $row_index + 1 ) . '</span>';
}, 10, 3 );

gfr_row_start

Output content at the start of each row (after the header).

add_action( 'gfr_row_start', function( string $group_name, array $form, int $row_index ): void {
    echo '<div class="row-intro">Fill in the details below</div>';
}, 10, 3 );

gfr_row_actions

Output buttons inside the .gfr-actions wrapper (alongside Remove/Copy buttons).

add_action( 'gfr_row_actions', function( string $group_name, array $form, int $row_index ): void {
    echo '<button type="button" class="my-custom-action">Custom</button>';
}, 10, 3 );

Editor Settings

These actions inject <li> elements into the Repeater settings tab in the form editor:

ActionModulePurpose
gfr_repeater_start_row_limit_settingsRow LimitsMin/max rows inputs
gfr_repeater_start_button_label_settingsButton LabelsAdd/Remove text inputs
gfr_repeater_start_copy_row_settingsCopy RowEnable + label
gfr_repeater_start_collapse_rows_settingsCollapse RowsEnable checkbox
gfr_repeater_start_drag_reorder_settingsDrag ReorderEnable checkbox
gfr_repeater_start_conditional_row_limits_settingsConditional Row LimitsSource field dropdown
gfr_repeater_start_extra_settingsAnyGeneric hook for custom settings

JavaScript Extension Hooks

Register extensions by pushing an object into window.GFRepeater.extensions:

window.GFRepeater.extensions.push({
    onRowAdded: function( $form, config, $newRow ) {
        console.log( 'Row added to', config.groupName );
    },
    onRowsUpdated: function( $form, config ) {
        console.log( 'Row count changed for', config.groupName );
    },
    onFieldChanged: function( $form, config, $row ) {
        console.log( 'Field changed in row', $row.data('row-index') );
    },
    onCopyRow: function( $form, config, $sourceRow ) {
        console.log( 'Copy requested for row', $sourceRow.data('row-index') );
    },
    onStickyRowsReady: function() {
        console.log( 'Sticky rows ready for CL evaluation' );
    }
});

Hook Reference

HookParametersFires When
onRowAdded$form, config, $newRowNew row inserted (add, copy, min-rows init)
onRowsUpdated$form, configAny row count change (add, remove, copy, drag)
onFieldChanged$form, config, $rowInput/select/textarea changes in a row
onCopyRow$form, config, $sourceRowCopy button clicked
onStickyRowsReady(none)Page load complete, GF CL script available

Config Object

The config object passed to hooks contains:

{
    formId: 1,
    groupName: 'passengers',
    maxRows: 5,
    minRows: 1,
    addButtonText: 'Add',
    removeButtonText: 'Remove',
    copyButtonText: 'Copy' // or null if not enabled
}

JavaScript Public API

// Add buttons to a row
window.GFRepeater.addRemoveButton( $row, config );
window.GFRepeater.addCopyButton( $row, config );

// Update button visibility based on row count
window.GFRepeater.updateRemoveButtons( $form, config );
window.GFRepeater.updateCopyButtons( $form, config );

Global JavaScript Variables

VariableTypeSet ByPurpose
window.GFRepeaterObjectCore JSPlugin namespace + API
window.gfrInputMasksObjectPHPInput mask patterns per field
window.gfrRepeatCLDataObjectPHPConditional logic rules for repeater fields
window.gfrEditorConfigObjectPHPEditor config (isPro flag)
window.gfrDebugConfigObjectPHPDebug AJAX URL (when enabled)
window.gfrRowDeleteFileFunctionFile Upload JSDelete file from async uploads