I'm adding a 'Remove' button next to each item in the Order via this function in functions.php:
add_action( 'woocommerce_order_item_meta_end', 'display_remove_order_item_button', 10, 3 );
function display_remove_order_item_button( $item_id, $item, $order ){
// Avoiding displaying buttons on email notification
if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) ) return;
if( isset($_POST["remove_item_$item_id"]) && $_POST["remove_item_$item_id"] == 'Remove this item' ){
wc_delete_order_item( $item_id );
}
echo '<form class="cart" method="post" enctype="multipart/form-data" style= "margin-top:12px;">
<input type="submit" class="button" name="remove_item_'.$item_id.'" value="Remove this item" />
</form>';
}
The issue is, after clicking the Remove button you then have to refresh the order page in order for the item to disappear.
I'd like that to happen automatically. I suppose I need to use Ajax to call the above function, but not quite sure how to do that.
Thanks in advance
Assuming your example is working, you'll change the function to look something like this:
add_action( 'woocommerce_order_item_meta_end', 'display_remove_order_item_button', 10, 3 );
function display_remove_order_item_button( $item_id, $item, $order ){
// Avoiding displaying buttons on email notification
if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) ) return;
echo '<form class="cart" method="post" enctype="multipart/form-data" style= "margin-top:12px;">
<input type="submit" id="remove-btn" data-id="'.$item_id.'" data-order="'.$order->get_order_number().'" class="button" name="remove_item_'.$item_id.'" value="Remove this item" />
</form>';
}
We gave the button a unique ID so we can detect clicks using jQuery. Notice data-id attribute, that's where we're passing $item_id. Now that display function is ready, we need to create an ajax call:
add_action('wp_head', 'ajax_call_remove_item');
function ajax_call_remove_item() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
$(document).on("click","#remove-btn",function(e) {
e.stopImmediatePropagation();
e.preventDefault();
// get data values from the button
var details = $(this).data();
var container = $(this).closest('td').parent('tr');
$(this).closest('td').append('<div id="loader">Data is loading</div>');
var data = {
action: 'remove_item',
// get id from data
id: details.id,
orderid: details.order,
};
$.post('<?php echo esc_url( home_url() ); ?>/wp-admin/admin-ajax.php', data, function(response) {
// display the response
$(container).empty();
$(container).html(response);
});
});
});
</script>
<?php
}
Now a function to handle POST data, delete the item and return a response:
add_action('wp_ajax_remove_item', 'remove_item_callback_wp');
add_action( 'wp_ajax_nopriv_remove_item', 'remove_item_callback_wp' );
function remove_item_callback_wp() {
$item_id = $_POST['id'];
$order_id = $_POST['orderid'];
$order = new WC_Order($order_id);
foreach ($order->get_items() as $order_item_id => $item){
if($order_item_id == $item_id){
wc_delete_order_item(absint($order_item_id));
}
}
echo "This items has been removed";
exit();
}
Related
I am creating my custom form-edit-account.php template. This contains a form that allows users to change their name, surname, password and other info. Originally the form does not perform ajax requests, you click the save changes button, the data is saved and the page is reloaded. The required fields and their validity are managed by the file https://woocommerce.github.io/code-reference/files/woocommerce-includes-class-wc-form-handler.html#source-view.218
What I did was create ajax request for the form in order to save the fields without the page refresh. The fields are edited and updated correctly, so it works. However, handling validation not working.
Somehow I need field handling validation but I don't know how to proceed I'm stuck at this point. I have two ideas I could work on:
Try somehow to make the original handling validation work.
Create a custom handling validation with js or php separately from the original file, but I don't know if this is correct.
How could I handle field validation? I hope someone can help me understand how I could do this, I appreciate any help and thank you for any replies.
Example of 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>
Js File
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' );
add_action('woocommerce_save_account_details_errors','save_account_details', 10, 1 );
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 (This not working)
if (trim($_POST['account_first_name']) == '') {
$response['error'] = true;
$response['error_message'] = 'Name is required';
if (trim($_POST['account_first_name']) == '') {
$response['status'] = false;
$response['message'] = 'Name is required';
}else{
$response['status'] = true;
$response['message'] = 'success';
}
// Exit here, for not processing further because of the error
echo json_encode($response);
exit();
}
exit(json_encode($response));
}
Thanks to the intervention of Martin Mirchev in the comments I was able to solve the problem.Here is the solution for anyone who is in the same conditions.
(The form remained the same)
Js File
jQuery(document).ready(function($) {
$('.mts-edit-account').on('submit', function(e) {
e.preventDefault();
//Ajax function
jQuery.ajax({
type: "post",
data: jQuery(".mts-edit-account").serialize(),
url: "wp-admin/admin-ajax.php",
success : function( response ) {
//jQuery('.woocommerce-notices-wrapper').append(response);
jQuery('.woocommerce-notices-wrapper').prepend(response);
}
});
});
});
functions.php
add_action( 'wp_ajax_save_account_details', 'save_account_details' );
add_action( 'woocommerce_save_account_details_errors','save_account_details', 10, 1 );
function save_account_details() {
if (trim($_POST['account_first_name']) == '') {
$response = wc_print_notices();
} else {
$response = "Settings Saved!";
}
// Don't forget to exit at the end of processing
echo json_encode($response);
exit();
}
I want to send an Ajax request when clicking a button but it seems my request is never executed.
Here is my HTML code :
<!DOCTYPE html>
<html lang="en">
<head>
<title>User Form</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src = "./actions.js"></script>
</head>
<body>
<div id="badFrm" class="container">
<h2><br>User Registration</h2>
<form id="Form" method="post">
<div class="form-group">
<label for="name">Name:</label>
<input type="name" class="form-control" id="name" placeholder="Enter Name" name="name">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" placeholder="Enter Email" name="email">
</div>
<button id="submitBtn" class="btn btn-primary">Submit</button>
</form>
</div>
</body>
</html>
i feel there is something wrong with my javascript code but i cant figure whats wrong ! i changed a lot of it based on the comments i got earlier . what i want is when i click on the update button it changes to " submit again " and i want to replace "list items" ( name and email ) with input fields and put whatever written in them to be saved in the database instead . and eventually return to the first page which is the register form. i need help in this part !! i know this part is buggy . i need to know how to reach each list item individually ( what attribute should i add/use )
and here is my javascript code :
$(document).ready(function() {
var i ;
$("#submitBtn").click(function (e) {
e.preventDefault();
var name = $("#name").val();
var email = $("#email").val();
$.post("http://localhost/MiniProject/connect.php",
{
name: name,
email: email
}, function () {
var element = document.getElementById("badFrm");
element.remove();
showTbl();
});
function showTbl() {
$.post("http://localhost/MiniProject/Select.php",
{
name: name,
email: email
}, function (res) {
// console.log(res);
res = JSON.parse(res);
var html = '<ul id="List">';
for (i = 0; i < res.length; i++) {
var j = i +1 ;
html += '<li class = "name" >' + res[i].name + '</li><li class = "email">' + res[i].email + '</li>'+ '<div>' + '<button onclick="removeUser(this)" class="btn btn-primary">Remove</button>' + '<button onclick="updateUser(this)" class="btn btn-primary">Update</button>' + '</div>';
}
html += '</ul>';
document.body.innerHTML = html;
});
}
});
});
function removeUser(element){
var ID = element.id;
var element2 = document.getElementById("List");
element2.remove();
$.post("http://localhost/MiniProject/Remove.php",{
id : ID
}, function (res) {
console.log(res);
document.write(res);
});
//alert(element.id);
}
function updateUser(element){
// code ...
$.post("http://localhost/MiniProject/Update.php",{
id : ID2,
}, function (res) {
console.log(res);
// document.write(res);
});
}
here is connect.php :
<?php
require 'Users.php';
$name = $_POST['name'];
$email = $_POST['email'];
$conn = new mysqli('localhost','root','','mydatabasename');
if($conn->connect_error){
die('Connection Failed : '.$conn->connect_error);
}else {
$user = new Users();
$user->Insert(['name' => $name, 'email' => $email]);
echo "name is : ".$name." and email is : ".$email;
}
this is Users.php :
<?php
require 'newDB.php';
class Users extends DatabaseClass{
public $table = 'Users';
}
and this is where i handle the database commands :
<?php
class DatabaseClass{
public $connection = null;
public $table = null;
// this function is called everytime this class is instantiated
public function __construct( $dbhost = "localhost", $dbname = "myDatabaseName", $username = "root", $password = ""){
try{
// $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$this->connection = new PDO("mysql:host=$dbhost;dbname=$dbname", $username, $password);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql = "CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)";
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
// Insert a row/s in a Database Table
public function Insert($parameters = [] ){
try{
$fields = array_keys($parameters);
$fields_string = '`' . implode('`,`', $fields) . '`';
$values_string = ':' . implode(',:', $fields);
$sql = "INSERT INTO `{$this->table}`({$fields_string}) VALUES ( {$values_string} )";
$this->executeStatement( $sql , $parameters );
return $this->connection->lastInsertId();
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
// Select a row/s in a Database Table
public function Select( $parameters = [] ){
try{
$fields = array_values($parameters);
$fields_string=implode(' , ',$fields);
$sql = "SELECT {$fields_string} FROM {$this->table}";
$stmt = $this->executeStatement( $sql , $parameters );
return $stmt->fetchAll();
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
// Update a row/s in a Database Table
public function Update( $parameters = [] ){
try{
$fields = array_keys($parameters);
$fields_string = 'id = '.implode($fields);
$sql = "UPDATE {$this->table} SET {$fields_string} WHERE {$fields_string} ";
echo $sql; exit ;
$this->executeStatement( $sql , $parameters );
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
// Remove a row/s in a Database Table
public function Remove( $parameters ){
try{
$fields_string = 'id = '.implode($parameters);
$sql = "DELETE FROM {$this->table} WHERE {$fields_string}";
$this->executeStatement( $sql , $parameters );
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
// execute statement
public function executeStatement( $statement = "" , $parameters = [] ){
try{
$stmt = $this->connection->prepare($statement);
$stmt->execute($parameters);
return $stmt;
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
}
and this is Update.php :
<?php
require 'Users.php';
$id = $_POST['id'];
$conn = new mysqli('localhost','root','','mydatabasename');
if($conn->connect_error){
die('Connection Failed : '.$conn->connect_error);
}else {
$user = new Users();
$result = $user->Update(['id'=>$id]);
// echo json_encode($result);
}
?>
i dont want the question to have a lot of code so hope this makes it better to understand.
I mentioned posting something without jQuery - here is a demo which does what I understand your requirement to be. There are comments below to explain what is going on.
<?php
error_reporting( E_ALL );
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'] ) ){
ob_clean();
/*
This emulates ALL of the PHP endpoints used in the original code
-this is for demo purposes ONLY. The data returned is DEMO data
and should be ignored. All AJAX functions should be pointed at
their original endpoints... unless you adopt a similar approach
in which case include your various PHP classes here.
The ficticious sql in the below is for example only!
Obviously you would use `prepared statements`...
*/
switch( $_POST['action'] ){
case 'insert':
// do stuff...
// send response...
$data=sprintf('name is: %s and email is: %s',$_POST['name'],$_POST['email']);
break;
case 'remove':
header('Content-Type: application/json');
$data=json_encode(array(
'action' => $_POST['action'],
'name' => $_POST['name'],
'email' => $_POST['email'],
'sql' => sprintf('delete from `TABLE` where `email`="%s"', $_POST['email'] )
));
break;
case 'update':
header('Content-Type: application/json');
$data=json_encode(array(
'action' => $_POST['action'],
'name' => $_POST['name'],
'email' => $_POST['email'],
'sql' => sprintf('update `TABLE` set `col`=? where `email`="%s"', $_POST['email'] )
));
break;
}
exit( $data );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
.hidden{display:none}
</style>
<script>
document.addEventListener('DOMContentLoaded',()=>{
/*
I can see no benefit to having multiple endpoints to process
the different AJAX requests. You can structure a single script
to process each request rather like the above PHP code but
that is just an opinion. The following points ALL requests to
the same page for this demo.
The user's `email` address should be unique(?) so could be used
as the key in whatever sql query???
*/
const endpoints={
'insert':location.href, // 'MiniProject/connect.php'
'select':location.href, // 'MiniProject/Select.php'
'remove':location.href, // 'MiniProject/Remove.php'
'update':location.href // 'MiniProject/Update.php'
};
// Elements in the initial page/form
let cont=document.querySelector('div.container');
let form=document.forms.register;
let bttn=form.querySelector('button');
// the main callback - for the `Submit` button
const bttnclickhandler=function(e){
e.preventDefault();
let valid=true;
// check the form fields are not empty before continuing
let col=form.elements;
Array.from( col ).some( n => {
if( n.tagName=='INPUT' && n.value=='' ){
alert( '"' + n.name + '" cannot be empty' );
valid=false;
return true;
}
})
if( !valid )return false;
// Prepare the Payload to be sent, via AJAX POST, to the backend script/endpoint.
let fd=new FormData( form );
fd.append('action',this.dataset.action);
// Send the AJAX request
fetch( endpoints.insert, { method:'post', body:fd } )
.then( r=>r.text() )
.then( text=>{
// Hide the original form - do not remove it though... you want to reinstate this later
form.classList.add('hidden');
/*
create a clone of the template and then find the elements within
assign new values and bind event listeners.
*/
let oTmpl=document.querySelector('template#list-item').content.firstElementChild.cloneNode( true );
oTmpl.querySelector('[data-id="name"]').textContent=fd.get('name');
oTmpl.querySelector('[data-id="email"]').textContent=fd.get('email');
oTmpl.querySelectorAll('button[data-action]').forEach( n=>{
n.addEventListener('click',function(e){
let action=this.dataset.action;
let url=endpoints[ action ];
let fd=new FormData();
fd.append('action',action);
fd.append('name',e.target.parentNode.parentNode.querySelector('span[data-id="name"]').textContent);
fd.append('email',e.target.parentNode.parentNode.querySelector('span[data-id="email"]').textContent);
// send a new AJAX request
fetch( url, { method:'post', body:fd })
.then( r=>r.json() )
.then( json=>{
// the response...
console.log( json );
// show the original form and remove the clone
form.classList.remove('hidden');
cont.querySelector('ul#list').removeChild( oTmpl );
})
});
});
// Add the cloned template to the container
cont.querySelector('ul#list').appendChild( oTmpl )
})
};
// bind the event handler to the button.
bttn.addEventListener( 'click', bttnclickhandler );
});
</script>
</head>
<body>
<!--
All buttons below have dataset attributes
data-action='value' - this is used to decide
which piece of PHP code to process.
-->
<div class='container'>
<h2>User Registration</h2>
<form name='register' method='post'>
<div class='form-group'>
<label>
Name:
<input type='text' name='name' class='form-control' placeholder='Enter Name' />
</label>
</div>
<div class='form-group'>
<label>
Email:
<input type='email' name='email' class='form-control' placeholder='Enter Email' />
</label>
</div>
<button data-action='insert' class='btn btn-primary'>Submit</button>
</form>
<ul id='list'></ul>
</div>
<!--
The template will be called and populated
by ajax callback when the above `Submit`
button is clicked.
This will NOT appear in the DOM until
requested with Javascript.
The inner contents of this template
are cloned and inserted into the DOM.
-->
<template id='list-item'>
<li>
<span data-id='name'></span>
<span data-id='email'></span>
<div>
<button data-action='remove' class="btn btn-primary">Remove</button>
<button data-action='update' class="btn btn-primary">Update</button>
</div>
</li>
</template>
</body>
</html>
You say that you want to make an AJAX request (submit), but I don't see where are you doing it.
Also, it seems that you're submitting twice your form.
You should have something like this:
$.ajax({
data: $(this).serialize(),
type: "POST",
url: "http://localhost/MiniProject/connect.php",
success: function(data) {
//if it's successful, put all your code here to change names etc.
}
$(this).serialize() will work only if you change your button to a submit input:
<input type="submit" id="submitBtn" class="btn btn-primary">Submit</input>
you can also use a "button" but then you'll have to specify what data you're submitting, it's easier to use a submit input, if you ask me.
Also, if you already have an ID for name and email, it's a lot easier to change them using it's respective ID's, instead of trying to re-write the whole div element.
Anyway, I hope it helps
I am trying to remove WordPress posts from front end using AJAX.
My code removes post, but displays blank page with "success", when i want to just fade out this post without page reloading and displaying blank page.
PHP code:
<?php if( current_user_can( 'delete_post' ) ) : ?>
<?php $nonce = wp_create_nonce('my_delete_post_nonce') ?>
delete
<?php endif ?>
Functions.php code:
function my_frontend_script() {
wp_enqueue_script( 'my_script', get_template_directory_uri() . '/js/my_script.js', array( 'jquery' ), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_frontend_script' );
wp_localize_script( 'js/my_script.js', 'MyAjax2', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'ajaxnonce' => wp_create_nonce('ajax-nonce') ) );
add_action( 'wp_ajax_my_delete_post', 'my_delete_post' );
function my_delete_post(){
$permission = check_ajax_referer( 'my_delete_post_nonce', 'nonce', false );
if( $permission == false ) {
echo 'error';
}
else {
wp_delete_post( $_REQUEST['id'] );
echo 'success';
}
die();
}
my_script.js code:
jQuery( document ).ready( function($) {
$(document).on( 'click', '.delete-post', function() {
var id = $(this).data('id');
var nonce = $(this).data('nonce');
var post = $(this).parents('.post:first');
$.ajax({
type: 'post',
url: MyAjax2.ajaxurl,
data: {
action: 'my_delete_post',
nonce: nonce,
id: id
},
success: function( result ) {
if( result == 'success7' ) {
post.fadeOut( function(){
post.remove();
});
}
}
})
return false;
})
})
The problem is page is reloading to a blank page with "success" text, when it should just fade out and remove post from current page, without reloading.
It looks like my_script.js is not even used at all :(
Any help much appreciated.
delete
it's reloading because it loads first the url in your href attribute, then executing your ajax-call. thats not what you want. you want to execute only the onclick. this should solve the problem. just put a # in your href
delete
or make buttons
<button data-id="<?php the_ID() ?>" data-nonce="<?php echo $nonce ?>" class="delete-post">delete</button>
edit: if it's still not working, it's because you got a typo here
if( result == 'success7' )
success7 instead of success
I found a function to automatically update the cart when the quantity of an item is changed, and it was working until WooCommerce's 3.2.0 updated (latest update 3.2.1). I'm pretty sure something changed within this code:
add_action('woocommerce_cart_updated', 'wac_update');
function wac_update() {
// is_wac_ajax: flag defined on wooajaxcart.js
if ( !empty($_POST['is_wac_ajax'])) {
$resp = array();
$resp['update_label'] = __( 'Update Cart', 'woocommerce' );
$resp['price'] = 0;
// render the cart totals (cart-totals.php)
ob_start();
do_action( 'woocommerce_after_cart_table' );
do_action( 'woocommerce_cart_collaterals' );
do_action( 'woocommerce_after_cart' );
$resp['html'] = ob_get_clean();
// calculate the item price
if ( !empty($_POST['cart_item_key']) ) {
$items = WC()->cart->get_cart();
$cart_item_key = $_POST['cart_item_key'];
if ( array_key_exists($cart_item_key, $items)) {
$cart_item = $items[$cart_item_key];
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$price = apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key );
$resp['price'] = $price;
}
}
echo json_encode($resp);
exit;
}
}
My Javascript still working but here it is for a reference:
function refreshCart() {
jQuery('.cart-builder .qty').on('change', function(){
var form = jQuery(this).closest('form');
// emulates button Update cart click
jQuery("<input type='hidden' name='update_cart' id='update_cart' value='1'>").appendTo(form);
// plugin flag
jQuery("<input type='hidden' name='is_wac_ajax' id='is_wac_ajax' value='1'>").appendTo(form);
var el_qty = jQuery(this);
var matches = jQuery(this).attr('name').match(/cart\[(\w+)\]/);
var cart_item_key = matches[1];
form.append( jQuery("<input type='hidden' name='cart_item_key' id='cart_item_key'>").val(cart_item_key) );
// get the form data before disable button...
var formData = form.serialize();
jQuery("input[name='update_cart']").val('Updating...').prop('disabled', true);
jQuery.post( form.attr('action'), formData, function(resp) {
// ajax response
jQuery('.cart-collaterals').html(resp.html);
el_qty.closest('.cart_item').find('.product-subtotal').html(resp.price);
console.log(resp.test);
jQuery('#update_cart').remove();
jQuery('#is_wac_ajax').remove();
jQuery('#cart_item_key').remove();
jQuery("input[name='update_cart']").val(resp.update_label).prop('disabled', false);
},
'json'
);
});
}
I've been looking through the change log, https://github.com/woocommerce/woocommerce/blob/master/CHANGELOG.txt, but I can't find what would be conflicting now. Like I said, it was working perfectly before this updated.
Ok here is a simpler solution, I am just appending a script to the bottom of the cart page but you could also enqueue it with wp_enqueue_script function which is the best way. All it does it simulates the pressing of the update cart button.
function cart_update_qty_script() {
if (is_cart()) :
?>
<script type="text/javascript">
(function($){
$(function(){
$('div.woocommerce').on( 'change', '.qty', function(){
$("[name='update_cart']").trigger('click');
});
});
})(jQuery);
</script>
<?php
endif;
}
add_action( 'wp_footer', 'cart_update_qty_script' );
I have designed a Sidebar Floating Form with PhP/Ajax which is working and sending submission to my targeted email. Here is the Link: http://logohour.com/form.html but when a visitor fill and submit the form successfully it routes him to another page for the confirmation.
This shouldn't be like this and must be stick to the homepage with popup Message as per my coding:
<div id="sendingMMessage" class="statusMessage"> <p>Sending your message. Please wait...</p> </div>
<div id="successMMessage" class="statusMessage"> <p>Thanks for sending your message! We'll get back to you shortly.</p> </div>
Below you may find my Ajax & PHP for reference:
<?php
// Define some constants
define( "RECIPIENT_NAME", "John Smith" );
define( "RECIPIENT_EMAIL", "example#gmail.com" );
define( "EMAIL_SUBJECT", "SiderBar Visitor Message" );
// Read the form values
$ssuccess = false;
$Name = isset( $_POST['Name'] ) ? preg_replace( "/[^\.\-\' a-zA-Z0-9]/", "", $_POST['Name'] ) : "";
$Email = isset( $_POST['Email'] ) ? preg_replace( "/[^\.\-\_\#a-zA-Z0-9]/", "", $_POST['Email'] ) : "";
$Phone = isset( $_POST['Phone'] ) ? preg_replace( "/[^\.\-\_\#a-zA-Z0-9]/", "", $_POST['Phone'] ) : "";
$Country = isset( $_POST['Country'] ) ? preg_replace( "/[^\.\-\_\#a-zA-Z0-9]/", "", $_POST['Country'] ) : "";
$Select = isset( $_POST['Select'] ) ? preg_replace( "/[^\.\-\_\#a-zA-Z0-9]/", "", $_POST['Select'] ) : "";
$Message = isset( $_POST['Message'] ) ? preg_replace( "/(From:|To:|BCC:|CC:|Subject:|Content-Type:)/", "", $_POST['Message'] ) : "";
// If all values exist, send the email
if ( $Name && $Email && $Phone && $Country && $Select && $Message ) {
$msgToSend = "Name: $Name\n";
$msgToSend .= "Email: $Email\n";
$msgToSend .= "Phone: $Phone\n";
$msgToSend .= "Sender Country: $Country\n";
$msgToSend .= "Sender Select: $Select\n";
$msgToSend .= "Message: $Message";
$recipient = RECIPIENT_NAME . " <" . RECIPIENT_EMAIL . ">";
$headers = "From: " . $Name . " <" . $Email . ">";
$ssuccess = mail( $recipient, EMAIL_SUBJECT, $msgToSend, $headers );
}
// Return an appropriate response to the browser
if ( isset($_GET["ajax"]) ) {
echo $ssuccess ? "ssuccess" : "error";
} else {
?>
<html>
<head>
<title>Thanks!</title>
</head>
<body>
<?php if ( $ssuccess ) echo "<p>Thanks for sending your message! We'll get back to you shortly.</p>" ?>
<?php if ( !$ssuccess ) echo "<p>There was a problem sending your message. Please try again.</p>" ?>
<p>Click your browser's Back button to return to the page.</p>
</body>
</html>
<?php
}
?>
var messageDDelay = 2000; // How long to display status messages (in milliseconds)
// Init the form once the document is ready
$(init);
// Initialize the form
function init() {
// Hide the form initially.
// Make submitForm() the form's submit handler.
// Position the form so it sits in the centre of the browser window.
// When the "Send us an email" link is clicked:
// 1. Fade the content out
// 2. Display the form
// 3. Move focus to the first field
// 4. Prevent the link being followed
$('a[href="#contact_form"]').click(function() {
$('#content').fadeTo('slow', .2);
$('#contact_form').fadeIn('slow', function() {
$('#Name').focus();
})
return false; });
// When the "Cancel" button is clicked, close the form
$('#cancel').click(function() {
$('#contact_form').fadeOut();
$('#content').fadeTo('slow', 1);
});
// When the "Escape" key is pressed, close the form
$('#contact_form').keydown(function(event) {
if (event.which == 27) {
$('#contact_form').fadeOut();
$('#content').fadeTo('slow', 1);}});}
// Submit the form via Ajax
function submitFForm() {
var contact_form = $(this);
// Are all the fields filled in?
if (!$('#Name').val() || !$('#Email').val() || !$('#Phone').val() || !$('#Country').val() || !$('#Select').val() || !$('#Message').val()) {
// No; display a warning message and return to the form
$('#incompleteMMessage').fadeIn().delay(messageDDelay).fadeOut();
contact_form.fadeOut().delay(messageDDelay).fadeIn();
} else {
// Yes; submit the form to the PHP script via Ajax
$('#sendingMMessage').fadeIn();
contact_form.fadeOut();
$.ajax({
url: contact_form.attr('action') + "?ajax=true",
type: contact_form.attr('method'),
data: contact_form.serialize(),
ssuccess: submitFFinished }); }
// Prevent the default form submission occurring
return false; }
// Handle the Ajax response
function submitFFinished(response) {
response = $.trim(response);
$('#sendingMMessage').fadeOut();
if (response == "ssuccess") {
// Form submitted ssuccessfully:
// 1. Display the ssuccess message
// 2. Clear the form fields
// 3. Fade the content back in
$('#successMMessage').fadeIn().delay(messageDDelay).fadeOut();
$('#Name').val("");
$('#Email').val("");
$('#Phone').val("");
$('#Country').val("");
$('#Selct').val("");
$('#Message').val("");
$('#content').delay(messageDDelay + 500).fadeTo('slow', 1);
} else {
// Form submission failed: Display the failure message,
// then redisplay the form
$('#failureMMessage').fadeIn().delay(messageDDelay).fadeOut();
$('#contact_form').delay(messageDDelay + 500).fadeIn(); } }
Below the simple ajax form submission. Hope it will help your need.
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script>
$(function () {
$('form#consultationForm').on('submit', function(e) {
$.ajax({
type: 'post',
url: 'receivedConfirmation.php',
data: $(this).serialize(),
success: function (result) {
console.log(result);
$('#receivedStatus').attr('style','display:block');
$('#receivedStatus').html(result);
}
});
e.preventDefault();
});
});
</script>
<form id="consultationForm" method="post">
Firstname: <input name="fname" />
Lastname: <input name="lname" />
<div style='clear:both;'></div>
<input type="submit" name="submit" value="save"/>
<input type="reset" name="cancel" value="cancel"/>
</form>
<div id='receivedStatus' style='display:none;'></div>
receivedConfirmation.php
<?php
echo "<PRE>";
print_r($_POST);
echo "</PRE><br>";
//do your DB stuffs here and finally echo your response based on success or failure
echo "Thanks for sending your message! We'll get back to you shortly.";
echo "<br>Click your browser's Back button to return to the page."
?>
First you have to avoid the normal form submission for this form and you can do this by using normal button instead of submit button.
<input type="button" id="sendMMessage" name="sendMMessage" value="Submit">
Execute a javascript ajax submit code onclick of sendMMessage id.
and this will solve your problem.
Updated answer :
$( "#target" ).click(function() {
// put your ajax form submit code here
$.ajax({
type: "POST",
url: 'http://logohour.com/sidebar-form.php',
data: $("#contact_form").serialize(), // serializes the form's elements.
success: function(data)
{
console.log(data); // show response from the php script.
}
});
});
If you are still unclear about this I will explain you more detail.
thanks.