Failed ajax call within wordpress - javascript

I previously had help here making a generic Ajax function for some checkboxes. I am now trying to integrate that project into a Wordpress site and having a few issues.
Here is my current code:
<label class="rep_label"><input type="checkbox" id="goal1<?php get_current_user_id() ?>" name="GOAL_1_HIT" value="1" <?php if($rep_goal1_hit == 'YES'){echo "checked";}?> />
<?php echo $rep_goal1; ?></label>
<br />
<label class="rep_label"><input type="checkbox" id="goal2<?php echo get_current_user_id() ?>" name="GOAL_2_HIT" value="1" <?php if($rep_goal2_hit == 'YES'){echo "checked";}?> />
<?php echo $rep_goal2; ?></label>
<br />
<label class="rep_label"><input type="checkbox" id="goal3<?php echo get_current_user_id() ?>" name="GOAL_3_HIT" value="1" <?php if($rep_goal3_hit == 'YES'){echo "checked";}?> />
<?php echo $rep_goal3; ?></label>
<br />
<label class="rep_label"><input type="checkbox" id="incentive<?php echo get_current_user_id() ?>" name="INCENTIVE_HIT" value="1" <?php if($rep_incentive_hit == 'YES'){echo "checked";}?> />
<?php echo $rep_incentive; ?></label>
JS/Ajax
jQuery(document).ready(function($) {
$("input[type=checkbox]").change(function() {
var $input = $(this);
$.ajax({
url: 'checkbox.php',
type: 'POST',
data: { db_column:$input.attr("name"), strState:$input.is(":checked"), user:"<?php echo $current_user->ID; ?>" },
success: function() { // this happens after we get results
$input.attr('checked', true);
},
error:function(){
$input.attr('checked', false);
}
});
});
});
PHP
<?php
$db_column = $_POST['db_column'];
$strState = $_POST['strState'];
$user = $_POST['user'];
if(set_cimyFieldValue('$user', '$db_column', '$strState')){
echo "ok";
} else {
echo "error";
}
?>
I am getting an "unexpected end of input" error on my javascript that I've googled endlessly to no avail.
I had the script within the html and the Ajax call wasn't even being triggered so I moved it to a .js file and included it in the same spot and now the ajax call goes, but returns a 404 on the php file.
This is only the tip of the iceberg of Ajax I'm going to have to implement. What general considerations do I need to be aware of using my own Ajax functions within Wordpress?
If anyone is familiar with Cimy Extra User Fields, I am merely trying to make an ajax driven front end for the fields provided from that plugin. I think I have problem trying to use a plugin function in my php file...

data: ({ db_column:$input.attr("name"), strState:$input.is(":checked"), user:"<?php echo $current_user->ID; ?>" })

Related

How to submit ajax form in wordpress (getting error 400)

