I have a form that allows the user to change their account info. I added ajax requests to save changes without page refresh. My problem is that I don’t want to submit all the fields on the form because some are disabled. So I just want to send some fields. To do this I wrote the code below which is not working, can someone help me figure out what am I wrong ?
Functions.php
// Validate - my account
add_action( 'woocommerce_save_account_details_errors', array( &$errors, &$user ), 1, 10 );
add_action( 'wp_ajax_save_account_details', 'save_account_details' );
function save_account_details( $user_id ) {
if (trim($_POST['account_first_name']) == '') {
$response = wc_print_notices();
} else if ( isset( $_POST['account_first_name'] ) ) {
$response = wc_print_notices();
}
echo json_encode($response);
exit();
}
My form
<form name="Form" class="mts-edit-account" action="<?php echo admin_url('admin-ajax.php'); ?>" method="post" enctype="multipart/form-data" <?php add_action( 'woocommerce_edit_account_form_tag', 'action_woocommerce_edit_account_form_tag' );?> >
<!-- Message section -->
<div class="msg_box"></div>
<!-- Fist & Last Name Field -->
<div class="row name_surname">
<div class="form-row">
<label class="t3" for="account_first_name">Nome *</label>
<input type="text" placeholder="Inserisci il tuo nome" class="field-settings" name="account_first_name" id="account_first_name" value="<?php echo esc_attr( $user->first_name ); ?>" />
</div>
<div class="form-row">
<label class="t3" for="account_last_name">Cognome *</label>
<input type="text" placeholder="Inserisci il tuo cognome" class="field-settings" name="account_last_name" id="account_last_name" value="<?php echo esc_attr( $user->last_name ); ?>" />
</div>
<!-- Save Settings -->
<p style="margin-bottom: 0px!important;">
<?php wp_nonce_field( 'save_account_details', 'save-account-details-nonce' ); ?>
<button type="submit" class="edit-account-button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>"><?php esc_html_e( 'Salva modifiche', 'woocommerce' ); ?></button>
<input type="hidden" name="action" value="save_account_details" />
</p>
</div>
</form>
Js Code
This is what I am doing to send only specific fields but it doesn’t work. When click on submit button nothing happens, there is no ajax request.
jQuery(document).ready(function($) {
$('.mts-edit-account').on('submit', function(e) {
e.preventDefault();
// Specific form field
var $formData = {
name: $("#account_first_name").val(),
lastName: $("#account_last_name").val()
};
//Ajax Save settings
jQuery.ajax({
dataType: "json",
type: "POST",
data: formData,
success: function(data) {
jQuery('.newdiv').html(data);
}
});
});
});
This instead is Js code that sends all fields of the form and works correctly.
jQuery(document).ready(function($) {
$('.mts-edit-account').on('submit', function(e) {
e.preventDefault();
//Ajax Save settings
jQuery.ajax({
type: "POST",
data: jQuery(".mts-edit-account").serialize(),
success: function(data) {
jQuery('.newdiv').html(data);
}
});
});
});
3
Answers
You’re missing a lot of this here.
admin-ajax.php
based url that will be used inurl
args, which is missing.action
key and value in form data, that is missing in your code.dataType: 'json'
which means you’re expecting json from your ajax response but in the success function, you’re trying to write json object into html div, so it’s unclear what you’re actually sending in your response. you need to work here, if you’re sending html code in response thendataType: 'html'
will be used if you’re sending json then you need to changehtml(data)
tohtml(JSON.stringify(data)
So after correcting all those things your code should be like this, I have provided all the possible explanations so that you could understand what I have done and changed in the code.
NOTE: I have not tested the code so if you see any error in console, please let me know so that I could update and fix the code
Coming to your PHP code for handling ajax.
add_action( 'woocommerce_save_account_details_errors', array( &$errors, &$user ), 1, 10 );
I am not sure what you’re added to this line, doesn’t make any sense when you have your own ajax handling function. remove this line.
Then you can’t use
wc_print_notices()
you’ll have to write your own validation and error handling. In able to usewc_print_notices()
, you need a deep understanding of WooCommerce.Also, you’re missing validation, nonce checking, sanitization, and many more things. You need to learn so much about these things. Below I have prepared the php code and tried to explain basics, but if you want to learn about those function and their usage you need to search each function on the internet or in WordPress documentation and learn about those. it’s hard to explain and teach all those functions and how they work, in detail.
Note: You should always use a prefix for your global function names to avoid conflict and keep the function name unique. I have changed
save_account_details
tovh_sto_wc_custom_save_account_details
to make it unique. However, your nonce action name is stillsave_account_details
you can change it and make it unique in all the required places laterHere is the php code for handling the ajax callback.
Well, to submit some fields and not the others you simply select them and send them in the ajax body, something like this.
and inside the ajax you do this
You are pulling the data in your PHP function differently to what is being submitted.
You have defined in javascript that
name
=account_first_name
. So your php function is looking for the$POST
'account_first_name'
field and you are giving itname
.So change your ajax request to:
and now the PHP function is getting the correct field.