Skip Navigation

[Closed] Validation Messages Not Appearing in Form Messages Field

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 7 replies, has 2 voices.

Last updated by Christopher Amirian 1 year, 2 months ago.

Assisted by: Christopher Amirian.

Author
Posts
#2542771

Tell us what you are trying to do?
Use custom validation to display a variety of error messages across numerous forms.

I've been having an issue for a while now regarding cred validations not appearing or not working via AJAX etc. I assumed it might have been related to another weird issue I had recently as detailed in this thread:

https://toolset.com/forums/topic/cred-conditional-is-showing-undefined-index-error-for-its-autogenerated-index/

But it turns out it was unrelated, although this issue is mentioned in that thread so I'm including it for context and completeness.

Basically, all of my custom validations have stopped rendering. Even if I take a really simplified one such as this (note: this is truncated code, but has been tested in this exact form):

function general_validation( $error_fields, $form_data ){
  //Load list of field data comprised of field values and errors
  list( $fields, $errors ) = $error_fields;
  //uncomment this if you want to print the field values
  //print_r($fields);

  //** Validation for New Term form OR Edit Term form OR Edit Term Dates form **//
  if( $form_data['id'] == 446 || $form_data['id'] == 732 || $form_data['id'] == 1132 )
  {
    /* Validation - Check the End Date comes after the Start Date */
    if( $fields['wpcf-term-start-date']['value']['datepicker'] > $fields['wpcf-term-end-date']['value']['datepicker'] )
    {
      //End Date error message
      $errors['term-end-date'] = 'End Date must be greater than the Start Date';
    }
  }
 
  //print_r($errors);
  //die;

  //Return array of results
  return array( $fields, $errors );
}
add_filter( 'cred_form_validate', 'general_validation', 10, 2 );

and use it on a simple form such as this one:

[credform]
[cred_field field='form_messages' class='alert alert-warning']
<div class="form-group">
  <div class="row">
    <div class="col-md-6">
      <label for="%%FORM_ID%%_school-term">[cred_i18n name='school-term-label']School Term[/cred_i18n]</label>
      [cred_field field='school-term' force_type='field' class='form-control' output='bootstrap']
    </div>
    <div class="col-md-6">
      <label for="%%FORM_ID%%_term-year">[cred_i18n name='term-year-label']Term Year[/cred_i18n]</label>
      <!--[cred_field field='term-year' force_type='field' class='form-control' output='bootstrap']-->
      [cred_show_group if="( $(term-year) gte '[possible_term_years current="true"]' )" mode="none"]
        [cred_generic_field type='select' field='term-year' class='generic-select-padding']
        {
        "required":1,
        "options":[ [possible_term_years] ],
      	"default":[types field='term-year' output='raw'][/types]
        }
        [/cred_generic_field]
      [/cred_show_group]
      [cred_show_group if="( $(term-year) lt '[possible_term_years current="true"]' )" mode="none"]
      	[cred_field field="term-year" force_type="field" class="form-control" output="bootstrap" readonly="true"]
      [/cred_show_group]
    </div>
  </div>
</div>
<div class="form-group">
  <div class="row center-calendars">
    <div class="col-md-6">
      <label for="%%FORM_ID%%_term-start-date">[cred_i18n name='term-start-date-label']Start Date[/cred_i18n]</label>
      [cred_field field='term-start-date' force_type='field' class='form-control' output='bootstrap']
    </div>
    <div class="col-md-6">
      <label for="%%FORM_ID%%_term-end-date">[cred_i18n name='term-end-date-label']End Date[/cred_i18n]</label>
      [cred_field field='term-end-date' force_type='field' class='form-control' output='bootstrap']
    </div>
  </div>
</div>
<div class="form-group token-end-layout">
  <div class="row center-calendars">
    <div class="col-md-6">
      <label for="%%FORM_ID%%_term-token-end-date">[cred_i18n name='term-token-end-date-label']Token End Date (Optional)[/cred_i18n]</label>
      [cred_field field='term-token-end-date' force_type='field' class='form-control' output='bootstrap']
    </div>
    <div class="col-md-6">
      Updating the Token End Date will affect <strong>all tokens</strong> associated with this term.
    </div>
  </div>
