JQuery AJAX Post and Refresh Page Content without reload page

12,452

Solution 1

Yes, jQuery can do it using ajax.

First of all, when using ajax, you don't have to post a form to get the data. Ajax in jQuery will load the text data of an url.

You may start by giving your select an id (here id="changeCurrency") and:

$("#changeCurrency").change(function(){
    currency = $('#changeCurrency option:selected').val() // get the selected option's value
    $("#some_div").load("someurl.php?currency=" + currency);
});

Now read up on jQuery and ajax for what kind of ajax call you need to do that suites your needs the best.

Solution 2

NOTE: this answer show some ideas about the php backend for the AJAX process. It is a complement for the other answers talking about the frontend process.

1.- a mockup to manage AJAX request in WP, just some ideas, ok?

add_action('init', 'process_ajax_callback');

function process_ajax_callback()
{
    if ( ! $_REQUEST['go_ajax'])
    {
        return;
    }

    try
    {
        if (isset($_REQUEST['nonce_my_ajax']))
        {
            $nonce   = $_REQUEST['nonce_my_ajax'];
            if ( ! wp_verify_nonce($nonce    = $_REQUEST['nonce_my_ajax'], 'nonce_my_ajax'))
            {
                throw new Exception("Nonce token invalid."); // security
            }
        }
    }
    catch (Exception $e)
    {
        $output['result']    = false;
        $output['message']   = $e->getMessage();

        echo json_encode($output);
        exit;
    }

    $result  = true;
    $message = '';

    switch ($_REQUEST['action'])
    {
        case 'update_price':
        try
        {
            // update price
            // price value comes in $_REQUEST['price']
        }
        catch (Exception $e)
        {
            $result              = false;
            $message             = $e->getMessage();
        }
        break;      

        case 'other_actions':
        break;      
    }

    $output['result']    = $result ? true : false;
    $output['message']   = $message;

    echo json_encode($output);
    exit;
}

2.- don't forget security

// nonce_my_ajax is passed to javascript like this:
wp_localize_script('my_js_admin', 'myJsVars', array(
    'nonce_my_ajax'  => wp_create_nonce('nonce_my_ajax')
));

3.- in general the needed in the frontend (to use with the backend mockup showed above) is something like:

$("select[name='ChangeCurrency']").live("change", function() {
    var price = $(this).val();
    $.post(
            window.location.href,
            {
                go_ajax : 1, // parse ajax
                action : 'update_price', // what to do
                price : price, // vars to use in backend
                nonce_my_ajax : myJsVars.nonce_my_ajax // security
            },
            function(output) {
            if ( output.result == true )
                // update widgets or whatever
                // $("#my_div").html("we happy, yabadabadoo!");
                // or do nothing (AJAX action was successful)
            else
                alert(output.message)
            }, 'json');
});

4.- You can use $.get() or $.post() to send/process data to/in server but .load() is not good when you update DB because you can't manage returning messages of failures with the precision of a json response (for example: multiples validation error messages). Just use .load() to load HTML views.

UPDATE:

Set session_id() where can be executed both for normal requests and for ajax requests and at the early stage as possible. I hope you are using a class to wrap your plugin, if not now is the right moment to do it... example:

class my_plugin {

    function __construct()
    {
        if ( ! session_id())
        {
            session_start();
        }

        add_action('init', array($this, 'process_ajax_callback'));

        // ...
    }   

    function process_ajax_callback()
    {
        // ...
    }
}

UPDATE 2:

About nonce based security:

A security feature available in WordPress is a “nonce”. Generally, a “nonce” is a token that can only be used once and are often used to prevent unauthorised people from submitting data on behalf of another person.

Ref: http://myatus.com/p/wordpress-caching-and-nonce-lifespan/

In this mockup nonce_my_ajax is just an example, indeed it should be more unique like nonce_{my_plugin_name}, or even better nonce_{my_plugin_name}_{what_action} where what_action represents updating user, or inserting new book, etc...

More info about it: WP Codex: WordPress Nonces, WPtuts+: Capabilities and Nonces.

Share:
12,452
Gravy
Author by

Gravy

Updated on June 04, 2022

Comments

  • Gravy
    Gravy almost 2 years

    Now I know that I am at risk here of asking a duplicate question, however I don't really know what to search for because I am a complete AJAX jQuery noob. Believe me, I have tried searching what I think is the obvious, with no luck so please go easy on me.

    I have a php wordpress site which shows prices in GBP as default. At the top, is a select box with onchange="this.form.submit()" which allows the user to change the default currency that all prices are quoted in.

    <form method="post" action="">
        <select name="ChangeCurrency" onChange="this.form.submit()">
            <option value="GBP">GBP</option>
            <option value="USD">USD</option>
            <option value="EUR">EUR</option>
        </select>
    </form>
    

    On the home page, are several, what I call "shortcode widgets", each one containing products and price tables. A dashboard if you like.

    How it currently works (inefficient):

    1. User changes select.
    2. Form submitted
    3. Homepage reloaded with updated prices in selected currency.

    This is not good, because whenever somebody changes currency, the whole page is reloaded (this takes time, transfers approx 1mb without caching, not to mention unnecessary load on the server).

    What I want (more efficient):

    1. When the select box is changed, I wish to asynchronously post the form which changes the currency session variable.
    2. Each "shortcode widget" is updated one by one without having to reload the entire page.

    Is this something that jquery can do? where do I start?

    Just in case it makes any difference so that you can see what I mean, here is the URL so that you can see what I am talking about... http://bit.ly/10ChZys

    PART 2: I have used jQuery and ajax to update the fixTable thanks to a mashup of answers below... I am using session variables to store the users choice, that way, if they return to the site, the option will be saved.

    I am having problems with my code because the session variable stored within http://goldealers.co.uk/wp-content/plugins/gd/tables.php?currency=GBP&table=fixTable appears to have a different session_id to the user's session id because the option is no longer stored.

    Is there a way of telling the server that they are one and the same session?

    SOLUTION I used Ribot's Solution to start with which worked and solved the initial problem, then extended with NomikOS's solution...