Advanced Custom Fields Validation

Is there way to use custom validation on an advanced custom field? For example, I might not want a textfield to have a value that starts with certain prefix, or I might want a number field to have a value greater than ‘x’. I might also want to run a regex against a value and return an error if it doesn’t match.

Related posts

Leave a Reply

4 comments

  1. I did it by plugging into acf/pre_save_post. Using that, you can test the $_POST data. And if you don’t like something, you can change $post_id to “error” when you return it. This will keep the form from processing since the post_id is not correct. You can also plug in to acf/save_post to make sure to unset the “return” or update messages from the form.

    It is all a little complicated, but I will try to give a simplified example of what I used.

    $submitted_fields = '';
    $validation_errors = '';
    
    add_filter( 'acf/pre_save_post', 'custom_validation' );
    function custom_validation( $post_id )
    {
        // Load the fields from $_POST
        if ( empty($_POST['fields']) || ! is_array($_POST['fields']) )
        {
            $validation_errors['empty'] = "One or more fields below are required";
        }
        else
        {
            foreach( $_POST['fields'] as $k => $v )
            {
                // get field
                $f = apply_filters('acf/load_field', false, $k );
                $f['value'] = $v;
                $submitted_fields[$f['name']] = $f;
            }
        }
    
        // Test stuff...
        if ( empty($submitted_fields['foo']) || 'bar' != $submitted_fields['foo'] )
        {
            $validation_errors['foo'] = "Foo did not equal bar";
        }
    
        // If there are errors, output them, keep the form from processing, and remove any redirect
        if ( $validation_errors )
        {
            // Output the messges area on the form
            add_filter( 'acf/get_post_id', array(__CLASS__, 'add_error') );
            // Turn the post_id into an error
            $post_id = 'error';
            // Add submitted values to fields
            add_action('acf/create_fields', array(__CLASS__, 'acf_create_fields'), 10, 2 );
        }
        else
        {
            // Do something... do nothing... ?
        }
    
        // return the new ID
        return $post_id;
    }
    
        function acf_create_fields( $fields, $post_id )
        {
            foreach ( $fields as &$field )
            {
                if ( array_key_exists($field['name'], $submitted_fields) )
                    $field['value'] = $submitted_fields[$field['name']];
            }
            return $fields;
        }
    
        function add_error()
        {
            echo '<div id="message" class="error">';
            foreach ( $validation_errors as $key => $error )
            {
                echo '<p class="' . $key . '">' . $error . '</p>';
            }
            echo '</div>';
        }
    
    add_action('acf/save_post', 'custom_handle_error', 1);
    function custom_handle_error( $post_id )
    {
        if ( 'error' == $post_id )
        {
            unset($_POST['return']);
        }
    }
    

    This doesn’t allow to highlight fields that returned an error, but you could actually do it pretty easily with javascript using the classes from the errors in #message div.

  2. you can use this code

    add_filter('acf/validate_value/name=validate_this_image', 'my_acf_validate_value', 10, 4);
    
    function my_acf_validate_value( $valid, $value, $field, $input ){
    
    // bail early if value is already invalid
    if( !$valid ) {
    
        return $valid;
    
    }
    
    
    // load image data
    $data = wp_get_attachment_image_src( $value, 'full' );
    $width = $data[1];
    $height = $data[2];
    
    if( $width < 960 ) {
    
        $valid = 'Image must be at least 960px wide';
    
    }
    
    
    // return
    return $valid;
    
    
    }
    

    result
    enter image description here
    Documentation