I am building my personal website based on wordpress / woocomerce. I am currently working on a form that allows users to change their account information such as name, surname and much more. Everything seems to be working fine.
What I'm trying to do now is make the form work with ajax requests without the need to refresh the page. I think I am on the right track but I have some small difficulties.
Currently, when the form is submitted the page is not loaded, so I have reached the goal, however the ajax request generates the error 400 and I don't understand why.
I apologize if this is a trivial question but I am new to all of this.
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' );?> >
<!-- 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>
Script
jQuery(document).ready(function($) {
$('.mts-edit-account').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
$.post($form.attr('action'), $form.serialize(), function(data) {
alert('This is data returned from the server ' + data);
}, 'json');
});
});
functions.php
add_action( 'wp_ajax_custom_action', 'save_account_details' );
add_action( 'wp_ajax_nopriv_custom_action', 'save_account_details' );
function custom_action() {
$response = array(
'error' => false,
);
if (trim($_POST['account_first_name']) == '') {
$response['error'] = true;
$response['error_message'] = 'Name is required';
exit(json_encode($response));
}
exit(json_encode($response));
}
Maybe I found a solution to submit data with the form using ajax request but I'm not sure. As I am a newbie I hope someone can correct or improve my answer below. Anyway, now the data is sent and saved correctly but I still have some problems which I list below.
After sending I get 302 (redirect) status
If one of the fields is empty the validate does not work, the form is submitted anyway, while an error message should appear.
Context:
I'm working with woocommerce, so my form belongs to the form-edit-account.php template. This allows users to change their account settings such as first name, last name and much more.
Reference:
I followed this tutorial which helped me tremendously - https://regularcoder.com/submit-form-using-ajax-in-wordpress/
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' );?> >
<!-- 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>
Script Js
jQuery(document).ready(function($) {
$('.mts-edit-account').on('submit', function(e) { //form onsubmit ecent
e.preventDefault(); // the preventDefault function stop default form action
//Ajax function
jQuery.ajax({
type: "post",
data: jQuery(".mts-edit-account").serialize(),
url: "wp-admin/admin-ajax.php",
success: function(data) {
alert('Form Inviato');
}
});
});
});
functions.php
add_action( 'wp_ajax_save_account_details', 'save_account_details' );
add_action( 'wp_ajax_nopriv_save_account_details', 'save_account_details' );
function save_account_details() {
// A default response holder, which will have data for sending back to our js file
$response = array(
'error' => false,
);
// Example for creating an response with error information, to know in our js file
// about the error and behave accordingly, like adding error message to the form with JS
if (trim($_POST['account_first_name']) == '') {
$response['error'] = true;
$response['error_message'] = 'Email is required';
if (trim($_POST['account_first_name']) == '') {
$response['status'] = false;
$response['message'] = 'Email is required';
}else{
$response['status'] = true;
$response['message'] = 'success';
}
// Exit here, for not processing further because of the error
echo json_encode($response);
exit();
}
// ... Do some code here, like storing inputs to the database, but don't forget to properly sanitize input data!
// Don't forget to exit at the end of processing
exit(json_encode($response));
}

Multiple Ajax Forms using Wordpress Loop

I am trying to make multiple Ajax forms work in a Wordpress loop. I have given the form and fields in each form a unique ID. I'm trying to reference each form within the javascript in order to submit the AJAX form but instead the page refreshes as if it's trying to submit the form using php. I am no expert and can't figure out how this works. The script works for an individual form as I can reference the actual form_id directly within the javascript. I want to be able to submit the form on each post within the loop without having to refresh the page. Thanks in advance for your help.
Javascript in the template that contains the loop.
<script>
var form_id = $(this).closest("form").attr('id');
form_id.validate({
highlight: function(element, errorClass, validClass) {
$(element).parent('label').addClass('errors');
},
unhighlight: function(element, errorClass, validClass) {
$(element).parent('label').removeClass('errors');
},
submitHandler: function(form) {
$.ajax({
type: "POST",
url: '<?php echo admin_url(); ?>admin-ajax.php',
data: form_id.serialize(),
beforeSend: function() {
$("input[name=submit],button", form).attr('disabled', 'disabled');
$("div.loading", form).show();
$("div.status", form).hide();
},
success: function(result) {
if (result == 1 || result == '1') {
$("div.loading", form).hide();
$("div.thanks").slideDown();
document.forms["leadForm"].reset();
} else {
$("div.loading", form).hide();
$("input[name=submit],button", form).removeAttr('disabled');
$("div.status", form).html(result).show();
}
}
});
}
});
</script>
The form within the loop.
<?php $pid = get_the_ID(); ?>
<form name="leadForm" method="post" id="leadForm-<?php echo $pid; ?>" action="#">
<div class="grid-x grid-padding-x">
<div class="medium-12 cell">
<textarea tabindex="2" rows="6" cols="30" maxlength="350" title="Please enter a message" name="message" id="message-<?php echo $pid; ?>" placeholder="Your message" ></textarea>
</div>
<div class="medium-6 cell">
<label>Full Name
<input type="text" placeholder="Full Name" class="required" autocomplete="off" name="fullname" id="fullname-<?php echo $pid; ?>" >
</label>
</div>
<div class="medium-6 cell">
<label>Email Address
<input type="email" placeholder="Email Address" class="required" autocomplete="off" name="email" id="email-<?php echo $pid; ?>" >
</label>
</div>
<div class="medium-12 cell">
<label>Phone Number
<input type="tel" placeholder="Phone Number" class="required" autocomplete="off" name="phone" id="phone-<?php echo $pid; ?>" >
</label>
</div>
<div class="medium-12 cell">
<button class="button submit radius expanded" type="submit" >Send</button>
<div class="loading" style="display:none;" >
<img src="<?php echo get_template_directory_uri(); ?>/images/progress.gif" alt="Loading..." />
</div>
<div class="status callout radius alert small" style="display:none; text-align:center;">There was an error sending your message.
</div>
<div class="thanks callout radius success small" style="display:none; text-align:center;">Thank you.
</div>
<input type="hidden" name="current_url" value="<?php echo the_permalink(); ?>" class="button" />
<input type="hidden" name="current_title" value="<?php echo the_title(); ?>" class="button" />
</div>
</div>
</form>
The php script within the Wordpress - functions.php
<?php
add_action('wp_ajax_nopriv_leadForm', 'core_leadForm');
add_action('wp_ajax_leadForm', 'core_leadForm');
function core_leadForm()
{
if (!((isset($_POST['fullname']) && !empty($_POST['fullname'])) && (isset($_POST['email']) && !empty($_POST['email'])) && (isset($_POST['phone']) && !empty($_POST['phone'])) && (isset($_POST['message']) && !empty($_POST['message'])) ))
{
echo 'Enter all fields';
}
else if (!is_email($_POST['email']))
{
echo 'Email is not valid';
}
else
{
if (function_exists('ot_get_option'))
{
//$to = ot_get_option('cont_email');
$to = 'email#website.com';
}
else
{
$to = '';
}
}
}
ob_start();
?>
<br>
<table>
<tr>
<td><b><u>CONTACT DETAILS</u></b><br>
<br></td>
<td> </td>
</tr>
<tr>
<td><b>Full Name:</b></td>
<td><?php echo $_POST['fullname'] ?></td>
</tr>
<tr>
<td><b>Phone Number:</b></td>
<td><?php echo $_POST['phone'] ?></td>
</tr>
<tr>
<td><b>Email Address:</b></td>
<td><?php echo $_POST['email'] ?></td>
</tr>
<tr>
<td><b>Link:</b></td>
<td><?php echo $_POST['current_title'] ?></td>
</tr>
<tr>
<td><b>Message:</b></td>
<td><?php echo $_POST['message'] ?></td>
</tr>
</table>
<?php
$message = ob_get_contents();
ob_end_clean();
$subject = 'NEW MESSAGE';
$headers[] = 'From: ' . $_POST["fullname"] . ' <' . $_POST["email"] . '>';
add_filter('wp_mail_content_type', 'core_html_content_type');
function core_html_content_type()
{
return 'text/html';
}
if (wp_mail($to, $subject, $message, $headers))
{
// echo "test";
echo 1;
}
else
{
echo 'Your message failed to send. Please try again.';
}
die();
?>
Hard to replicate all the issues that WP might have with your code. But it would be one of these:
this when used outside of an reference to an html object refers to window. .closest travels up the dom tree, not down, so it will not find forms within the window object. The same effect of what you want to achieve can be achieved by $('form').attr('id'), i.e. return the id of the 1st form found.
You need to ensure $ is defined before using, this is a WP quirk of using the shipped version of jquery, you substitute the word jQuery for $
I see no evidence that jQuery is loaded by the time you use it, you are also using another library, .validate, make use of $(document).ready();
Also on a side note, learn how to use the console (e.g. in chrome), you can output js here to test variables, any errors in your code will output here too.

How to get CSS on-off button value in PHP page?

Well,
I have this code which generate CSS on-off button in a php while loop:
<div class="onoffswitch">
<input type="hidden" name="hiddenID" value="<?php echo $id; ?>">
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch<?php echo $i ?>" <?php echo $status; ?>>
<label class="onoffswitch-label" for="myonoffswitch<?php echo $i; ?>">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
When the on-off button changes then I am calling a PHP page using jQuery/Ajax.
jQuery/Ajax Code:
$(document).ready(function () {
$(".onoffswitch").change(function() {
var hiddenID = $(this).find("[name='hiddenID']").val()
var status = $('.onoffswitch-checkbox').val();
$.ajax({
type: 'post',
url: 'changeInlineData.php',
data: {
'id' : hiddenID,
'status' : status,
},
dataType : 'html',
success: function ( result ) {
$('.validation_msg').html(result);
}
});
});
});
Here you can see I just pass 2 key which is id and status in a php page. Now in php page I see the id value only not status value. Everytime status key is showing 0. It's should be 0 or 1.
PHP page:
<?php
echo $id = (int) $_POST['id'];
echo $status = (int) $_POST['status'];
Can you tell me what I am doing wrong?
Update:
I see in console log network tab that is showing status:on always if I toggle the button to on or off!!
Form Data
id:2203
status:on
You have to take value of checked checkbox. Change your status var in jquery as below :
var status = $('.onoffswitch-checkbox:checked').val();