</div>

<div class="row">
  <div class="col-md-6">
    [cred_field field='form_submit' output='bootstrap' value='Save' class='btn btn-primary btn-lg btn-block']
  </div>
  <div class="col-md-6">
    <button type="button" class="btn btn-secondary btn-lg btn-block" data-dismiss="modal">Cancel</button>
  </div>
</div>
[/credform]

The error messages will not appear on the front end. They used to. I used to be able to see this one both via AJAX and if I reopened the form modal if it was not submitted via AJAX. But not nothing appears at all and the validation does not halt execution.

If I uncomment the print_r($errors) and use die to halt a non-AJAX submission, the error code is there and being returned to the validation hook as it always has been. So something is interfering with the AJAX or the hook after this point, but for the life of me, I can't figure out what.

Also, the forms will not submit via AJAX is there is a print_r function active in the code. But the presence of this does not affect the validation message, which doesn't work regardless.

Apart from the duplicator plugin for the other thread, I've not installed any new plugins, and I've not added any code that should affect the AJAX as I don't use it outside of the cred submissions.

I've checked the admin-ajax in XHR under the Network console tab, and it shows the form fields being submitted and nothing about the error messages at all, and I know you can see the errors in there when they are sent, so I'm led to believe that the hook is not sending the error messages to the AJAX properly.

#2543673

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

We first need to see if this is happening on your installation only or can be replicated on a clean installation.

After that we will be able to know which course of action to take.

I created a clean installation of WordPress and Toolset that you can access the dashboard here:

hidden link

- Create a simple Form
- Add a validation code in functions.php using the File Manager plugin that is installed
- Make sure that the form is submitted via Ajax
- See if the same issue is there

If yes, then I will report this to the second tier to follow up.

If it is not replicable, please follow the steps below:

- IMPORTANT STEP! Create a backup of your website.
- Switch to the default theme such as "TwentyTwenty" by going to "WordPress Dashboard > Appearance > themes".
- Go to "WordPress Dashboard > Plugins" and deactivate all plugins except Toolset and its add-ons.
- Check if you can still recreate the issue.
- If not, re-activate your plugins one by one and check the issue each time to find out the plugin that causes the problem.

Also, Would you please kindly follow the steps below to provide the debug information?

https://toolset.com/faq/provide-debug-information-faster-support/

Thanks.

#2544583

Apologies, I opened this ticket in pure frustration as I got completely brick walled by this problem as there doesn't seem to be any easy way of debugging the AJAX calls.

I have since had a minor breakthrough after sleeping on it and have narrowed it down to two specific functions that are both causing the validation to fail to fire when they are active, but I've not had time to debug them further at this point.

Could I kindly request this ticket is left open for a few days until I've finished debugging them in case I need some specific help. If not I will report back on what the issue was so that it is documented just in case anyone else that has a similar issue.

#2544969

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

Sure thing. This ticket will be closed in 10 days automatically.

so you will have time till then to answer back.

Thanks.

#2545597

Ok, I have some more information after MUCH debugging trial and error, but I could do with some clarification on a point or two and probably some help after all.

So I have validation hook calls in multiple snippets, and snippets are structured alphabetically obviously. So the first three examples of this are as follows:


adding_children_to_class_functions
class_edit_functions
custom_form_validations

And the issue I've noticed originates in the custom_form_validations file, as this contains all of the main basic form validations, and has over 300 lines of code in it, but all of the validations are written as one long ifelse under one function.

If all three snippets are active, the validation hooks in the first two function perfectly and the third (the main one) will not function (the validation literally does not appear to fire at all). If I disable the first two, then the third one starts working again, but if there is even a call to the cred_form_validate hook in either of those files with empty functions, absolutely zero code in the function, then the third file's validations will fail again. This really makes very little sense to me.

So I've tried taking the simplest validation from the function the main custom_form_validations file and isolating it, here is the stripped-back function in question:

