0

I want to make pre validation in some custom post type I made, I decided to do this with ajax, so I wrote this code: Enqeue the script:

function hazeracareer_admin_scripts(){
    global $post_type;    

    if ( $post_type == 'job' ) {
        $theme_uri = get_stylesheet_directory_uri();
        wp_register_script('pre-job-submit-validation', $theme_uri . '/admin/js/pre-job-submit-validation.js', array('jquery'), '2133672');
        wp_localize_script('pre-job-submit-validation', 'secure', array('nonce' => wp_create_nonce('hazeracareer_pre_job_submit_validation')));
        wp_enqueue_script('pre-job-submit-validation');
    }

}
add_action('admin_enqueue_scripts', 'hazeracareer_admin_scripts');

The JS file:

jQuery(document).ready(function ($) {
    $('#post').submit(function () {

        var form_data = $('#post').serialize();
        var nonce = secure.nonce;
        var data = {
            action: 'hazeracareer_pre_job_submit_validation',
            security: nonce,
            form_data: form_data
        };
        $.post(ajaxurl, data, function (response) {
            if ( response == 0 ) {
                alert('The Job Number You entered is already exists in another job!');
                return false;
            } else {
                return true;
            }
        });
    });
});

Handle the ajax request and make the validation:

function hazeracareer_pre_job_submit_validation(){

    check_ajax_referer('hazeracareer_pre_job_submit_validation', 'security');

    $post = array();
    parse_str($_POST['form_data'], $post);

    if ( !isset($post['fields']['field_job_number']) )
        return;

    $jobs = get_posts(array(
        'post_type' => 'job',
        'post_status' => array('publish', 'draft'),
        'posts_per_page' => -1,
        'meta_key' => 'job_number',
        'meta_value' =>$post['fields']['field_job_number']
    ));

    if ( empty($jobs) ) {
        echo 1;
    }

    echo 0;



    wp_die();

}
add_action('wp_ajax_hazeracareer_pre_job_submit_validation', 'hazeracareer_pre_job_submit_validation');

But even though I get the error alert "The Job Number You entered is already exists in another job!", after I press OK the form does submit, and I get the admin notice that confirm the post was updated. After the alert I returned false so the form should not be submitted. I search in the web and nothing seems to work. What am I missing here?

Thanks in advance

Avishay28
  • 2,288
  • 4
  • 25
  • 47
  • 1
    http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Chris Mar 19 '17 at 16:59

2 Answers2

1

Your issue lies in the fact that you are returning false from within a nested function. Looking at your code,

jQuery(document).ready(function ($) {
    $('#post').submit(function () {

        //...
        //you need to return from within this function

        $.post(ajaxurl, data, function (response) {

            //...
            //you are instead returning from this function, which will not stop the form submission

        });
    });
});

The way I would resolve this is to use a persistent variable of some sort in order to know if your validation passed. As an example,

jQuery(document).ready(function($) {

    //protect scope
    $(function() {

        //track the validation
        var valid = false;

        //form submit
        $('#post').on('submit', function(evt) {

            if( valid === true )
                return true;    //now the form will submit!

            //not valid yet! Perform validation
            $.post(ajaxurl, data, function(response) {

                //was the response valid?
                if( response_is_valid ) {

                    valid = true;
                    $('#post').trigger('submit');   //trigger the submit event, which will submit the form since valid is not true

                }else {
                    //display some error to the user
                }

            });


            //always returning false otherwise, so the form never submits
            return false;
        });

    });

});
Chris
  • 4,762
  • 3
  • 44
  • 79
  • What's the purpose of the ` $(function()` you put inside the `document.(ready)`? Thank you for your help – Avishay28 Mar 20 '17 at 07:53
  • It is a self calling function. I use it to protect variable scope. Since `var valid` is created within this function, the variable will not pollute the scope outside of this function. http://stackoverflow.com/questions/3259496/jquery-document-ready-vs-self-calling-anonymous-function – Chris Mar 20 '17 at 13:35
0

change

$('#post').submit(function () {

to

$('#post').submit(function (e) {
  e.preventDefault();
  ....

or another option is do not use a "submit" button. Use a "button" button with an "on click" event. Check if everything is fine and if so, then do the

....
    if (fine = true){
      $("#post").submit();
    }
...
Alex Angelico
  • 3,710
  • 8
  • 31
  • 49