'Click' action conflict with `submit` action

So, I have the following setup with a Submit button that saves any changes.
<div class="mysite-body">
<?php do_action('mysite_pre_form_message'); ?>
<form action="" method="post" data-action="<?php echo $template; ?>">
<input type="hidden" name="user_id-<?php echo $i; ?>" id="user_id-<?php echo $i; ?>" value="<?php echo $user_id; ?>" />
<?php
if (!isset($user_id)) $user_id = 0;
$hook_args = array_merge($args, array('user_id' => $user_id, 'unique_id' => $i));
do_action('mysite_before_fields', $hook_args);
?>
<?php foreach( mysite_fields_group_by_template( $template, $args["{$template}_group"] ) as $key => $array ) { ?>
<?php if ($array) echo mysite_edit_field( $key, $array, $i, $args, $user_id ) ?>
<?php } ?>
<?php
if (!isset($user_id)) $user_id = 0;
$hook_args = array_merge($args, array('user_id' => $user_id, 'unique_id' => $i));
do_action('mysite_after_fields', $hook_args);
?>
<?php
if (!isset($user_id)) $user_id = 0;
$hook_args = array_merge($args, array('user_id' => $user_id, 'unique_id' => $i));
do_action('mysite_before_form_submit', $hook_args);
?>
<?php if ( mysite_can_delete_user($user_id) || $mysite->request_verification($user_id) || isset( $args["{$template}_button_primary"] ) || isset( $args["{$template}_button_secondary"] ) ) { ?>
<div class="mysite-field mysite-submit mysite-column" id="A">
<?php if (isset($args["{$template}_button_primary"]) ) { ?>
<input type="submit" value="<?php echo $args["{$template}_button_primary"]; ?>" class="mysite-button" />
<?php } ?>
<?php if (isset( $args["{$template}_button_mysite"] )) { ?>
<input type="button" value="<?php echo $args["{$template}_button_secondary"]; ?>" class="mysite-button secondary" data-template="<?php echo $args["{$template}_button_action"]; ?>" />
<?php } ?>
<?php if ( $mysite->request_verification($user_id) ) { ?>
<input type="button" value="<?php _e('Request Verification','mysite'); ?>" class="popup-request_verify mysite-button secondary" data-up_username="<?php echo $mysite->id_to_member($user_id); ?>" />
<?php } ?>
<?php if ( mysite_can_delete_user($user_id) ) { ?>
<input type="button" value="<?php _e('Delete Profile','mysite'); ?>" class="mysite-button red" data-template="delete" data-up_username="<?php echo $mysite->id_to_member($user_id); ?>" />
<?php } ?>
<img src="<?php echo $mysite->skin_url(); ?>loading.gif" alt="" class="mysite-loading" />
<div class="mysite-clear"></div>
</div>
<?php } ?>
</form>
</div>
<?php } ?>
Then following javascript:
<script>// <![CDATA[
jQuery("#A").click(function(){
jQuery("#B").trigger('click');
return false; });
// ]]></script>
And id="B" is on a header as a simple anchor button:
<div class="startskip"><a id="B" href="http://mysite/start/item">Skip</a></div>
What I want to achieve is that when a submit button is clicked, then the skip button is also triggered and the user will be redirected to the next page.
Of course, I am going to put setTimeoutso there is enough time to save instead of instant redirect.
However, the submit button becomes not-responsive when I add the javascript.
So, it seems that there is a javascript conflict between the click function and submit function. (Without the javascript, the submit button works).
By looking the code, could you guys figure out what the problem is and how to solve it?
Thanks!
I read an article on this previously which explains why it doesn't work - but have lost the link, I'll see if I can find it an update this post tomorrow. But the summary would be to say that the jQuery trigger click method triggers the event handler for the element, it does not trigger the browsers default behaviour i.e. following a link.
You have two choices, if you must use jQuery, then you can use this:
window.location = $('#B').attr('href');
Another option is to use pure JS:
document.getElementById("a_link").click();
In this case, I would go for the second option since I think it is more clear and readable - but that's subjective!
The return false inside the click handler cancels the original click and that is why the form doesn't get submitted.
I don't think it's possible to run any script after the form submission though. You could try submitting the form with ajax and on success do the redirect.

