Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am trying to create button click counter meta box in a custom post type, but I can't get it to work. What I want to do is when a user click the submit button, then it will do update_post_meta in the background and display the value on the current screen by echo get_post_meta with ajax.

Here is my codes so far:

Hooks the metabox function

add_action('add_meta_boxes', 'add_custom_categories_box');

Add metabox function

function add_custom_categories_box() {  
 add_meta_box(
        'wpse_54822_sectionid',
        __( 'Page Attachments' ), 
        'wpse_54822_inner_custom_box',
        'indtablea', 'normal'
    );
} 

Meta box

function wpse_54822_inner_custom_box(){
?>
<script>
jQuery(document).ready(function($){

$('#target').click(function() {
    $('#output').html(function(i, val) { return val*1+1 });
});

$('.submitmeplease').on('click', function(e){
e.preventDefault();
    $('#counter').html(function(i, val) {
        $.post({
            url: ajaxurl,
            action:"ak_attach",
            type: 'POST',
            data: {increment: true},
            success: function() { alert('Request has returned') }
        });
        return +val+1;
});
});
});
</script>
<?php
?>
<button id="target" type="button">Click Me</button>
<div id="output">10</div>

<div id="#counter">1</div>
<input type="submit" name="submit" class="submitmeplease" value="Submit" />
<?php
}

Ajax Response

 // Response to ajax script
function ajaxResponse($post){  
$data = $_POST['submit'];
update_post_meta($post_ID, 'my_key', $data);
 }  
add_action('wp_ajax_ak_attach', 'ajaxResponse');

I can't figure out what is the string of the variable $data in the ajaxResponse function should be.

Could somebody walking me through on creating that button click counter in metabox?

Please help me..

share|improve this question
add comment

3 Answers 3

First of all output your javascript in like this is a worse practice. So it's a lot better if you create your javascript file and the enqueue it using wp_enqueue_script hooked admin_enqueue_scripts action.

function enqueue_my_ajax( $hook ) {
    if( 'post.php' != $hook && 'post-new.php' != $hook ) return;
    // if you use in theme use get_template_directori_uri to retrieve the url
    wp_enqueue_script( 'my_ajax_script', plugins_url('/my_ajax_script.js', __FILE__) );
}
add_action( 'admin_enqueue_scripts', 'enqueue_my_ajax' );

Second, when you use metabox and ajax is always a good idea use nonces. You can use wp_nonce_field to create an hidden nonce input in the metabox and the retrieve the value and post with ajax.

Check in Codex for the functions named above for more info.

Regarding the problem, the post Id should be passed via ajax, or ajaxResponse cannot make use of it.

So the function that display your metabox should be:

function wpse_54822_inner_custom_box( $post ) {
  $current_count = get_post_meta($post->ID, '_increment_key', true) ? : 1;
  wp_nonce_field( 'increment_my_count', '_nonce_count' );
?>

<input type="hidden" id="_count" name="_count" value="<?php echo $current_count ? : 1; ?>" />
<input type="hidden" id="_postid" name="_postid" value="<?php echo $post->ID; ?>" />
<div id="counter"><?php printf( 'Current Count: %d', $current_count ); ?></div>
<input type="button" name="button" class="button button-primary submitmeplease" value="<?php _e('Update'); ?>" />

<?php } ?>

Your javascript (in the my_ajax_script.js file enqueued as above) should be:

jQuery(document).ready(function($){
  $('.submitmeplease').on('click', function(e){
    e.preventDefault();
    var nonce = $('input[name="_nonce_count"]').val();
    var count = $('#_count').val();
    var id = $('#_postid').val();
    $.ajax({
      url: ajaxurl,
      type: 'POST',
      data: { _nonce_count: nonce, action: 'update_my_count', _count: count, postid: id },
      success: function( data ) {
        if (data != '' && data != '0')
          $('#_count').val( data );
          $('#counter').html('Current Count: ' + data)
        }
    });
  });
});

Your myUpdateCount function shoud be:

function myUpdateCount() {
  if ( ! check_admin_referer( 'increment_my_count', '_nonce_count' ) ) die();
  $postid = isset( $_POST['postid'] ) && $_POST['postid'] ? $_POST['postid'] : null;
  if ( ! $postid ) die();
  if ( ! current_user_can('edit_posts', $postid) ) die();
  $new_count = isset( $_POST['_count'] ) && $_POST['_count'] ? $_POST['_count'] + 1 : 1;
  update_post_meta($postid, '_increment_key', $new_count);
  die( (string)$new_count );
}

add_action('wp_ajax_update_my_count', 'myUpdateCount');
share|improve this answer
    
Hey.., Thank you very much, but I can't get it to update the database. Is there something I need to do to make it work? I had doing correction in this '$postid' to this '$post->ID' in 'get_post_meta($postid, 'increment_key', true);', since it's return error message. –  Ari Susanto Aug 29 '13 at 3:57
    
I did, but I get this notice: "Notice: Undefined variable: postid in C:\xampp\htdocs\wordpress\wp-content\plugins\simpleajax\simpleajax.php on line 78" –  Ari Susanto Aug 29 '13 at 8:58
    
