I have a form that $_POST
s 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.com/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.
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.