0

I am developing a reservation form using ajax. I am facing 2 problems. One is When I use the shortcode of the form in the page or post, showing the form in the WP backend 5.2.3 version. Another one is when I check the nonce field using this function check_ajax_referer(). The form does not appear in the view page. Only showing -1 in the view page.

/*
Plugin Name: Ajax Reservation Form
Plugin URI: http://example.com
Description: Reservation Form
Version: 1.0
Author: Ataur Rahman
Author URI: md-ataur.github.io
License: GPL v2 or later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  ajax-reservation-form
*/
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
if(!class_exists('AjaxReservationForm')){
    class AjaxReservationForm{
        public function __construct(){
            add_action('plugins_loaded', array($this, 'ajaxrf_load_textdomain' ));
            add_action('wp_enqueue_scripts', array($this, 'ajaxrf_enqueue_scripts'));
            add_shortcode( 'ajax_reservation_form', array($this,'ajaxrf_shortcode' ));
            add_action( 'wp_ajax_ajaxRSF', array($this, 'AjaxdataProcess') );
            add_action( 'wp_ajax_nopriv_ajaxRSF', array($this, 'AjaxdataProcess') );
        }
        public function ajaxrf_load_textdomain(){
            load_plugin_textdomain( 'ajax-reservation-form', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
        }
        public function ajaxrf_enqueue_scripts(){
            wp_enqueue_style( 'bootstrap', plugin_dir_url( __FILE__ ).'assets/public/css/bootstrap.min.css');
            wp_enqueue_script( 'ajax-reservation-js', plugin_dir_url( __FILE__ ).'assets/public/js/ajax-reservation.js', array( 'jquery' ), time(), true );
            $ajaxUrl = admin_url( 'admin-ajax.php');
            wp_localize_script( 'ajax-reservation-js', 'url', array('ajaxUrl' => $ajaxUrl) );
        }

        public static function AjaxdataProcess(){
            if (check_ajax_referer( 'rsf_nonce_action', 'snonce' )) {
                $RFname     = sanitize_text_field( isset($_POST['RFname'])?$_POST['RFname']:'' );
                $RFemail    = sanitize_text_field( isset($_POST['RFemail'])?$_POST['RFemail']:'' );
                $RFphone    = sanitize_text_field( isset($_POST['RFphone'])?$_POST['RFphone']:'' );
                $RFperson   = sanitize_text_field( isset($_POST['RFperson'])?$_POST['RFperson']:'' );
                $RFdate     = sanitize_text_field( isset($_POST['RFdate'])?$_POST['RFdate']:'' );
                $RFtime     = sanitize_text_field( isset($_POST['RFtime'])?$_POST['RFtime']:'' );
                $RFMessage  = sanitize_text_field( isset($_POST['RFMessage'])?$_POST['RFMessage']:'' );                 
                $data = array(
                    'RFname' => $RFname,
                    'RFemail' => $RFemail,
                    'RFphone' => $RFphone,
                    'RFperson' => $RFperson,
                    'RFdate' => $RFdate,
                    'RFtime' => $RFtime,
                    'RFMessage' => $RFMessage,
                );      
                echo "<pre>";
                print_r($data);
                echo "</pre>";  
            }
        }

        public static function ajax_reservation_form(){         
            ?>
            <div class="container">
                <div class="col-md-6 offset-md-3">
                    <form action="<?php the_permalink(); ?>" id="arform">
                        <?php wp_nonce_field( 'rsf_nonce_action', 'rsf_nonce_field');?>
                        <div class="form-group">
                            <label for="name" class="label">Name</label>                
                            <input type="text" class="form-control" id="RFname">                            
                        </div>
                        <div class="form-group">
                            <label for="email" class="label">Email</label>
                            <input type="email" class="form-control" id="RFemail">                           
                        </div>
                        <div class="form-group">
                            <label for="phone" class="label">Phone</label>                            
                            <input type="text" class="form-control" id="RFphone">
                        </div>
                        <div class="form-group">
                            <label for="persons" class="label">Number of Persons</label>
                            <select name="persons" id="RFperson" class="form-control">
                                <option value="1">1 person</option>
                                <option value="2">2 person</option>
                                <option value="3">3 person</option>
                                <option value="4">4 person</option>
                                <option value="5">5 person</option>
                            </select>                            
                        </div>
                        <div class="row">
                            <div class="form-group col-md-6">
                                <label for="date" class="label">Date</label>
                                <input type="date" class="form-control" id="RFdate">                                
                            </div>
                            <div class="form-group col-md-6">
                                <label for="time" class="label">Time</label>
                                <input type="time" class="form-control" id="RFtime" autocomplete="off">
                            </div>
                        </div>   
                        <div class="form-group">
                            <textarea class="form-control" id="RFMessage" rows="5"></textarea>
                        </div>                 
                        <div class="row justify-content-center">
                            <button id="reserveForm" class="btn btn-primary">Reserve Now</button>
                        </div>
                    </form>
                </div>
            </div>
            <?php
        }

        public function ajaxrf_shortcode(){
            self::AjaxdataProcess();
            self::ajax_reservation_form();
        }
    }
    new AjaxReservationForm;
}

Javascript

;(function($){
    $(document).ready(function(){       
        $('#reserveForm').on('click', function(){
            $.post(url.ajaxUrl, {
                action: 'ajaxRSF',
                snonce: $('#rsf_nonce_field').val(),
                RFname: $('#RFname').val(),
                RFemail: $('#RFemail').val(),
                RFphone: $('#RFphone').val(),
                RFperson: $('#RFperson').val(),
                RFdate: $('#RFdate').val(),
                RFtime: $('#RFtime').val(),
                RFMessage: $('#RFMessage').val()
            }, function(data) {
                console.log(data);
            });         
            return false;
        });
    });
})(jQuery);

enter image description here

1

One is When I use the shortcode of the form in the page or post, showing the form in the WP backend 5.2.3 version.

That happens because your shortcode is echoing the output. A shortcode should always return the output, but if you need to echo it, then you should use output buffering:

public function ajaxrf_shortcode(){
    // Turn on output buffering.
    ob_start();

    self::AjaxdataProcess();
    self::ajax_reservation_form(); // echo the form

    // Turn off output buffering and then return the output echoed via the above functions.
    return ob_get_clean();
}

Another one is when I check the nonce field using this function check_ajax_referer(). The form does not appear in the view page. Only showing -1 in the view page.

First off, why are you calling AjaxdataProcess() in the shortcode function (ajaxrf_shortcode())? Is it because you are allowing non-AJAX form submissions?

But that "-1" could happen if the (AJAX) request verification failed (e.g. due a missing or an expired nonce) and by default, check_ajax_referer() will call either wp_die() if doing an AJAX request or die() otherwise.

And to prevent WordPress/PHP execution from being halted upon failure of the request verification, set the third parameter to false when you call check_ajax_referer():

check_ajax_referer( 'rsf_nonce_action', 'snonce', false )

If you want to allow non-AJAX form submissions...

  1. Make sure the relevant form fields are assigned the proper name; e.g.:

    <input type="text" class="form-control" id="RFname" name="RFname">
    <input type="email" class="form-control" id="RFemail" name="RFemail">
    
  2. You should also set the form's method to post (because AjaxdataProcess() is using $_POST):

    <form action="<?php the_permalink(); ?>" id="arform" method="post">
    
  3. Although your form does include the proper nonce, WordPress/PHP doesn't recognize it because you're not using the proper name — you used snonce with check_ajax_referer() (and in your JS script), but in the form, the name is rsf_nonce_field:

    • In ajax_reservation_form()the value of the second parameter for wp_nonce_field() should match the value of the second parameter for check_ajax_referer() (and in fact, same goes to the first parameter..):

      <?php wp_nonce_field( 'rsf_nonce_action', 'rsf_nonce_field');?>
      

    So that rsf_nonce_field should be changed to snonce.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.