Home > Mobile >  Passing Variable From PHP Function to AJAX in Wordpress
Passing Variable From PHP Function to AJAX in Wordpress

Time:09-23

I am currently working on a custom widget for Elementor and need to convert my Javascript functions into Ajax functions. My main issue has been figuring out how to pass variables from PHP to AJAX.

Here is the Javascript for the function in Question:

    //Dynamic Price Calculator

      $('#productQuant').keyup(function(){

        // assign size from checked radio button
        let productSize =  $("input[type=radio][name=sizeRadio]:checked" ).val();
        // assign quantity from values found in input text box
        let productQuantity = $("#productQuant").val();

        $.ajax({
            // admin-ajax.php url
             url: productDataAjax.url,
             method: 'post',
             dataType: 'json',
             data:({
               action: 'priceUpdate',
               phpProductSize: productSize,
               phpProductQuantity: productQuantity

             }),

             success:function(data){
             console.log("Success");
             // Text to product total
              $('#productTotal').text(" "   data.dynamicTotal);
             }

           });


         }); // function end
})( jQuery );

Here is the PHP:

    /* Enque Scripts and Styles */

function shop_plugin_assets(){

  // Enqueue CSS

  wp_enqueue_style( 'bootstrap','https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css', array(), '1.0', 'all' );

// remeber array(), null at the end to mak sure googlefonts load. family = family = etc throws it off
  wp_enqueue_style( 'google-font', 'https://fonts.googleapis.com/css2?family=Bungee&family=Sintony&display=swap', array(), null );



  // Enqueue JQuery and JS Files

  wp_enqueue_script( 'jquery');

  wp_enqueue_script( 'bootstrap-bundle-js', 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js', array(), '1.0', true );

     wp_enqueue_script( 'my-scripts', get_template_directory_uri() . '/js-custom/my-scripts.js', array( 'jquery' ), '1.0', true );


     $script_data_array = array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        );

        wp_localize_script('my-scripts', 'productDataAjax', $script_data_array);

    }

add_action( 'wp_enqueue_scripts', 'shop_plugin_assets', 20 );


function dynamicPriceCalc(){

                 $productSize = $_POST['phpProductSize'];
                 $productQuantity =  $_POST['phpProductQuantity'];
                 $productPrice = 0;
                 $productTotal = 0;
                 $response = array();

                 if( $productSize === "small"){
                     $productPrice = 7.99;
                     $productTotal = number_format( (float) ($productPrice * $productQuantity), 2, '.', '');

                     $response["dynamicTotal"] = $productTotal;
                     echo json_encode($response);

                 }
                 else if( $productSize === "medium"){

                     $productPrice = 10.99;
                     $productTotal = number_format( (float) ($productPrice * $productQuantity), 2, '.', '');
                     $response["dynamicTotal"] = $productTotal;
                     echo json_encode($response);


                 }
                 else if( $productSize === "large"){
                     $productPrice = 14.99;
                     $productTotal = number_format( (float) ($productPrice * $productQuantity), 2, '.', '');
                     $response["dynamicTotal"] = $productTotal;
                     echo json_encode($response);

                 }



                     die();

                 }


                 add_action('wp_ajax_priceUpdate', 'dynamicPriceCalc');
                 add_action('wp_ajax_nopriv_priceUpdate', 'dynamicPriceCalc');

Here is the Elementor widget File:

<?php
class Elementor_Custom_Product_Archive_Food extends \Elementor\Widget_Base {

    public function get_name() {
        return 'Custom Product Archive Food';
    }

    public function get_title() {
        return esc_html__( 'Custom Product Archive Food Service', 'elementor-addon' );
    }

    public function get_icon() {
        return 'eicon-code';
    }

    public function get_categories() {
        return [ 'basic' ];
    }

    public function get_keywords() {
        return [ 'archive', 'product', 'food' ];
    }


// Controls for widgets



    protected function register_controls()

  {
        $this->start_controls_section(
        'button_section',
        [
            'label' => esc_html__( 'Product Archive Food', 'custom_product_archive_food' ),
            'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
        ]
    );

    $this->add_control(
        'button_align',
        [
            'label' => esc_html__( 'Alignment', 'custom_product_archive_food' ),
            'type' => \Elementor\Controls_Manager::CHOOSE,
            'options' => [

                'text-start' => [
                    'title' => esc_html__( 'Left', 'custom_product_archive_food' ),
                    'icon' => 'eicon-text-align-left',
                ],
                'text-center' => [
                    'title' => esc_html__( 'Center', 'custom_product_archive_food' ),
                    'icon' => 'eicon-text-align-center',
                ],
                'text-end' => [
                    'title' => esc_html__( 'Right', 'custom_product_archive_food' ),
                    'icon' => 'eicon-text-align-right',
                ],
            ],
            'default' => 'text-center',
            'toggle' => true,
        ]
    );

    $this->end_controls_section();


  } //end of controls




// Render the HTML and pulll data from controls to change classes or feed settings dynamic properties

protected function render() {
        // settings pulls properties from control options to use within your html blocks
        $settings = $this->get_settings_for_display();
        $checkOutLink = wc_get_checkout_url();

    // Radio Size selector
    echo '<div >';
    echo '<label>  Choose a Size </label>';
    echo '</div>';
    echo '<div  id="radioContainer">';
          echo '<div >';
          echo '<input  type="radio" name="sizeRadio" id="smallRadio" value="small">';
          echo '<label  for="smallRadio">';
          echo 'Small';
          echo '</label>';
          echo '</div>';
          echo '<div >';
          echo '<input  type="radio" name="sizeRadio" id="medRadio" value="medium">';
          echo '<label  for="medRadio">';
          echo 'Medium';
          echo '</label>';
          echo '</div>';
          echo '<div >';
          echo '<input  type="radio" name="sizeRadio" id="largeRadio" value="large">';
          echo '<label  for="largeRadio">';
          echo 'Large';
          echo '</label>';
          echo '</div>';
    echo '</div>';
    // Quantity / Logic Button / Redirect Button';
       echo '<div >';
       echo '<div >';
          echo '<label id="productPrice"> Price: </label>';
          echo '</div>';
          echo '<input type="text"  placeholder="Enter Quantity" aria-label="Quantity" id="productQuant">';
          echo '<div >';
          echo '<label id="productTotal"> Total:</label>';
          echo '</div>';
          echo '<button type="button"  name="button" id="addCartSubmit"> Add to Cart </button>';
          echo '<a href="'.$checkOutLink.'" > Proceed to Check Out</a>';
        echo '</div>';



} // End of protected functions


} //end of class

It is my understanding that I am supposed to call the PHP function using action while sending whatever data I pull with JQuery, execute the PHP function, make an array of the result within that function, encode the result in JSON, and on success have the JSON data inserted into whatever JQuery function I need it for.

For some reason, the function won't work even after trying several variations of the solution seen above. I know the logic works as I've recreated the same solution with pure JQuery and it works without a hitch. I know that there is some type of response going through as I get undefined and a console log of success when I remove the dataType:'json'. I don't know what is happening in between these two things that is stopping me from getting the label change to reflect my new product total.

Some Images After Inputting Text into the Text Field. You'll notice the Total section remains blank:

Header Request showing it accepts Javascript and JSON

Preview Showing HTML page

Response showing HTML - I think I need it to return JSON here

Payload Picture

CodePudding user response:

The core issue was that I was not using the right name for my ajax url. In my case, the object declared in my functions.php needed to be written as productUpdate.ajaxUrl for my ajax url to have the correct url to follow. I thought I needed to writeit as just productUpdate.url

For reference this is where the array and the object were declared in functions.php:

function shop_plugin_assets(){

  // Enqueue CSS

  wp_enqueue_style( 'bootstrap','https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css', array(), '1.0', 'all' );

// remeber array(), null at the end to mak sure googlefonts load. family = family = etc throws it off
  wp_enqueue_style( 'google-font', 'https://fonts.googleapis.com/css2?family=Bungee&family=Sintony&display=swap', array(), null );



  // Enqueue JQuery and JS Files

  wp_enqueue_script( 'jquery');

  wp_enqueue_script( 'bootstrap-bundle-js', 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js', array(), '1.0', true );

     wp_enqueue_script( 'my-scripts', get_template_directory_uri() . '/js-custom/my-scripts.js', array( 'jquery' ), '1.0', true );


     $script_data_array = array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('product_nonce')
        );

        wp_localize_script('my-scripts', 'productDataAjax', $script_data_array);

    }

add_action( 'wp_enqueue_scripts', 'shop_plugin_assets', 20 );

This is the what the proper ajax function looks like:

$('#productQuant').keyup(function(){

        // assign size from checked radio button
        let productSize =  $("input[type=radio][name=sizeRadio]:checked" ).val();
        // assign quantity from values found in input text box
        let productQuantity = $("#productQuant").val();

        $.ajax({
            // admin-ajax.php url
             url: productDataAjax.ajaxUrl,
             method: 'post',
             dataType: 'json',
             data:({

              action: 'priceUpdate',
              phpProductSize: productSize,
              phpProductQuantity: productQuantity,
               _ajax_nonce: productDataAjax.nonce

             }),

             success:function(response){

             console.log("success");
             //Text to product total
             $('#productTotal').text(" "   response.dynamicTotal);
             }

           });


         }); // function end
})( jQuery );

This is the full code after all changes have been made:

Functions.php

/* Enque Scripts and Styles */

function shop_plugin_assets(){

  // Enqueue CSS

  wp_enqueue_style( 'bootstrap','https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css', array(), '1.0', 'all' );

// remeber array(), null at the end to mak sure googlefonts load. family = family = etc throws it off
  wp_enqueue_style( 'google-font', 'https://fonts.googleapis.com/css2?family=Bungee&family=Sintony&display=swap', array(), null );



  // Enqueue JQuery and JS Files

  wp_enqueue_script( 'jquery');

  wp_enqueue_script( 'bootstrap-bundle-js', 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js', array(), '1.0', true );

     wp_enqueue_script( 'my-scripts', get_template_directory_uri() . '/js-custom/my-scripts.js', array( 'jquery' ), '1.0', true );


     $script_data_array = array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('product_nonce')
        );

        wp_localize_script('my-scripts', 'productDataAjax', $script_data_array);

    }

add_action( 'wp_enqueue_scripts', 'shop_plugin_assets', 20 );


function dynamicPriceCalc(){

                check_ajax_referer('product_nonce');

                 $productSize = $_POST['phpProductSize'];
                 $productQuantity =  $_POST['phpProductQuantity'];
                 $productPrice = 0;
                 $productTotal = 0;
                 $response = array();


                 if( $productSize === "small"){
                     $productPrice = 7.99;
                     $productTotal = number_format( (float) ($productPrice * $productQuantity), 2, '.', '');

                     // stor return values in an array
                     $response["dynamicTotal"] = $productTotal;
                     // returns variables to ajax function making the call
                     echo json_encode($response);
                    // wp_ die() better for wordpress rather than just die()
                        wp_die();


                 }
                 else if( $productSize === "medium"){

                     $productPrice = 10.99;
                     $productTotal = number_format( (float) ($productPrice * $productQuantity), 2, '.', '');

                     // stor return values in an array
                     $response["dynamicTotal"] = $productTotal;
                     // returns variables to ajax function making the call
                     echo json_encode($response);
                    // wp_ die() better for wordpress rather than just die()
                        wp_die();

                 }
                 else if( $productSize === "large"){
                     $productPrice = 14.99;
                     $productTotal = number_format( (float) ($productPrice * $productQuantity), 2, '.', '');

                     // stor return values in an array
                     $response["dynamicTotal"] = $productTotal;
                     // returns variables to ajax function making the call
                     echo json_encode($response);
                    // wp_ die() better for wordpress rather than just die()
                        wp_die();
                 }


                 }


                 add_action('wp_ajax_priceUpdate', 'dynamicPriceCalc');
                 add_action('wp_ajax_priceUpdate', 'dynamicPriceCalc');

Javascipt File

$('#productQuant').keyup(function(){

        // assign size from checked radio button
        let productSize =  $("input[type=radio][name=sizeRadio]:checked" ).val();
        // assign quantity from values found in input text box
        let productQuantity = $("#productQuant").val();

        $.ajax({
            // admin-ajax.php url
             url: productDataAjax.ajaxUrl,
             method: 'post',
             dataType: 'json',
             data:({

              action: 'priceUpdate',
              phpProductSize: productSize,
              phpProductQuantity: productQuantity,
               _ajax_nonce: productDataAjax.nonce

             }),

             success:function(response){

             console.log("success");
             //Text to product total
             $('#productTotal').text(" "   response.dynamicTotal);
             }

           });


         }); // function end
})( jQuery );

The nonce was just added for some extra security. It has nothing to do with the actual solution. I'd like to thank everyone again who pitched in to help me fix this issue. Now I can get back to converting the rest of my Javascript into Ajax.

CodePudding user response:

the 'action' needs to match the PHP Action. In your case:

$.ajax({
        // admin-ajax.php url
        url: productDataAjax.url,
        method: 'post',
        dataType: 'json',
        data:({
            action: 'dynamicPriceCalc',
            phpProductSize: productSize,
            phpProductQuantity: productQuantity
        }),
        success:function(data){
        console.log("Success");
        // Text to product total
        $('#productTotal').text(" "   data.dynamicTotal);
        }
    });

and your PHP function should be:

function dynamicPriceCalc(){
    //Your function
}
add_action('wp_ajax_dynamicPriceCalc', 'dynamicPriceCalc');
add_action('wp_ajax_dynamicPriceCalc', 'dynamicPriceCalc');
  • Related