最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to link Wordpress heartbeat to ajax form

programmeradmin0浏览0评论

I have a form that $_POSTs an input value, and user's ID that saves the data to the database:

// frontend form 
<form id="form">
    <input type="radio" name="location" id="name1" value="1">
    <label for="name1">Label 1</label>

    <input type="radio" name="location" id="name2" value="2">
    <label for="name2">Label 2</label>

    <input type="radio" name="location" id="name3" value="3">
    <label for="name3">Label 3</label>

    <input type="hidden" name="userid" value="{userid}">
</form>     


// footer script
<script>
$(function() {
    $( "#form" ).change(function(a) {
        a.preventDefault();
        var formdata = new FormData($(this)[0]);

        $.ajax({
            method:         "POST",
            data:           formdata,
            contentType:    false,
            processData:    false
        });
    });
});
</script>


// validation snippet
<?php
    $location = isset( $_POST['location'] ) ? $_POST['location'] : '';
    $userID   = isset( $_POST['userid']   ) ? $_POST['userid']   : '';
    update_user_meta( $userID, 'location_current',  $location );
?>

When the users sets the radio location from their desktop, it send the form to the server, and saves it.

Each user also has a display (tablet) that has no input but echoes out the location value.

I currently have the tablet refreshing every 5 minutes, but wanted it to be more of a push with WP heartbeat.

I tried using this example:

But wasnt sure how to have the value of the data['client'] = 'marco'; be data['client'] = '<?= $_POST['location']; ?>'; each time as it is printed once and not refreshed once the page is loaded or the location changed.

I have a form that $_POSTs an input value, and user's ID that saves the data to the database:

// frontend form 
<form id="form">
    <input type="radio" name="location" id="name1" value="1">
    <label for="name1">Label 1</label>

    <input type="radio" name="location" id="name2" value="2">
    <label for="name2">Label 2</label>

    <input type="radio" name="location" id="name3" value="3">
    <label for="name3">Label 3</label>

    <input type="hidden" name="userid" value="{userid}">
</form>     


// footer script
<script>
$(function() {
    $( "#form" ).change(function(a) {
        a.preventDefault();
        var formdata = new FormData($(this)[0]);

        $.ajax({
            method:         "POST",
            data:           formdata,
            contentType:    false,
            processData:    false
        });
    });
});
</script>


// validation snippet
<?php
    $location = isset( $_POST['location'] ) ? $_POST['location'] : '';
    $userID   = isset( $_POST['userid']   ) ? $_POST['userid']   : '';
    update_user_meta( $userID, 'location_current',  $location );
?>

When the users sets the radio location from their desktop, it send the form to the server, and saves it.

Each user also has a display (tablet) that has no input but echoes out the location value.

I currently have the tablet refreshing every 5 minutes, but wanted it to be more of a push with WP heartbeat.

I tried using this example: https://gist.github/strangerstudios/5888123

But wasnt sure how to have the value of the data['client'] = 'marco'; be data['client'] = '<?= $_POST['location']; ?>'; each time as it is printed once and not refreshed once the page is loaded or the location changed.

Share Improve this question edited Apr 22, 2019 at 23:39 markb asked Apr 12, 2019 at 5:14 markbmarkb 2996 silver badges18 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3 +50

Saving data

Based on Heartbeat API, you can add custom data to the sent heartbeat on heartbeat-send event in js. This would be used instead of the ajax function you have in your code example.

jQuery( document ).on( 'heartbeat-send', function ( event, data ) {
  // Grab the required form data
  data.location = jQuery('input[name="location"]:checked').val();
  data.userid = jQuery('input[name="userid"]').val();
});

You can then use the data in PHP with hearbeat_recieved filter. There's also the heartbeat_nopriv_received filter for no-privilege environments.

add_filter( 'heartbeat_received', 'myplugin_save_location_on_heartbeat', 10, 2 );
function myplugin_save_location_on_heartbeat( $response, $data ) {
  // data required
  if ( empty( $data['location'] ) || empty( $data['userid'] ) ) {
    return $response;
  }
  // validate
  if ( ! is_numeric( $data['location'] ) || ! is_numeric( $data['userid'] ) ) {
    return $response;
  }
  // sanitize
  $location = absint( $data['location'] );
  $userID = absint( $data['userid'] );
  // update
  update_user_meta( $userID, 'location_current',  $location );
  // optional response
  $send_data_back = true;
  if ( $send_data_back ) {
    $response['location'] = $location;
    $response['userid'] = $userID;
  }
  // send response
  return $response;
}

You can access the data (response from hearbeat_recieved) again on heartbeat-tick event in js,

jQuery( document ).on( 'heartbeat-tick', function ( event, data ) {
  // Check for our data, and use it.
  if ( ! data.location || ! data.userid ) {
    return;
  }
  // use the response as needed
  console.log("location: " + data.location);
  console.log("user: " + data.userid);
});

Get data

With couple of tweaks you can get just the location data instead of saving it.

First send user id with heartbeat-send in js,

jQuery( document ).on( 'heartbeat-send', function ( event, data ) {
  data.userid = jQuery('input[name="userid"]').val();
});

Then respond with current location user meta in PHP on hearbeat_recieved,

add_filter( 'heartbeat_received', 'myplugin_get_location_on_heartbeat', 10, 2 );
function myplugin_get_location_on_heartbeat( $response, $data ) {
  // data required
  if ( empty( $data['userid'] ) ) {
    return $response;
  }
  // validate
  if ( ! is_numeric( $data['userid'] ) ) {
    return $response;
  }
  // sanitize
  $userID = absint( $data['userid'] );
  // update
  $location = get_user_meta( $userID, 'location_current',  true );
  // send response
  return $response['location'] = $location;
}

EDIT 1: I think you could also use get_current_user_id() inside the php response function to get the user id, if you don't want to or can't send it in js on heartbeat-send event.

Last, update your view with the recieved data on heartbeat-tick in js,

jQuery( document ).on( 'heartbeat-tick', function ( event, data ) {
  // Check for our data, and use it.
  if ( ! data.location ) {
    return;
  }
  // if using radio buttons
  jQuery('input[name="location"][value='"+data.location+"']').prop('checked', true);
  // if you want to show result in somewhere else
  jQuery('#location-output-element').text(data.location);
});

I hope this helps and answers your question.

To send value using HTTP methods, the page must submit data. Only page refresh will not work. Your page must send a post request with the data location and you are using ajax to send form data.

In the API data['client'] = 'marco'; you can use your own data object send from your ajax request.

data['client'] = your formdata;

or you can use your PHP code same as you mentioned above:

data['client'] = '<?php echo $_POST['location']; ?>'; // make sure you validate data first.

If this doesn't help, please show the full implementation of API and usage of your ajax data.

发布评论

评论列表(0)

  1. 暂无评论