function term_validations( $error_fields, $form_data ){
  //Load list of field data comprised of field values and errors
  list( $fields, $errors ) = $error_fields;
  //uncomment this if you want to print the field values
  //print_r($fields);

  /** Validation for New Term form OR Edit Term form OR Edit Term Dates form **/ 
  //if( $form_data['id'] == 446 || $form_data['id'] == 732 || $form_data['id'] == 1132 )
  if( $form_data['id'] == 732 ){

    /* Validation - Check the End Date comes after the Start Date */ 
    if( $fields['wpcf-term-start-date']['value']['datepicker'] > $fields['wpcf-term-end-date']['value']['datepicker']){
      //End Date error message
      $errors['term-end-date'] = 'End Date must be greater than the Start Date';
    }

    //Return array of results
    return array( $fields, $errors );
  }
}
add_filter( 'cred_form_validate', 'term_validations', 10, 2 );

But the same pattern is true. It works in isolation, but not with the other hook calls active. I've moved it to a new snippet and it works fine by itself, but not with the other calls. I moved the, admittedly more complex, validation from the adding_children_to_class_functions snippet into the new file while leaving the original snippet inactive, and having the two validation calls again resulted in the above validation function not firing and the second one (see below) working fine, exactly as they had when in individual snippet files. Here is the code from the adding_children_to_class_functions snippet:

function add_child_to_class_validations( $error_fields, $form_data ) {
  //Load list of field data comprised of field values and errors
  list( $fields, $errors ) = $error_fields;
  //uncomment this if you want to print the field values
  //print_r($fields);

  //Validation for Add Child to Class form
  if ( $form_data['id'] == 1283 ){

    //Get current class ID
    $class = get_the_ID();

    //Get number of children assigned to current class
    $assigned_children = toolset_get_related_posts(
      $class,
      'child-class',
      array( 
        'query_by_role'	=>	'parent',
        'limit'			=>	999,
        'offset'		=>	0,
        'args'			=>	array(),
        'return'		=>	'post_id',
        'role_to_return'=>	'child'
      )
    );

    //Get number of children being added
    $added_children = count( $_POST['select-children'] );
    //Sum the total number of children this will be
    $total_children = count( $assigned_children ) + $added_children;
    //Get classes stored capacity
    $capacity = get_post_meta( $class, 'wpcf-class-capacity', true );

    //Check there is space in the class
    if( $total_children >= $capacity ){

      //Capacity error message
      $errors['select-children'] = 'Sorry, this will exceed the classes maximum capacity of ' . $capacity;

      //return result
      return array( $fields, $errors );
    }

    //Loop through the children added
    foreach( $_POST['select-children'] as $child ){

      //If child is already in the array of children in the class
      if( in_array( $child, $assigned_children ) ){

        //Duplicate child error message
        $errors['select-children'] = 'Sorry, ' . get_post_meta( $child, 'wpcf-child-first-name', true ) . ' ' . get_post_meta( $child , 'wpcf-child-surname', true ) . ' is already in this class.';

        //return result
        return array( $fields, $errors );

      }

      //Check to see if this child has available tokens
      $child_tokens = toolset_get_related_posts(
        $child,
        'child-token',
        array( 
          'query_by_role'	=>	'parent',
          'limit'			=>	999,
          'offset'		=>	0,
          'args'			=>	array(
            'meta_key' => 'wpcf-token-status',
            'meta_value'	=>	'Available',
            'meta_compare'	=>	'='
          ),
          'return'		=>	'post_id',
          'role_to_return'=>	'child'
        )
      );

      //If available tokens are found
      if( !empty( $child_tokens ) ){

        if( isset( $_POST['all-classes'] ) ){
          if( count( $child_tokens ) < count( get_class_group( $class, 'future' ) ) ){

            $errors['select-children'] = token_error_message( $child, 'quantity' );

            //return result
            return array( $fields, $errors );
          }
        }

        //Loop through each token
        foreach( $child_tokens as $child_token ){

          //If the token end date is NOT in the future (end date is smaller than current date)
          if( get_post_meta( $child_token, 'wpcf-token-valid-until-date', true ) < strtotime( "now" ) ){
    
            //Token error message
            $errors['select-children'] = token_error_message( $child, 'status' );

            //return result
            return array( $fields, $errors );
          }
        }
        //If no available tokens were found
      } else {
        //Token error message
        $errors['select-children'] = token_error_message( $child, 'status' );

        //return result
        return array( $fields, $errors );
      }
    }
  }
}
add_filter( 'cred_form_validate', 'add_child_to_class_validations', 10, 2 );

