2

I am working on a voting system in Wordpress. I first made it with GET requests but someone told me you should not use GET for this, So I started working with AJAX to update custom fields/meta values, after reading this article. I've read a lot of the documentation from jQuery and Wordpress AJAX pages this is with I have now.

I think I am on the good way, but there is something missing / or I am doing wrong.

The vote function works fine, because I have tested this earlier with the GET requests.

I have this simple HTML test form:

<form id="vote_form" method="post">
    <input type="hidden" id="id" name="id" value="810">
    <input type="hidden" id="post_id" name="post_id" value="811">
    <input type="submit">
</form>

I have this jQuery file included in my header.php and off course included the jQuery library itself.

jQuery(document).ready(function() {

    jQuery( "#vote_form" ).submit( function( event ) {

        event.preventDefault();

        var id = jQuery("#vote_form #id").val();
        var post_id = jQuery("#vote_form #post_id").val();
        var vote = 'up';

        jQuery.ajax({
            type: "POST",
            url: stn_vote.ajaxurl,
            data: { 
                id: id, 
                post_id: post_id,
                vote: vote, 
                action: 'stn_voting' 
            },

        }); 

    });

});

And my vote function hooked into the wp_ajax action.

    // Ajax Voting
wp_register_script( 'ajax-vote', get_template_directory_uri() . '/js/ajax-vote.js', array('jquery') );

$nonce = wp_create_nonce("vote_nonce");
$stn_vote_data = array(
    'ajaxurl' => admin_url( 'admin-ajax.php'),
    'nonce' => $nonce,
);
wp_localize_script( 'ajax-vote', 'stn_vote', $stn_vote_data );

function stn_script_enqueuer() {    
    wp_enqueue_script( 'jquery' );
    wp_enqueue_script( 'ajax-vote' );

}
add_action( 'wp_enqueue_scripts', 'stn_script_enqueuer' );

        // Vote Up
        if( isset( $_POST['id'] ) ) {

            //simple Security check
            if ( ! wp_verify_nonce( $_POST['nonce'], 'vote_nonce' ) )
                die ( 'Busted!');

            if( isset( $_POST['post_id'] ) ) {
                $post_id =  $_POST['post_id'];
            }

            if( $_POST['vote'] == 'up' ) {

                $vote_id = $_POST['id'];
                $key = 'vote_up_' . $post_id;
                $vote_up = get_post_meta( $vote_id, $key, true );
                $value = $vote_up + 1;
                $update_vote_up = update_post_meta( $vote_id, 'vote_up_' . $post_id, $value );

                // Update vote count
                $vote_count = get_post_meta( $vote_id, 'vote_count_' . $post_id, true );
                $value = $vote_count + 1;
                $update_vote_count = update_post_meta( $vote_id, 'vote_count_' . $post_id, $value );

                // Update vote percent
                $vote_percent = ( ( $vote_up + 1) / ( $vote_count + 1 ) ) * 100;
                update_post_meta( $vote_id, 'vote_percent_' . $post_id, $vote_percent );

            }

            // Vote Down
            else {          
                $vote_id = $_POST['id'];
                $key = 'vote_down_' . $post_id;
                $vote_down = get_post_meta( $vote_id, $key, true );
                $value = $vote_down + 1;
                $update_vote_down = update_post_meta( $vote_id, 'vote_down_' . $post_id, $value );

                // Update vote count
                $vote_count = get_post_meta( $vote_id, 'vote_count_' . $post_id, true );
                $value = $vote_count + 1;
                $update_vote_count = update_post_meta( $vote_id, 'vote_count_' . $post_id, $value );

                // Update vote percent
                $key = 'vote_up_' . $post_id;
                $vote_up = get_post_meta( $vote_id, $key, true );
                $vote_percent = ( $vote_up / ( $vote_count + 1 ) ) * 100;
                update_post_meta( $vote_id, 'vote_percent_' . $post_id, $vote_percent );

            }
        }
        die();

    }
    add_action('wp_ajax_stn_voting', 'ajax_stn_voting');
    add_action('wp_ajax_nopriv_stn_voting', 'ajax_stn_voting');
