0

I've been trying to grasp AJAX for the past 12 hours and i'm slowly losing it. How can I simply pass two basic input dates via form or any other means, not refresh the page, and have it execute the PHP function which contains a JS script?

Before I even pass the values to the script I just wanna echo the array of data I'm passing to see if...well ajax is working. The form button just refreshes the page regardless, so I don't think AJAX is even kicking in at all. I'm trying on the https://localhost for xampp. I don't know what's missing to stop the refresh and kick in the ajax script over the button.

Appreciate any insight.

functions.php

<?php
add_action('wp_enqueue_scripts','enqueue_parent_styles');
add_action('wp_ajax_nopriv_lineChartCustom', 'lineChartCustomCreate');
add_action('wp_ajax_lineChartCustom', 'lineChartCustomCreate');

function lineChartCustomCreate(){

    if ( isset( $_POST['dataForPHP'])){
        //echo data array
    echo $dataForPHP;
    //<script>Some chart generating script using the data array</script>
    }
}
?>

page-template.php

<?php
    echo "<form id='my-form'>
        Select Date Range:
        <input type='date' name='date1'>
        <input type='date' name='date2'>
        <input type='submit' id='submit' value='submit'>
        </form>";
?>
<script>
        jQuery('#submit').on('click', function() {

            let formData = jQuery('#my-form').serializeArray(); // retrieves the form's data as an array

           jQuery.ajax({
                     url: ajaxurl, // default ajax url of wordpress
                     type: 'POST',
                     data: {
                         action: 'lineChartCustom', // use this action to handle the event
                         dataForPHP: formData // this is your form's data that is going to be submitted to PHP by the name of dataForPHP                
                 });
             });
         });
</script>

3 Answers 3

0

You should add wp_die(); at the end of your php function.

But you could also send the response with wp_send_json, wp_send_json_error or wp_send_json_success. These functions also terminate the function execution.

2
  • It's because i omitted the die function that it's not executing? It's still refreshing the page which is sort of the cue for me that ajax isn't doing anything Commented Apr 14, 2019 at 21:30
  • Yes, you need to end the PHP function in one way or the other to return a proper response. I don't know, if you know this already, but please note that you won't be seeing the echo / var_dump() / print_r() on the page, but in browser dev tools > network > ajax call's response tab. And also as @nmr pointed out onclick must return false or call .preventDefault() to prevent browser from submitting the form and stopping your javascript from kicking in. Commented Apr 15, 2019 at 6:42
0

The page is refreshed because you are sending the form synchronously (traditionally). To send the form using ajax your function hooked to onclick must return false or call .preventDefault() on submit event.

jQuery( "#my-form" ).submit(function( event ) {
    event.preventDefault();
    //
    // your code...
});

// --- or --- 

jQuery('#submit').on('click', function() {
    // ....
    return false;
});

Edit:

Move your javascript code to separate file (e.g. myscript.js). include that file on page using wp_enqueue_scripts() (hook). in the code you used ajaxurl but you have not defined it anywhere. wp_localize_script() is used to pass values from php to javascript, this way you will set the address for ajax in ajx_url variable.

page-template.php:

<?php
echo "<form id='my-form'>
    Select Date Range:
    <input type='date' name='date1'>
    <input type='date' name='date2'>
    <input type='submit' id='submit' value='submit'>
    </form>";
?>

myscript.js:

jQuery('#submit').on('click', function() {

    let formData = jQuery('#my-form').serializeArray(); // retrieves the form's data as an array

    jQuery.ajax({
        url: ajax_object.ajax_url, // default ajax url of wordpress
        type: 'POST',
        data: {
            action: 'lineChartCustom', // use this action to handle the event
            dataForPHP: formData // this is your form's data that is going to be submitted to PHP by the name of dataForPHP                
        }
    }).done(function( msg ) {
        alert( msg );
    });
    return false;
});

functions.php

add_action( 'wp_enqueue_scripts', 'my_enqueue' );
function my_enqueue() {

    wp_enqueue_script( 'my-javascript', get_stylesheet_directory_uri(). '/myscript.js',  array('jquery'), '', true );

    // in JavaScript, object properties are accessed as ajax_object.ajax_url
    wp_localize_script( 'my-javascript', 'ajax_object',
            array( 'ajax_url' => admin_url('admin-ajax.php') ) );
}

