Richard Parnaby-King

Gravity Forms – Moving the validation errors message ABOVE the pagination controls

Wow, there’s a title!

Gravity Forms is a WordPress plugin that allows the user to create and manage a collection of forms to be published on posts and pages. An example of this is a simple Contact Us form. One of the features of Gravity Forms is the ability to paginate the form. That’s right! If you have 50 form elements, instead of having them all on one page, you can break them up to five pages of 10 form fields a page.

Another feature is the built-in validation! Gravity Forms will validate user data against the form element types to ensure that the data you end up with is the data you want. Any failed validation messages will be collated and displayed between the pagination and form! Fantastic!

Unless the design is for the pagination to be down the left sidebar. At which point the validation message sits above the form, but next to the top of the pagination. This triggers my personal OCD – the validation messages should be shown above the whole caboodle!

My solution is to hook into the Gravity Form events so that I can grab the validation message and store it; then, just before the form is shown to the user, insert the message ABOVE the pagination controls!

All this code goes into the theme’s functions.php file.

    //Listen to Gravity Form hooks:
//get the validation message
add_filter( 'gform_validation_message', 'gform_validation_message', 10, 2 );
//get the form just before it is displayed to the user
add_filter( 'gform_get_form_filter', 'gform_get_form_filter', 10, 2 );
 
//This is where we store the validation message between events
$_message = null;
 
/**
 * Store validation message and return empty string.
 * @param string $message
 * @param GravityForm::FormObject $form
 * @return string
 */
function gform_validation_message($message, $form)  use ($_message) {
    $_message = $message;
 
    //we return an empty string because we don't want the validation message to show in the form any more.
    return '';
}
 
/**
 * Move notification error above pagination
 * @param string $form_string
 * @param GravityForm::FormObject $form
 * @return string
 */
function gform_get_form_filter($form_string, $form )  use ($_message){
    //If there are no validation messages, just show the form
    if(is_null($_message)) {
        return $form_string;
    }
 
    //Load the generated form into a DomDocument so we can insert the validation messages above the pagination steps.
    $doc = new \DOMDocument();
    $doc->loadHTML($form_string);
    $doc->preserveWhiteSpace = false;
 
    //Here is our pagination control
    $el = $doc->getElementById('gf_page_steps_' . $form['id']);
 
    //Create a new DomDocument holding our generated message
    $tmpDoc = new \DOMDocument();
    $tmpDoc->loadHTML($_message);
    foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) {
        $node = $el->ownerDocument->importNode($node, true);
        //insert our validation messages before the pagination control
        $el->parentNode->insertBefore($node, $el);
    }
 
    $doc->formatOutput = true;
 
    //return our modified HTML :)
    return $doc->saveHTML();
}

Conclusion

Oh yes, much better. My OCD has been satisfied: