0

I created a shortcode for user submission form. I want to submit this form without loading the page (Ajax).

Here is my shortcode code

add_shortcode('et-test-plugin_shortcode', function($atts, $content) {

    $atts = shortcode_atts(array(
        'name-field' => 'Name',
        'phone-field' => 'Phone Number',
        'email-field' => 'Email Address',
        'budget-field' => 'Desired Budget',
        'min-budget' => '1000',
        'max-budget' => '10000',
        'message-field' => 'Message',
        'submit-btn-label' => 'Submit',
    ), $atts);

    ob_start();
    ?>
    <form action="<?php echo admin_url('admin-ajax.php'); ?>" class="et_test_form" method="post">
        <div class="row">
            <div class="col-sm-6">
                <input type="text" name="_name" placeholder="<?php echo esc_attr($atts['name-field']) ?>">
            </div>
            <div class="col-sm-6">
                <input type="text" name="_phone" placeholder="<?php echo esc_attr($atts['phone-field']) ?>">
            </div>
            <div class="col-sm-6">
                <input type="email" name="_email" placeholder="<?php echo esc_attr($atts['email-field']) ?>">
            </div>
            <div class="col-sm-6">
                <input type="number" name="_budget" min="<?php echo esc_attr($atts['min-budget']) ?>" max="<?php echo esc_attr($atts['max-budget']) ?>" placeholder="<?php echo esc_attr($atts['budget-field']) ?>">
            </div>
        </div>
        <textarea class="form-control" rows="3" cols="10" name="_message" placeholder="<?php echo esc_attr($atts['message-field']) ?>"></textarea>
        <input type="submit" name="submit" value="<?php echo $atts['submit-btn-label']; ?>"/>
        <div id="note"></div>
    </form>
    <?php

    $html = ob_get_clean();

    add_action('wp_ajax_et_test_plugin_create_post', 'et_test_plugin_create_post');
    add_action('wp_ajax_nopriv_et_test_plugin_create_post', 'et_test_plugin_create_post');

    function et_test_plugin_create_post() {
        if (isset($_POST['submit'])) {
            $name = !empty($_POST['_name']) ? $_POST['_name'] : '';
            $phone = !empty($_POST['_phone']) ? $_POST['_phone'] : '';
            $email = !empty($_POST['_email']) ? $_POST['_email'] : '';
            $budget = !empty($_POST['_budget']) ? $_POST['_budget'] : '';
            $message = !empty($_POST['_message']) ? $_POST['_message'] : '';
            if ($name) {
                wp_insert_post(
                    array(
                        'post_title' => wp_strip_all_tags($name) . ' submitted a form',
                        'post_type' => 'customer',
                        'post_status' => 'private', /* Or "draft", if required */
                        'meta_input' => array(
                            'et-test-plugin_customer_name' => wp_strip_all_tags($name),
                            'et-test-plugin_customer_phone' => wp_strip_all_tags($phone),
                            'et-test-plugin_customer_email' => wp_strip_all_tags($email),
                            'et-test-plugin_customer_budget' => wp_strip_all_tags($budget),
                            'et-test-plugin_customer_message' => wp_strip_all_tags($message),
                        )
                    )
                );
            }
        }
    }

    ?>
    <script type="text/javascript">
        var $a = jQuery.noConflict();

        $a(window).load(function(){

            $a(".et_test_form").submit(function(e){

                e.preventDefault();
                var input_data = $a(this).serialize();
                $a.ajax({
                    type: "POST",
                    url: "<?php echo admin_url('admin-ajax.php') ?>",
                    data: input_data,
                    action: 'et_test_plugin_create_post',
                    success: function(alrt){
                        $a("#note").ajaxComplete(function(event, request, settings){
                            if(alrt == "OK"){
                                result = "Thanks for sending the message.";
                                $a(".et_test_form").hide();
                            } else {
                                result = 'Error';
                            }
                            $a(this).html(result);
                        });
                    }
                });

                return false;
            });
        });

    </script>
    <?php

    return $html;

});

I actually don't know why this returning error. Probably, the wp_ajax_et_test_plugin_create_post action isn't working in the shortcode.

2 Answers 2

1

I love to solve problems and to keep that habit fresh I've solved your problem. There were lots of issues. Now the form and ajax is working perfectly but still, there are some issues. For instance, you didn't use nonce or CSRF token, which will lead to CSRF. You didn't use any validation which is also an important issue. You didn't check user capability and login status, not sure it's feature or mistake.

Btw, here is the working code -

function et_text_render_plugin_shortcode( $atts, $content ) {
    $atts = shortcode_atts( array(
        'name-field'       => 'Name',
        'phone-field'      => 'Phone Number',
        'email-field'      => 'Email Address',
        'budget-field'     => 'Desired Budget',
        'min-budget'       => '1000',
        'max-budget'       => '10000',
        'message-field'    => 'Message',
        'submit-btn-label' => 'Submit',
    ), $atts );

    ob_start();
    ?>

    <form class="et_test_form" method="post">
        <div class="row">
            <div class="col-sm-6">
                <input type="text" name="_name" placeholder="<?php echo esc_attr( $atts['name-field'] ); ?>">
            </div>
            <div class="col-sm-6">
                <input type="text" name="_phone" placeholder="<?php echo esc_attr( $atts['phone-field'] ); ?>">
            </div>
            <div class="col-sm-6">
                <input type="email" name="_email" placeholder="<?php echo esc_attr( $atts['email-field'] ); ?>">
            </div>
            <div class="col-sm-6">
                <input type="number" name="_budget" min="<?php echo esc_attr( $atts['min-budget'] ); ?>" max="<?php echo esc_attr( $atts['max-budget'] ); ?>" placeholder="<?php echo esc_attr( $atts['budget-field'] ); ?>">
            </div>
        </div>
        <textarea class="form-control" rows="3" cols="10" name="_message" placeholder="<?php echo esc_attr( $atts['message-field'] ); ?>"></textarea>
        <input type="submit" name="submit" value="<?php echo esc_attr( $atts['submit-btn-label'] ); ?>"/>
    </form>
    <div id="note"></div>
    <script>
        jQuery( function( $ ) {
            $( ".et_test_form" ).on( "submit", function( e ) {
                e.preventDefault();
                var result = '',
                    ajax_url = "<?php echo esc_url_raw( admin_url( 'admin-ajax.php' ) ); ?>";

                $.post(
                    ajax_url,
                    {
                        data: $( this ).serialize(),
                        action: 'et_test_plugin_create_post'
                    },
                    function( res ){
                        if ( res.success ) {
                            $( ".et_test_form" ).hide();
                        }
                        $( "#note" ).html( res.data.message );
                    }
                );

                return false;
            } );
        } )
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode( 'et-test-plugin_shortcode', 'et_text_render_plugin_shortcode' );

function et_test_plugin_create_post() {
    if ( isset( $_POST['data'] ) ) {
        $data = array();
        wp_parse_str( $_POST['data'], $data );

        $name    = ! empty( $data['_name'] ) ? $data['_name']    : '';
        $phone   = ! empty( $data['_phone'] ) ? $data['_phone']  : '';
        $email   = ! empty( $data['_email'] ) ? $data['_email']  : '';
        $budget  = ! empty( $data['_budget'] ) ? $data['_budget']: '';
        $message = ! empty( $data['_message'] ) ? $data['_message'] : '';

        $post = array(
            'post_title'  => wp_strip_all_tags( $name ) . ' submitted a form',
            'post_type'   => 'customer',
            'post_status' => 'private', /* Or "draft", if required */
            'meta_input'  => array(
                'et-test-plugin_customer_name'    => wp_strip_all_tags( $name ),
                'et-test-plugin_customer_phone'   => wp_strip_all_tags( $phone ),
                'et-test-plugin_customer_email'   => wp_strip_all_tags( $email ),
                'et-test-plugin_customer_budget'  => wp_strip_all_tags( $budget ),
                'et-test-plugin_customer_message' => wp_strip_all_tags( $message ),
            )
        );

        if ( $name ) {
            wp_insert_post( $post );

            wp_send_json_success( array(
                'message' => 'Added successfully!',
            ) );
        }
    }
    wp_send_json_error( array(
        'message' => 'Something went wrong!',
    ) );
}
add_action( 'wp_ajax_et_test_plugin_create_post', 'et_test_plugin_create_post' );
add_action( 'wp_ajax_nopriv_et_test_plugin_create_post', 'et_test_plugin_create_post' );
1
  • I understood my mistakes and I learned a lot from your code. I'm grateful to you @obiPlabon <3
    – Eh Jewel
    Commented Feb 26, 2018 at 18:27
1

the 2 "add_action ajax ..." are executed only when the shortcode is executed. and then, ob_get_clean was not a the good place

in order to work, theses actions need to be separated of the shortcode like that :

add_shortcode('et-test-plugin_shortcode', function($atts, $content) {

    //$atts = shortcode_atts ...

    ob_start();
    ?>
        <form action="<?php echo admin_url('admin-ajax.php'); ?>" class="et_test_form" method="post">
            <!-- ... -->
        </form>

        <script type="text/javascript">
            //...
        </script>
    <?php
    $html = ob_get_clean();

    return $html;

});


add_action('wp_ajax_et_test_plugin_create_post', 'et_test_plugin_create_post');
add_action('wp_ajax_nopriv_et_test_plugin_create_post', 'et_test_plugin_create_post');

function et_test_plugin_create_post() {
    // ....
}
1
  • I tried according to your code arrange. But still, it's not working. Probably, the problem is happening for something else.
    – Eh Jewel
    Commented Feb 25, 2018 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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