add_action('wp_enqueue_scripts','enqueue_parent_styles');
add_action('wp_ajax_nopriv_lineChartCustom', 'lineChartCustomCreate');
add_action('wp_ajax_lineChartCustom', 'lineChartCustomCreate');

function lineChartCustomCreate(){

    if ( isset( $_POST['dataForPHP']) ){
        //echo data array
        print_r($_POST['dataForPHP']);
    }
    die();
}
3
  • Is that the traditional method to do all ajax calls asynchronously? I had tried even with a standard <button> rather than a <form> and the button would yet still not trigger the jquery Commented Apr 14, 2019 at 22:20
  • @Dennisio By default, jQuery.ajax() is asynchronous but it can be changed by the async parameter, jQuery ajax Commented Apr 14, 2019 at 22:37
  • @Dennisio Check updated answer Commented Apr 14, 2019 at 23:39
0

You’re super close—three core issues are blocking you:

You’re binding to the button click without preventing the form submit (so the page refreshes).

Ajax-URL is not defined on the front-end unless you localize it (it exists only in wp-admin).

Your PHP handler echoes nothing useful and doesn’t end with wp_die()/wp_send_json_*.

Below is a minimal, bullet-proof setup.

    add_action('wp_enqueue_scripts', function () {
        // Enqueue your JS (adjust path as needed)
        wp_enqueue_script(
            'tk-linechart-ajax',
            get_stylesheet_directory_uri() . '/js/tk-linechart-ajax.js',
            ['jquery'],
            null,
            true
        );
    
        // Localize ajax URL + nonce for front-end use
        wp_localize_script('tk-linechart-ajax', 'tkAjax', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('linechart_nonce'),
        ]);
    });
    
    // AJAX hooks (for logged-in + logged-out)
    add_action('wp_ajax_lineChartCustom', 'lineChartCustomCreate');
    add_action('wp_ajax_nopriv_lineChartCustom', 'lineChartCustomCreate');
    
    function lineChartCustomCreate() {
        // Security
        check_ajax_referer('linechart_nonce');
    
        // Get data
        $data = isset($_POST['dataForPHP']) ? wp_unslash($_POST['dataForPHP']) : [];
    
        // If you just want to "echo" what you got, send JSON back
        // serializeArray() sends an array of objects [{name:..., value:...}, ...]
        // so $data will be an array you can inspect.
        wp_send_json_success([
            'received' => $data,
            'message'  => 'AJAX working',
        ]);
    }
    
    page-template.php (your form)
    
        <?php
    echo '<form id="my-form">
        <label>Select Date Range:</label>
        <input type="date" name="date1" required>
        <input type="date" name="date2" required>
        <button type="submit" id="submit">Submit</button>
    </form>';
    
    /js/tk-linechart-ajax.js (front-end JS)
    
        jQuery(function ($) {
      $('#my-form').on('submit', function (e) {
        e.preventDefault(); // stop the refresh
    
        const formData = $(this).serializeArray();
    
        $.ajax({
          url: tkAjax.ajax_url,        // comes from wp_localize_script
          type: 'POST',
          dataType: 'json',
          data: {
            action: 'lineChartCustom',
            _ajax_nonce: tkAjax.nonce, // required by check_ajax_referer
            dataForPHP: formData
          },
          success: function (resp) {
            if (resp.success) {
              console.log('Server said:', resp.data);
              // Example: use resp.data.received to feed your chart code
              // buildChart(resp.data.received);
            } else {
              console.error('AJAX error payload:', resp);
            }
          },
          error: function (xhr, status, err) {
            console.error('AJAX request failed:', status, err);
          }
        });
      });
    });

Why your original attempt failed

Page refresh: You listened to #submit click but never preventDefault(). Always bind to the form’s submit event and call e.preventDefault().

Ajax-URL undefined: On the front-end, WordPress does not define Ajax-URL. You must pass admin_url('admin-ajax.php') to JavaScript via wp_localize_script.

Echoing data: $dataForPHP isn’t a PHP variable. Read $_POST['dataForPHP'] and return with wp_send_json_success() (or echo then wp_die()).

No wp_die(): If you echo manually, end with wp_die();. Using wp_send_json_*() handles output + exit properly.

Quick sanity test

  1. Open your page, fill both dates, submit.

  2. Check the browser console: you should see Server said: with the received array echoing your date1 / date2.

  3. Plug that array into your chart code.

This pattern is production-safe (nonce + proper hooks) and works on localhost/XAMPP.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.