Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@androsland
Last active April 21, 2023 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save androsland/86e55e38d8d04d4afb3f043c876c0f55 to your computer and use it in GitHub Desktop.
Save androsland/86e55e38d8d04d4afb3f043c876c0f55 to your computer and use it in GitHub Desktop.
jQuery AJAX request to WordPress API
(function ($) {
$(function () {
// On form submit
$("#my-form").on("submit", function (e) {
e.preventDefault();
form = $(this);
var endpoint = form.data("endpoint");
// Optional: add loading class to the form
loadingClass = "form-component__form--loading";
form.addClass(loadingClass);
$(".form__row-item-inner.error").removeClass("error");
$(".error-message").remove();
var form = $(this);
var formData = new FormData();
// Include the nonce with the data
formData.append("_my_nonce", sqfinAjax.nonce);
form.serializeArray().forEach((element) => {
formData.append(element.name, element.value);
});
settings = {
url: `${sqfinAjax.resturl}namespace/v1/${endpoint}`,
type: "POST",
data: formData,
dataType: "json",
// You need the following for the call to work as json
processData: false,
contentType: false,
// The correct way to send the nonce to the call
beforeSend: function (xhr) {
xhr.setRequestHeader("X-WP-Nonce", sqfinAjax.nonce);
},
// callback for successful response. Note that wp_send_json($respond, 200) is always successful, even if the curl resulted in an error
success: function(data){
if (data.errors) {
// loop through the errors and add an error class and message to the potential fields (if supported by the API)
for (const error of Object.keys(data.errors)) {
$(`.form__row-item #${error}`)
.closest(".form__row-item-inner")
.addClass("error");
$(`.form__row-item #${error}`)
.closest(".form__row-item")
.append(`<div class='error-message'>${data.errors[error]}</div>`);
}
} else {
// bonus: fire a sweetalert2 instead of a traditional modal
Swal.fire({
icon: "success",
html: "Registration successful<br> We are creating your account...",
showConfirmButton: false,
});
}
// Remove the loading class from the form
$(".form-component__form").removeClass(loadingClass);
},
// callback for erronius response. Something real bad happened here better catch it than wondering what might have happened
error: function(data){
$(".form-component__form").removeClass(loadingClass);
// bonus: fire a sweetalert2 instead of a traditional modal
Swal.fire({
icon: "error",
title: formModals.error.title,
text: formModals.error.message,
});
},
};
$.ajax(settings);
});
});
})(jQuery);
<?php
/**
* Register custom endpoints
*/
add_action('rest_api_init', 'register_custom_api_endpoints');
function register_custom_api_endpoints()
{
// wp-json/namespace/v1/my_callback
register_rest_route('namespace/v1', '/path', array(
'methods' => 'POST',
'callback' => 'my_callback',
'permission_callback' => '__return_true',
));
}
/**
* Register client endpoint
*/
function register_client(WP_REST_Request $request)
{
if (
isset($_sqfin_nonce)
&& !wp_verify_nonce($_sqfin_nonce, "wp_rest")
) {
die("Rest API nonce verification failed");
}
// API endpoint URL
$base_url = "https://api-endpoint.url";
// Custom headers if needed
$token = "potential-token";
$headers = array(
"Content-Type: application/json",
"Authorization: Bearer {$token}",
);
$data = $request->get_params();
// Make each array key a variable
// e.g. $data['firstName'] => $firstName
extract($data);
// Any custom modification to the data before being sent to the API
$first_name .= " halloumia na faeis";
// Prepare an array with all the data you want to send
// Make sure you filter them to avoid any XSS attacks
$postData = array(
"firstName" => filter_var($firstName, FILTER_SANITIZE_FULL_SPECIAL_CHARS),
"lastName" => filter_var($lastName, FILTER_SANITIZE_FULL_SPECIAL_CHARS),
"country" => filter_var($country, FILTER_SANITIZE_FULL_SPECIAL_CHARS),
"phone" => filter_var($fullPhone, FILTER_SANITIZE_FULL_SPECIAL_CHARS),
"email" => filter_var($email, FILTER_SANITIZE_EMAIL),
);
// Prepare the call to the API
$ch = curl_init($url);
// Setup the headers. This should be fine
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
// Execute the call
$result = curl_exec($ch);
// Make sure you close the curl
curl_close($ch);
// Convert the result to an array for better readability
$res = json_decode($result, true);
// Initialize the response
$response = [];
// Check for errors or make any modifications
if (isset($res['errors'])) {
$respond['code'] = $res['code'];
$respond['message'] = $res['message'];
// send the response as json
wp_send_json($respond, 200);
}
$response['code'] = 200;
$response['message'] = "success";
wp_send_json($rl_respond, 200);
}
/**
* In a wp_enqueue_scripts action, register the script that will do the ajax call
* localize some variables like nonce and enqueue it
*/
add_action('wp_enqueue_scripts', 'ajax_register_scripts');
function ajax_register_scripts()
{
// if your script is not working, check if you have wp_dequeue_script('jquery') somewhere.
// if the dependancies are missing, your script will not be enqueued
wp_register_script('ajax-script', get_stylesheet_directory_uri() . "/path/to/the/script/ajax-script.js", array('jquery'), $version, true);
// myAjax will be available in the script
// some useful variables
wp_localize_script('ajax-script', 'myAjax', [
'ajaxurl' => admin_url('admin-ajax.php'),
'resturl' => esc_url_raw(rest_url()),
'nonce' => wp_create_nonce('wp_rest'),
]);
wp_enqueue_script('ajax-script');
}
/**
* The form markup
* data-type: The path of our custom api endpoint
*/
?>
<form id="my-form" class="form-component__form" data-endpoint="path" method="post">
<div class="form__inner">
<div class="form__header">
<h2><?= __('Register now', 'sqf-website'); ?></h2>
</div>
<div class="form__content">
<div class="form__row form__row--full">
<div class="form__row-item form-field form-field--input input--text">
<div class="form__row-item-inner">
<input type="text" id="firstName" name="firstName" placeholder="<?= __('First name', 'domain'); ?>" required="required">
</div>
</div>
</div>
<div class="form__row form__row--full">
<div class="form__row-item form-field form-field--input input--text">
<div class="form__row-item-inner">
<input type="text" id="lastName" name="lastName" placeholder="<?= __('Last name', 'domain'); ?>" required="required">
</div>
</div>
</div>
<div class="form__row form__row--full">
<div class="form__row-item form-field form-field--input input--submit">
<div class="form__row-item-inner">
<input type="submit" name="submit" class="btn btn--primary" value="<?= __('Submit', 'domain'); ?>">
</div>
</div>
</div>
</div>
</form>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment