Woocommerce mini-cart ajax apply coupon - ajax

I have been going in circles with this I have added an apply coupon field to mini-cart.php and am trying to get it to run without refreshing the whole page. Any suggestions would be amazing help.
functions:
function apply_coupon_code(){
$coupon_code = isset( $_POST["coupon_code"] ) ? $_POST["coupon_code"] : '';
WC()->cart->apply_coupon($coupon_code);
}
add_action( 'wp_ajax_apply_coupon_code', 'apply_coupon_code' );
add_action( 'wp_ajax_nopriv_apply_coupon_code', 'apply_coupon_code' );
Input:
<?php if (empty (WC()->cart->get_coupons())): ?>
<span id="coupon-form">
<?php if ( wc_coupons_enabled() ) { ?>
<form class="widget_shopping_cart_content" action="<?php echo $cart_url ?>" method="post">
<?php } else { ?>
<form id="apply-promo-code" class="widget_shopping_cart__coupon">
<?php } ?>
<label id="promo-code" for="coupon-code">Promo Code:</label>
<input id="minicart-coupon" class="input-text" type="text" value="" name="coupon_code"/>
<button type="submit" id="minicart-apply-button" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_attr_e( 'Apply', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_coupon' ); ?>
<?php do_action( 'woocommerce_cart_actions' ); ?>
</form>
<?php endif; ?>
<?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?>
<span id="widget-shopping-cart-remove-coupon" class="mini_cart_coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
Promo Code: <?php echo esc_attr( sanitize_title( $code ) ); ?>
<?php $remove_url = $cart_url.'?remove_coupon='.$coupon->code; ?>
<?php wc_cart_totals_coupon_html( $coupon ); ?>
</span>
<?php endforeach; ?>
jQuery:
jQuery(document).on('click', 'button#minicart-apply-button', function() {
var coupon = jQuery( 'input#minicart-coupon' ).val();
var button = ( this );
var data = {
action: "apply_coupon_code",
coupon_code: "coupon"
};
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: wc_add_to_cart_params.ajax_url,
data: data,
success: function (response) {
console.log(response);
},
error: function (errorThrown) {
console.log(errorThrown);
}
});
});

You can get the new mini cart HTML inside your ajax callback on the server and then return that as a response to the jQuery ajax call then simply replace the whole mini cart HTML on the front-end with the updated HTML.
function apply_coupon_code(){
$coupon_code = isset( $_POST["coupon_code"] ) ? $_POST["coupon_code"] : '';
WC()->cart->apply_coupon($coupon_code);
ob_start();
woocommerce_mini_cart();
$cart_html = ob_get_clean();
return $cart_html;
}
add_action( 'wp_ajax_apply_coupon_code', 'apply_coupon_code' );
add_action( 'wp_ajax_nopriv_apply_coupon_code', 'apply_coupon_code' );
The output buffer is used here as woocommerce_mini_cart uses wc_get_template which just echoes out the content. The output buffer will allow you to capture this as a string.
Now you need to tell jQuery that you're expecting HTML back from the server...
jQuery(document).on('click', 'button#minicart-apply-button', function() {
var coupon = jQuery( 'input#minicart-coupon' ).val();
var button = ( this );
var data = {
action: "apply_coupon_code",
coupon_code: "coupon"
};
jQuery.ajax({
type: 'POST',
dataType: 'html',
url: wc_add_to_cart_params.ajax_url,
data: data,
success: function (response) {
console.log(response);
},
error: function (errorThrown) {
console.log(errorThrown);
}
});
});
Now response will have the new HTML for the mini-cart, so you can replace it using jQuery's html() function...
success: function (response) {
console.log(response);
jQuery('.mini-cart-wrapper').html(response);
},

Related

How to get data from wordpress ajax search form?

My form html code, where i set action and the attribute name.
<div class="search_form">
<form action="<?php esc_url( home_url( '/' ) ); ?>" method="POST">
<input type="text" name="s" value="<?php get_search_query(); ?>" placeholder="Search...">
<input type="submit" value="Send">
</form>
</div>
I use localize scripts to connect ajax-search.
wp_enqueue_script( 'wc-estore-ajax-search-js', get_template_directory_uri() . '/assets/js/ajax-search.js', array( 'jquery' ), _S_VERSION, true );
wp_localize_script( 'wc-estore-ajax-search-js', 'search_form', array(
'url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'search-nonce' )
) );
In ajax-search got nonce, set action and set url.
jQuery(function ($) {
$('.search_form input[name="s"]').on('keyup', function () {
let search = $('.search_form input[name="s"]').val();
if (search.length < 4) {
return false;
}
let data = {
s: search,
action: 'search_action',
nonce: search_form.nonce
};
$.ajax({
url: search_form.url,
data: data,
type: 'POST',
dataType: 'json',
beforeSend: function (xhr) {
},
success: function (data) {
console.log(data);
}
});
});
});
And in functions.php i want to see, what is in $_POST.
The action is the same as in the search-ajax.js.
add_action( 'wp_ajax_search_action', 'esp_search_ajax_action_callback' );
add_action( 'wp_ajax_nopriv_search_action', 'esp_search_ajax_action_callback' );
function esp_search_ajax_action_callback() {
/**
* Проверяем нонсе из массива пости и из wp_localize script
*/
if(!wp_verify_nonce($_POST['nonce'], 'search-nonce')){
wp_die('Данные пришли с левого адреса');
}
$_POST = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
$args = [
'post_type' => ['post', 'product'],
'post_status' => 'public',
's' => $_POST['s'],
];
$query_ajax = new WP_Query($args);
?>
<?php if($query_ajax->have_posts()): ?>
<?php while($query_ajax->have_posts()): ?>
<?php $query_ajax->the_post(); ?>
<h3 class="title-search"><?php the_title(); ?></h3>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
<?php
}
But the console is clear?
Where is my mistake?
Thanks for help.
Looks like you have a few things going on. Try these:
dataType is the type of data you're expecting back. You're not passing valid JSON back, so it is failing with a parse error (i.e. no success, no console.log).
vardump probably should be var_dump unless you've defined it elsewhere. If not, that's probably causing an error and sending back the error string (which again would not be valid JSON)
Although not necessarily the issue you're asking about, but you should also finish your callback with wp_die(); and pass whatever parameters you need for your situation.
If you want, while you're testing you can switch dataType to html.
You can also add in error (to see what the error is) and complete (to see that it actually came back) callbacks.
And just to be safe, you might want to filter your $_POST data with something like this:
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
or whatever filters fit your situation.

How to get Advanced Custom Fields values with Ajax in Wordpress

I'm trying to do a WP_query on a custom-post-type but for some reason I cannot get the values from the custom-field-types of these posts.
Here is what I got so far (functions.php)
function fetch_cases(){
$args = array(
'post_type' => array('case'),
'post_status' => array('publish'),
'posts_per_page' => 5
);
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts() ){
$query->the_post();
?>
<a href="<?php the_permalink(); ?>">
<div style="background-image:url('<?= get_field('case_picture'); ?>')">
<p><?= get_field('case_title') ?></p>
</div>
</a>
<?php }
}
die();
add_action('wp_ajax_nopriv_fetch_cases', 'fetch_cases');
add_action('wp_ajax_fetch_cases','fetch_cases');
}
And in my JS file have the following:
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: {
action: "fetch_cases"
},
success: function(data) {
$(".fetch_cases").append(data);
},
error: function(errorThrown) {
console.log(errorThrown);
}
});
Can someone tell me what I'm doing wrong?
I also tried to do:
<?php the_field('case_picture'); ?>
but with no luck? what am I missing?
add_action() should be outside your custom function. Try this instead.
function fetch_cases(){
$args = array(
'post_type' => array('case'),
'post_status' => array('publish'),
'posts_per_page' => 5
);
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts() ){
$query->the_post();
?>
<a href="<?php the_permalink(); ?>">
<div style="background-image:url('<?= get_field('case_picture'); ?>')">
<p><?= get_field('case_title') ?></p>
</div>
</a>
<?php }
}
die();
}
add_action('wp_ajax_nopriv_fetch_cases', 'fetch_cases');
add_action('wp_ajax_fetch_cases','fetch_cases');
you can use this logic by storing the field as a hidden value and pass in ajax through js
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts() ){
$query->the_post();
?>
<a href="<?php the_permalink(); ?>">
<div style="background-image:url('<?= get_field('case_picture'); ?>')">
<p><?= get_field('case_title') ?></p>
<input type="hidden" id="hidden" name="hidden_field" value="<?= get_field('case_picture'); ?>"> // store the value
</div>
</a>
<?php }
}
die();
Now get the data in jquery and pass through ajax
<script>
var hidden=//Grab data here.
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: {
action: "fetch_cases",
image:hidden, // Pass the data
},
success: function(data) {
$(".fetch_cases").append(data);
},
error: function(errorThrown) {
console.log(errorThrown);
}
});
</script>
and use the data in ajax called
function fetch_cases()
{
$image=$_POST['image'];
}
get_field method has 2nd parameter which is post ID, pass this and check. It should work.
$post_id = $post->ID;
$value = get_field( 'case_picture', $post_id );

Ajax form submit for wordpress

So, here is my codes:
form-checkout.php
<form id="rh_checkout_ajax" name="checkout" method="post" class="checkout woocommerce-checkout" enctype="multipart/form-data">
<?php if ( sizeof( $checkout->checkout_fields ) > 0 ) : ?>
<?php do_action( 'woocommerce_checkout_before_customer_details' ); ?>
<div class="col2-set" id="customer_details">
<div class="col-1">
<?php do_action( 'woocommerce_checkout_billing' ); ?>
</div>
<div class="col-2">
<?php do_action( 'woocommerce_checkout_shipping' ); ?>
</div>
</div>
<?php do_action( 'woocommerce_checkout_after_customer_details' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_checkout_before_order_review' ); ?>
<div id="order_review" class="woocommerce-checkout-review-order">
<?php do_action( 'woocommerce_checkout_order_review' ); ?>
</div>
<?php do_action( 'woocommerce_checkout_after_order_review' ); ?>
<input value="send" type="submit" name="buy_product" style="display:none;" id="rh_product_add_done_click"></input>
</form>
my_js.js
//Ajax checkout submit
jQuery('#rh_checkout_ajax').submit(function(e){
var name = jQuery(this).attr('name');
jQuery.ajax({
data: {action: 'contact_form', name:name},
type: 'post',
url: ajaxurl,
success: function(data) {
alert(data);
}
});
});
functions.php
//Ajax submit callback
add_action('wp_ajax_contact_form', 'contact_form');
add_action('wp_ajax_nopriv_contact_form', 'contact_form');
function contact_form()
{
echo $_POST['name'];
}
What happens normally
So, when a product is purchased, then the user is redirected to order-detail page which shows what he/she just bought.
What I want it to happen:
I am trying to make it so that the form is submitted via ajax and the user is NOT redirected to the order-detail page, but rather stays in the product page (so, no refresh nor redirect).
I attempted to submit the form via ajax as above but not much of luck.
Could someone help me out with this?
Thanks!
You have to prevent the form from submitting normally. In your js file, add e.preventDefault(). Something like this:
jQuery('#rh_checkout_ajax').submit(function(e){
e.preventDefault();
var name = jQuery(this).attr('name');
jQuery.ajax({
data: {action: 'contact_form', name:name},
type: 'post',
url: ajaxurl,
success: function(data) {
alert(data);
}
});
});

dropdown is not working i ajax form submit in yii 1x

My drop down is not working in ajax form submit but its working on normal form.
When i do ajax submit i get error in firebug
"NetworkError: 404 Not Found - http://example.com/yii/def/state/create"
But when i do the normal submission the form works.
Please help me to solve this issue
My ajax view is _ajax_create_form.php. Code:
<div class="form">
<?php
$form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(
'id'=>'state-create-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'method'=>'post',
'action'=>array("state/create"),
'type'=>'horizontal',
'htmlOptions'=>array(
'onsubmit'=>"return false;",/* Disable normal form submit */
),
'clientOptions'=>array(
'validateOnType'=>true,
'validateOnSubmit'=>true,
'afterValidate'=>'js:function(form, data, hasError) {
if (!hasError)
{
create();
}
}'
),
)); ?>
div class="row"> <?php echo $form->labelEx($model,'country_id'); ?> <?php echo $form->dropDownList($model,'country_id',
CHtml::listData(Country::model()->findAll(),'id','name')); ?> <?php echo $form->error($model,'country_id'); ?> </div>
<div class="modal-footer">
<div class="form-actions">
<?php
$this->widget('bootstrap.widgets.TbButton', array(
'buttonType'=>'submit',
'type'=>'primary',
'icon'=>'ok white',
'label'=>$model->isNewRecord ? 'Create' : 'Save',
));
?>
</div>
</div>
<?php
$this->endWidget(); ?>
</div>
Scipt for ajax submit
<script type="text/javascript">
function create()
{
var data=$("#state-create-form").serialize();
jQuery.ajax({
type: 'POST',
url: '<?php
echo Yii::app()->createAbsoluteUrl("state/create"); ?>',
data:data,
success:function(data){
//alert("succes:"+data);
if(data!="false")
{
$('#state-create-modal').modal('hide');
renderView(data);
$.fn.yiiGridView.update('state-grid', {
});
}
},
error: function(data) { // if error occured
alert("Error occured.please try again");
alert(data);
},
dataType:'html'
});
}
function renderCreateForm()
{
$('#state-create-form').each (function(){
this.reset();
});
$('#state-view-modal').modal('hide');
$('#state-create-modal').modal({
show:true,
});
}
</script>
My Controller code is
public function actionCreate()
{
$model=new State;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model,"state-create-form");
if(Yii::app()->request->isAjaxRequest)
{
print_r($_POST['State']);
if(isset($_POST['State']))
{
$model->attributes=$_POST['State'];
if($model->save())
{
echo $model->id;
}
else
{
echo "false";
}
return;
}
}
else
{
if(isset($_POST['State']))
{
$model->attributes=$_POST['State'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
}
Chnage your AJAX url
try by this
var href = window.localion.href.split('/');
var SITE_URL = href[0] + '//' + href[2] + '/';
$.ajax({
url: SITE_URL + 'controller/action',
........
........
});

Using fileuploader.js in codeigniter along with csrf in ajax

How do I use fileuploader.js in Codeigniter with csrf, in ajax?
I am using the images_crud library http://www.web-and-development.com/image-crud-an-automatic-multiple-image-uploader-for-codeigniter/
I keep getting
The action you have requested is not allowed.
Added..
I have added the create method in the controller :
/**
* pages form
*/
public function create(){
if(!isset($this->data['output'])){
$this->data = array_merge($this->data,
array( 'output' => '' ,
'js_files' => array() ,
'css_files' => array()
)
);
}
//-------------------------
//for file uploading
$image_crud = new image_CRUD();
$image_crud->set_primary_key_field('id');
$image_crud->set_url_field('filename');
$image_crud->set_table('news')
->set_image_path('public/documents');
$output = $image_crud->render();
$this->data['output']=$output->output;
$this->data['js_files']=$output->js_files;
$this->data['css_files']=$output->css_files;
//-------------------------
//display
$this->load->view('templates/admin_header');
$this->load->view('admin/index.php');
$this->load->view('admin/create_pages.php', $this->data);
$this->load->view('templates/admin_footer');
}
And the create_pages in view :
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?>
<?php echo validation_errors()?>
<?php
foreach($css_files as $file): ?>
<link type="text/css" rel="stylesheet" href="<?php echo $file; ?>" />
<?php endforeach; ?>
<?php foreach($js_files as $file): ?>
<script src="<?php echo $file; ?>"></script>
<?php endforeach; ?>
<?php echo form_open(site_url('admin/pages/save'),array('style'=>'width:700px;'))?>
<label>
Title
<input type='text' name='title' value='<?php echo #$title?>' />
</label>
<br/>
content :
<textarea name="content" id="content" >
<?php echo #$content?>
</textarea>
<br/>
<?php echo $output?>
<input type='submit' name='submit' value='save' />
</form>
I have added image_crud.php and image_moo.php in the library.
I am getting 500 Internal Server Error with the url being
http://example.com/mole/pages/create/upload_file?qqfile=1355936206.9151.jpg
which I wanted to be
http://example.com/mole/admin/pages/create/upload_file?qqfile=1355936206.9151.jpg
I am not sure why the fileuploader.js is taking a different url for uploading.
Added
Well, I have not made much changes to the codings avilaible from http://www.web-and-development.com/image-crud-an-automatic-multiple-image-uploader-for-codeigniter/
$(function(){
<?php if ( ! $unset_upload) {?>
createUploader();
<?php }?>
loadColorbox();
});
function loadColorbox()
{
$('.color-box').colorbox({
rel: 'color-box'
});
}
function loadPhotoGallery(){
$.ajax({
url: '<?php echo $ajax_list_url?>',
dataType: 'text',
data:$('input[type=hidden]').eq(1).prop('name')+':'+$('input[type=hidden]').eq(1).prop('value'),
beforeSend: function()
{
$('.file-upload-messages-container:first').show();
$('.file-upload-message').html("<?php echo $this->l('loading');?>");
},
complete: function()
{
$('.file-upload-messages-container').hide();
$('.file-upload-message').html('');
},
success: function(data){
$('#ajax-list').html(data);
loadColorbox();
}
});
}
function createUploader(){
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader-demo1'),
template: '<div class="qq-uploader">' +
'<div class="qq-upload-drop-area"><span><?php echo $this->l("upload-drop-area");?></span></div>' +
'<div class="qq-upload-button"><?php echo $this->l("upload_button");?></div>' +
'<ul class="qq-upload-list"></ul>' +
'</div>',
fileTemplate: '<li>' +
'<span class="qq-upload-file"></span>' +
'<span class="qq-upload-spinner"></span>' +
'<span class="qq-upload-size"></span>' +
'<a class="qq-upload-cancel" href="#"><?php echo $this->l("upload-cancel");?></a>' +
'<span class="qq-upload-failed-text"><?php echo $this->l("upload-failed");?></span>' +
'</li>',
action: '<?php echo $upload_url?>',
debug: true,
onComplete: function(id, fileName, responseJSON){
loadPhotoGallery();
}
});
}
function saveTitle(data_id, data_title)
{
$.ajax({
url: '<?php echo $insert_title_url; ?>',
type: 'post',
data: {primary_key: data_id, value: data_title},
beforeSend: function()
{
$('.file-upload-messages-container:first').show();
$('.file-upload-message').html("<?php echo $this->l('saving_title');?>");
},
complete: function()
{
$('.file-upload-messages-container').hide();
$('.file-upload-message').html('');
}
});
}
here you have two problems.
First: you need to set the csrf token with every ajax request. which is simple.
Second: you need to set the csrf token for when uploading. which is impossible.
But sure you have other alternatives here. DON'T Worry!.
each method like edit title or delete etc.. you can solve it like this:
in your list.php at the very first:
$this->set_css('assets/image_crud/css/fileuploader.css');
$this->set_css('assets/image_crud/css/photogallery.css');
$this->set_css('assets/image_crud/css/colorbox.css');
$this->set_js('assets/image_crud/js/jquery-1.8.2.min.js');
$this->set_js('assets/image_crud/js/jquery-ui-1.9.0.custom.min.js');
$this->set_js('assets/image_crud/js/fileuploader.js');
$this->set_js('assets/image_crud/js/jquery.colorbox-min.js');
$CI =& get_instance(); // create codeigniter reference instance.
Then:
function saveTitle(data_id, data_title)
{
$.ajax({
url: '<?php echo $insert_title_url; ?>',
type: 'post',
data: {primary_key: data_id, value: data_title,
'<?php echo $CI->security->get_csrf_token_name(); ?>':'<?php echo $CI->security->get_csrf_hash(); ?>'},
beforeSend: function()
{
$('.file-upload-messages-container:first').show();
$('.file-upload-message').html("<?php echo $this->l('saving_title');?>");
},
complete: function()
{
$('.file-upload-messages-container').hide();
$('.file-upload-message').html('');
}
});
}
simple solution. just adding the csrf_token_name and csrf_hash_value.
now for the second problem I said that it's impossible because the qq.fileuploader
uses $_GET and not $_POST, so the property params they offer just adds a get argument for you which will not be parsed by csrf_verify() method.
how to solve it: simply go to your config/config.php and add the following code to the end of it:
if(stripos($_SERVER["REQUEST_URI"],'/upload_file') === FALSE)
{
$config['csrf_protection'] = TRUE;
}
else
{
$config['csrf_protection'] = FALSE;
}
which will disable the uploading csrf checking for you ( it will be disabled just when uploading ) and it will re-enable it with the next request.
I have tested this code and it's working 100%. :)
Update: the main problem consists of that the developer of image_crud has not considered multipart encoded request ( as I can see from the new results). and he is using an old version of fineuploader. the problem is solved by fineuploader 3.0+ but not yet in image_crud which is making problems when using multipart encoded request.
Hope that I helped.
The author of image_crud has just pushed out a new version that utilizes the latest version of Fine Uploader. Problems with IE and other issues you may have run into should be fixed in the newest version. You should be able to make use of csrf tokens now without minimal reconfiguration.

Resources