Refresh div with jquery in ajax call

I have a div that has foreach's in them like so:
<div id="conversation">
<?php foreach($singles as $question): ?>
<div class="well well-sm">
<h4><?php echo $question['question_title']; ?></h4>
</div>
<div class="bubble bubble--alt">
<?php echo $question['question_text']; ?>
</div>
<?php endforeach; ?>
<?php foreach($information as $answer): ?>
<div class="bubble">
<?php echo $answer['answer_text']; ?>
</div>
<?php endforeach; ?>
</div>
And I also have a form to put in a new answer:
<form method="post" style="padding-bottom:15px;" id="answerForm">
<input type="hidden" id="user_id" value="<?php echo $_SESSION['user_id']; ?>" name="user_id" />
<input type="hidden" id="question_id" value="<?php echo $_GET['id']; ?>" name="question_id" />
<div class="row">
<div class="col-lg-10">
<textarea class="form-control" name="answer" id="answer" placeholder="<?php if($_SESSION['loggedIn'] != 'true'): ?>You must be logged in to answer a question <?php else: ?>Place your answer here <?php endif; ?>" placeholder="Place your answer here" <?php if($_SESSION['loggedIn'] != 'true'): ?>disabled <?php endif; ?>></textarea>
</div>
<div class="col-lg-2">
<?php if($_SESSION['loggedIn'] != 'true'): ?>
<?php else: ?>
<input type="submit" value="Send" id="newAnswer" class="btn btn-primary btn-block" style="height:58px;" />
<?php endif; ?>
</div>
</div>
</form>
I am submitting the form via ajax and would like the div #conversation to refresh and reload the for each every time the user submits an answer to the question. Right now I have the following ajax code:
<script type="text/javascript">
$("#newAnswer").click(function() {
var answer = $("#answer").val();
if(answer == ''){
$.growl({ title: "Success!", message: "You must enter an answer before sending!" });
return false;
}
var user_id = $("input#user_id").val();
var question_id = $("input#question_id").val();
var dataString = 'answer='+ answer + '&user_id=' + user_id + '&question_id=' + question_id;
$.ajax({
type: "POST",
url: "config/accountActions.php?action=newanswer",
data: dataString,
success: function() {
$.growl({ title: "Success!", message: "Your answer was submitted successfully!" });
$("#answerForm").find("input[type=text], textarea").val("");
$("#conversation").hide().html(data).fadeIn('fast');
}
});
return false;
});
</script>
You will notice that I have tried $("#conversation").hide().html(data).fadeIn('fast'); but it did not successfully do the job. It only reloaded the information that was passed through ajax into the div instead of just reloading the foreach.
How can I refresh the div or the <?php foreach(); ?> in the success function of the ajax call?
Mitch, I'm looking at this part:
success: function() {
$.growl({ title: "Success!", message: "Your answer was submitted successfully!" });
$("#answerForm").find("input[type=text], textarea").val("");
$("#conversation").hide().html(data).fadeIn('fast');
}
See the expression ".html(data)"??? Where is "data" being declared? The code above will never work. Now, look at the lines below. Particularly the first one. See my change?
success: function(data) {
$.growl({ title: "Success!", message: "Your answer was submitted successfully!" });
$("#answerForm").find("input[type=text], textarea").val("");
$("#conversation").hide().html(data).fadeIn('fast');
}
Once you make this change, you need to use a debugger (chrome's or otherwise) to examine that what's coming back from your ajax call (which we don't have here) is what you need. But first, fix the bug.
Good luck.
jQuery .load() method (http://api.jquery.com/load/) can fetch and update single block from webpage. It will reload whole webpage in background, so some overhead is generated..
Change your ajax success to something like below:
success: function() {
$.growl({ title: "Success!", message: "Your answer was submitted successfully!" });
$("#conversation").load("config/accountActions.php #conversation >*");
}
This should load your conversation block and all it's childs and replace current(old) conversation block.

Categories

Resources