How to implement advanced validation logic beyond the built-in rules.
Regex-Based Validation
The built-in regex property on text fields supports custom patterns:
php
$field = [
'id' => 'field_tax_id',
'type' => 'text',
'label' => 'Tax ID',
'required' => true,
'regex' => '/^d{2}-d{7}$/',
'regex_message' => 'Tax ID must be in format XX-XXXXXXX',
];Cross-Field Validation
Validate relationships between multiple fields using formforge_before_submit:
php
add_action( 'formforge_before_submit', function( $form_id, $data, $form ) {
// Ensure end date is after start date
$start = $data['field_start_date']['value'] ?? '';
$end = $data['field_end_date']['value'] ?? '';
if ( $start && $end && strtotime( $end ) <= strtotime( $start ) ) {
wp_send_json_error( [
'message' => 'End date must be after start date.',
'errors' => [ 'field_end_date' => 'Please select a later date.' ],
] );
}
}, 10, 3 );External API Validation
Validate against external services:
php
add_action( 'formforge_before_submit', function( $form_id, $data, $form ) {
if ( $form_id !== 8 ) return;
$vat_number = $data['field_vat']['value'] ?? '';
if ( empty( $vat_number ) ) return;
$response = wp_remote_get(
'https://vat-api.example.com/validate?vat=' . urlencode( $vat_number )
);
$body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $body['valid'] ) ) {
wp_send_json_error( [
'message' => 'Invalid VAT number.',
'errors' => [ 'field_vat' => 'This VAT number could not be verified.' ],
] );
}
}, 10, 3 );Conditional Required Fields
Make fields required based on other field values:
php
add_action( 'formforge_before_submit', function( $form_id, $data, $form ) {
$type = $data['field_customer_type']['value'] ?? '';
$company = $data['field_company_name']['value'] ?? '';
if ( $type === 'business' && empty( $company ) ) {
wp_send_json_error( [
'message' => 'Company name is required for business customers.',
'errors' => [ 'field_company_name' => 'This field is required.' ],
] );
}
}, 10, 3 );—