But as I've said, both of these validations work perfectly in isolation, and if they're both active the second one will always work fine and the first (which is a part of something much larger usually) will not work at all.

I have managed to make them both work at the same time by combining them into a single function and hook call by using the form ID's as an ifelse, but surely this just brings up more questions.

I've also tried changing the priorities on the hook calls, but it's made no difference.

I also have validation hook calls in another file called woocommerce_refund_functions, and having this validation hook active does not appear to affect the others, but the validation isn't 100% working right now as I've pulled it apart trying to figure this issue out, so I can't confirm if it can coexist or not at this point.

So from what I can see, it appears that it's not liking multiple validation hook calls being active. Is this a factor for Toolset? Is there a proper way of using multiple validation hook calls for Cred forms? Can it become an issue if several are in different files at once? It doesn't seem to make sense that I'd have to combine all validation calls into a single giant function for them to work as this isn't how hooks are designed to function.

If not, do you have any idea what else could be affecting this, as the forms only have the most basic of JS on them, just editing field rendering, the behaviour is consistent with just Toolset Types, Blocks, and Forms as active plugins and on the default theme.

I'd really appreciate some help debugging this further as at present it appears to be an issue with how Toolset is processing the cred_form_validate hook calls.

#2546335

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

This seems to be a complex issue that I am not sure if we can help as it is a complicated custom code that you use there.

What I can suggest which I am not sure how helpful it can be:

1- You said you played with the priorities, try to use 2, 10 instead of 10, 2. See what happens.

2- Try to combine all instances and see if it works? If not, then it might be a resource issue:

Maybe check the max exec time in PHP and see if it is more than 300s and not 30s.

Also, check the PHP and WordPress memory limit and make sure it is at least 512M.

Also, check the max_input_var and make sure it is more than 1000.

3- Use the Sandbox that I gave to you and add small validations in different files three times. That way you will see if the number of the cred_validation calls is the issue or the length of the code.

4- If nothing helps, you will need to install X Debug and follow the steps of the code execution one step at a time to see what happens when it comes to executing the hook for the third instance.

Thanks.

#2549299

I'm not convinced it's a custom code issue, or if it is it's not isolated to the validation hook call as I can have every other instance disabled except the simplest check as detailed above, but then any further hook call stops it dead, so you can ignore the complexity of the second validation example above, it was just the first one I grabbed that was easy to test.

This feels way more like an AJAX issue somewhere as if I run the same setup without the AJAX on, I can dump out the results of the validation right before the return.

Execution and memory limits are fine, as the site has some heavy processing to do sometimes, so those are right up anyway.

Experimenting with the priorities has not changed anything.

Combining every validation call into one long function is really not a viable solution given the nature of some of the validation calls.

I've tried installing a local version of the site and getting xDebug up and running, but so far I've not been able to get it interfacing with the site properly as the integration process has a fair bit of conflicting information online about how to set up the local.json file.

But I'm really stumped as to where to go next as I have no idea to watch the AJAX execution order, so the next thing I'm trying is disabling EVERY code snippet except the validation ones to search for a non-validation related conflict. But I could really use any further insight as to what could affect the AJAX validation from running.

#2549555

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

I honestly do not have any other suggestions other than the ones I already mentioned.

The thing is that if Ajax is the problem then it should be replicable on a clean installation.

Only that way I can report this to the development team. That is why I created a clean installation in my first reply. I will paste the dashboard here:

hidden link

So by adding two or three validation codes using the File Manager plugin and using the Ajax submit feature of the form that you will create there it will show the issue.

If yes, then we will follow up by reporting this to the compatibility team.

If not, then it is not an Ajax issue and you will still need to follow the steps mentioned in the previous reply to use X Debug to find where the issue is happening on your code.

Just to make sure I give all the possible avenues, you also are welcome to hire a developer to take a look on the code:

https://toolset.com/contractors/

Thank you.

The topic ‘[Closed] Validation Messages Not Appearing in Form Messages Field’ is closed to new replies.