Ok, my bad. You made correction in wpse_54822_inner_custom_box function, I was looking at ajaxResponse function. In wpse_54822_inner_custom_box you have to use $post->ID (I've corrected the code in answer) @AriSusanto –  G. M. Aug 29 '13 at 9:46
    
@AriSusanto, I tested my code and there was some typos and bugs. Now I've corrected and it works. –  G. M. Aug 29 '13 at 10:50
add comment

Basically an ajax call within WordPress looks like this:

The jQuery / JS script:

jQuery.ajax({
  url: ajaxurl, // the URL where the data are submitted
  type: 'POST'  // the METHOD on how the data are submitted
  action: 'myaction', // the ACTION called to process the data
  data: { // the DATA sent to the server 
    submit: 'somevalue',
    postid: $('#postid').val() // You can store the post ID value in an hidden input text field within the function you use to diplay the content of your metabox.
  },
  success: function(data){
    //Do something with the DATA pushed from server
    console.log( data );
  }
});

The server side

// functions.php
add_action( 'wp_ajax_myaction', 'wpcf_process_data' );
function wpcf_process_data(){

  //I'm sending data via POST method so i look for this data in $_POST variable
  $submit = isset( $_POST['submit'] ) ? $_POST['submit'] : false;
  $postid =  isset( $_POST['postid'] ) ? $_POST['postid'] : false;   

  //Do something with the data, for example update post meta
  $update = update_post_meta( $postid, 'mykey', $submit )

  //echo the result, in order to send it to the ajax call. we know that if update_post_meta creates a new record, it returns the meta_id, if you update a value, it returns true and false on failure. in other words this the data pushed from the server.
  echo $update;

  //Every ajax call must die.. i know sounds creepy, but it has to be done
  die();
}

Hope it helps.

share|improve this answer
1  
Sorry, but how the global $post variable can be setted in top of an ajax request? And how it should be linked to the post which send the request? Remember than ajax request is a completely new http request with no status mantaining from the page that send and the page that receive. –  G. M. Aug 28 '13 at 18:37
    
@G.M. Yes, it's true. I'm going to update the answer. Thank you –  iEmanuele Aug 28 '13 at 18:46
add comment

Here is what I do to achieve it! Hope this will be helpful for anyone who find it useful. This example works perfectly in my local server. I am not creating the nonce for security yet, though. So you need to find how to add the nonce if you want to use it on your live site.

Meta Box Hook

add_action('add_meta_boxes', 'add_custom_categories_box');

function add_custom_categories_box() {  
 add_meta_box(
        'wpse_54822_sectionid',
        __( 'Page Attachments' ), 
        'wpse_54822_inner_custom_box',
        'indtablea', 'normal'
    );
}  

Metabox Form

function wpse_54822_inner_custom_box(){
global $post;
echo get_post_meta($post->ID, 'my_key', true); // Show result

//You need to give your form fields class name or id to connect them with jQuery.    
?>
    <br/>
    <button id="target" type="button">Click Me</button>
    <input type="text" name="submit" class="submitme" value="" placeholder="columns" />
    <input type="text" name="posid" class="posid" value="<?php echo $post->ID; ?>" />
    <?php
    }

Register and Enqueue The jQuery To Administration Screen

I use traditional way to include the script to administration screen.

function enqueue_my_ajax( $hook ) {

    wp_register_script( 'my_ajax_script', plugins_url('/simpleajax/my_ajax_script.js') );
    wp_enqueue_script('my_ajax_script');
}
add_action( 'admin_enqueue_scripts', 'enqueue_my_ajax' );

Ajax Response

add_action('wp_ajax_my_action', 'my_action_callback');

function my_action_callback($post_id) {
    global $post;
    $post_id = $post['ID'];
    global $wpdb; // this is how you get access to the database
    $whatever = intval( $_POST['whatever'] );
    $whatever += 10;
    $potid = $_POST['postid']; // get this string's name and value from jQUery
        $subamit = $_POST['submit']; // get this string's name and value from jQuery 
        $subamit += 1; // plus 1 the value so the submitted data equal to the number of cliks.
    $update = update_post_meta($potid, 'my_key', $subamit); // Let's execute the data to our wordpress' database.

      echo $potid;
      echo $whatever;

    die(); // this is required to return a proper result
}

jQuery Ajax This is the my_ajax_script.js file.

jQuery(document).ready(function($){

$('#target').click(function(e) {
    var m = $('.submitme').val(); //get value of input field with class name "submitme"
    var pid = $('.posid').val(); //get value of input field with class name "posid"
    var sbmit = $('.submitme').val();
    $('.submitme').val(m*1+1); // Increment the input field's value named "submitme"        
    var data = {
        action: 'my_action', // Put this action name after wp_ajax hook  
        whatever: 1234,
        postid: pid, // get the post id to included in update_post_meta
        submit: sbmit // get the value to be submitted.
    };

    $.post(ajaxurl, data, function(response) { // do the ajax
//Display the success response here if you want to do it!
    });
});

});

Useful External Referrences:

Ajax in Wordpress Plugin http://codex.wordpress.org/AJAX_in_Plugins

jQUeryajax API documentation http://api.jquery.com/jQuery.ajax/

jQuery API documentation http://api.jquery.com/

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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