Update ACF field using AJAX in WordPress front end

Recently I was asked to build a very simple tracker where I could just track the number of times a download button was clicked on the WordPress front end. Since we predominately use the ACF PRO plugin (Advanced Custom Fields) I thought we can use this to create the field and record the number of clicks. So let’s get started with this simple fun WordPress Tutorial.

Upon further research, I realized I needed to make use of AJAX which is now shipped natively in WordPress, and also track the IP address since the button click had no predefined qualifiers to prevent the same user from clicking the button a 1000 times in a short span of time. Yes if the IP changes it will record as another click, but IPs via VPNs might not change that often. As mentioned in the title this is just a simple way of tracking the button clicks.

AJAX in WordPress is easy to use
AJAX is shipped natively in WordPress

Step 1: We need to set up the options page

For this example, we’re going to set up the tracking variables on an options page and then assign a field variable to that page. Use the following code in the functions.php, you should.

if( function_exists('acf_add_options_page') ) {


  'page_title' 	=> 'Theme Settings',
  'menu_title' 	=> 'Theme Settings',
  'menu_slug' 	=> 'theme-general-settings',
  'capability' 	=> 'edit_posts',
  'redirect' 	=> false,
  'parent_slug' => 'options-general.php'



Now see a blank options page under the Dashboard > Settings tab called “Theme Settings”

Step 2: We create a custom fileds and assign it to appear on the options page

We create 2 custom fields in a new field group called “Theme Settings”

And don’t forget to set it to only show this field group on the options page called “Theme settings” that you just set up in step 1.

Now create 2 fields and take note of the meta key you will find alongside each key name, these key names are going to come in very handy when you are writing your filter hooks later on.

WordPress key
WordPress Key
  1. download count (numbers field)
  2. user (repeater field)
    1. ip (set as a text field but this is what we use to capture the user IP)

Step 3: Now let’s set up the code that is going to generate the users IP address

This code should be placed in the functions.php file

function GetIP()
        if (array_key_exists($key, $_SERVER) === true)
            foreach (array_map('trim', explode(',', $_SERVER[$key])) as $ip)
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false)
                    return $ip;

Step 4: Set up the action that will be triggered by AJAX in WordPress

add_action( 'wp_ajax_nopriv_my_ajax_action', 'my_ajax_action' ); 

// This lines it's because we are using AJAX on the FrontEnd.
add_action( 'wp_ajax_my_ajax_action', 'my_ajax_action' );

function my_ajax_action(){

  // input the number of times the button has already been clicked
  $count     = (int)get_field('[your download count key]','option');
  // get the user IP
  $user_ip   = GetIP();
  // add one to the existing count

  // Update with new value.

  //checking to see if there are any repeater rows that exist

  if(have_rows('[your repeater row key]','option') ){
    //cycling through all the reapter field rows
    while( have_rows('[your repeater row key]','option') ){
        //copare the stored and new IP addresses and set found boolian

        if(ip2long(get_sub_field('ip')) == ip2long($user_ip) ){
          $found = TRUE;

          $found = FALSE;
          $row_index = get_row_index();




    // if boolian was not found add the new count to the count key field
    // and add a new row to the repeater key field 

      $row = array(
        "ip"   => $user_ip

      update_field( '[your download count key]',$count, 'option' );
      add_row('[your repeater row key]', $row, 'option');



Step 5: Set up the jQuery script to trigger the my_ajax_action() we just set up.

(function ($) {

        // call action when the download button is clicked
	$(".download").click(function (e) {

			url: '[your website url]/wp-admin/admin-ajax.php',
			type: "POST",
			data: {
				action : 'my_ajax_action',
			success: function (html) {
				//alert('Ajax TWICE')



Bonus step:

And finally, if you want to seal off the download count variable so nobody will be able to go into it and skew the data use the following filter in your functions.php file.

//make field read only
add_filter('acf/load_field/key=[your download count key]', 'acf_read_only');
function acf_read_only( $field ) {
    $field['readonly'] = 1;
    $field['disabled'] = true;
return $field;

We hope you enjoyed that. If you have a better way of doing this we would love to hear from you about it.

Toffy Co provides Melbourne WordPress designs services, please get in touch with us for all your WordPress design and development needs.