7
  • 1 When used from frontend url: "/wp-admin/admin-ajax.php" may not work, use the full url that you should retrieve in php using admin_url('admin-ajax.php') and pass to the script using wp_localize_script - 2 most important, your jQuery ajax syntax is wrong, when you use jQuery.ajax() arguments are passed via data property, the action property does not exists... your code should be $.ajax({type: "POST", url: "/wp-admin/admin-ajax.php", data: { id: id, vote: vote, action: "stn_voting" } });.
    – gmazzap
    Apr 7, 2014 at 13:36
  • 3 the global $post variable is not available in the ajax request, that is an entirely new request and does not save any state of the calling page. Before using $post variable you have to get $post using get_post($_POST['id']).
    – gmazzap
    Apr 7, 2014 at 13:38
  • Thanks for your comments! I am gonna try your improvements!
    – Robbert
    Apr 7, 2014 at 13:45
  • @G.M. I made all the improvements (see my edited question), but when I click on submit, still nothing happens..
    – Robbert
    Apr 8, 2014 at 7:47
  • stn_voting is a string, you have to wrap into quotes, it should be action: "stn_voting" and not action: stn_voting also do not forget no-conflict wrappers: jQuery(document).ready(function($) { on first line and then you can use $ in the rest of the code.
    – gmazzap
    Apr 8, 2014 at 12:55

2 Answers 2

2

Couple of things:

1: When you include the script after jquery, localise it using the wp_localize_script function:

$nonce = wp_create_nonce("vote_nonce");
$yourscript_info = array(
    'ajaxurl' => admin_url( 'admin-ajax.php'),
    'nonce' => $nonce
);
wp_localize_script( 'yourscript', 'yourscript', $yourscript_info );

$.ajax({
    type: "POST",
    url: yourscript.ajaxurl,
    data: { id: id, vote: vote, nonce: yourscript.nonce, action: "stn_voting" },

2: Add some security checks using a nonce:

function ajax_stn_voting() {
    //simple Security check
    if ( ! wp_verify_nonce( $_POST['nonce'], 'vote_nonce' ) )
        die ( 'Busted!');

3: You don't need to include the post id in the meta keys. Its already attached to the post, so its already stored in the database.

$key = 'vote_up';
instead of
$key = 'vote_up_' . $post->ID;

Not just the vote_up key, but all of the _' . $post->ID; part is unnecessary inside the function. If all of your keys are different, you can't order the posts based on these values and its simply an unnecessary thing to do.

4: You need to "die" at the end of the function when you're using ajax:

    die();
}
add_action('wp_ajax_stn_voting', 'ajax_stn_voting');
add_action('wp_ajax_nopriv_stn_voting', 'ajax_stn_voting');

Otherwise, the script looks good to me.

And what G. M. said in the comments above:)

4
  • Thanks for you answer. The _' . $post->ID; is because I made a special voting system, where only some posts have votes with other posts. So I need to save a meta value for a specific post ID.
    – Robbert
    Apr 7, 2014 at 13:39
  • To be honest, i'm not sure what you mean by this, but if this is necessary, you need to pass the current post id too, not just the $vote_id in the ajax request, because the global $post variable is not in the wp_ajax function.
    – passatgt
    Apr 7, 2014 at 13:41
  • Oh that's a good one! I am gonna try your solutions.
    – Robbert
    Apr 7, 2014 at 13:44
  • I made all the improvements (see my edited question), but when I click on submit, still nothing happens..
    – Robbert
    Apr 8, 2014 at 7:47
0

Your custom script uses $'s and thus does not account for "noConflict" mode.

Use a proper no-conflict wrapper, or simply replace "$" with "jQuery" everywhere.

More info: http://codex.wordpress.org/Function_Reference/wp_enqueue_script#jQuery_noConflict_Wrappers

The $ shortcut is not valid in all contexts. You need to stop using it when possible, or define it specifically using a wrapper as described in that link.

1
  • I have changed that, but my code still doesn't work correct.
    – Robbert
    Apr 8, 2014 at 12:05

Your Answer

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

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