Live WooCommerce Product Search Form using AJAX (Shortcode) - javascript

While the search form works, I need help fixing the problem that occurs when the form is empty after having been typed into.
What I mean is this:
If you start typing a search query, you start to get results. This part works fine.
But if you, while / after typing, remove the text from the search form - you get a list of ALL products.
It should only show results if and when typing and show nothing if and when empty.
Fix:
After applying a modified version of the solution offered and provided by Terminator-Barbapapa as per below, it works as intended.
The code below might not be 100% correct, but it works.
The code so far:
add_shortcode('live_search', 'live_search_function');
function live_search_function() { ?>
<input type="text" name="keyword" id="keyword" onkeyup="fetch()"></input>
<div id="productfetch"></div>
<?php
}
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() { ?>
<script type="text/javascript">
function fetch() {
if( document.getElementById('keyword').value.trim().length == 0 ) {
jQuery('#productfetch').html('');
} else {
jQuery.ajax( {
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#productfetch').html( data );
}
});
}
}
</script>
<?php
}
add_action('wp_ajax_data_fetch' , 'product_fetch');
add_action('wp_ajax_nopriv_data_fetch','product_fetch');
function product_fetch() {
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => 'product' ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h2><?php the_title();?></h2>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}

You can add a check in your fetch() function to see if your input field is empty. If so, clear the datafetch div, else run your AJAX.
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() { ?>
<script type="text/javascript">
function fetch() {
if( document.getElementById('keyword').value.trim().length == 0 ) {
jQuery('#productfetch').html('');
} else {
jQuery.ajax( {
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#productfetch').html( data );
}
});
}
}
</script>
<?php
}

Related

Update post_author on button click via ajax request

I'm somewhat new to PHP and WordPress.
I'm attempting to update a posts "post_author" when a logged-in user, who is the author of this post, clicks on a button on the post page itself.
This is my code currently
PHP within functions.php file
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback() {
$post = get_post($post_id);
if ($post->post_author == get_current_user_id()) {
wp_update_post(array(
'ID' => $post_id,
'post_author' => 1
));
}
wp_die();
}
Front end JS on the post itself
<script>
$(document).ready(function() {
$("#submit").click(function() {
var ajaxurl = 'MYDOMAINNAME/wp-admin/admin-ajax.php';
$.ajax ({
url: ajaxurl,
type: 'POST',
data: {
action: 'my_action',
id: 1234
},
})
});
});
</script>
<button id="submit">Change Author</button>
Ajax is quite new to me also so just trying to wrap my head around this and ensuring I'm approaching this the best way.
Use this code. You have use $_POST["id"] instead of $post_id.
footer.php
<script>
jQuery(document).ready(function() {
jQuery("#submit").click(function() {
var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
jQuery.ajax ({
url: ajaxurl,
type: 'POST',
data: {
action: 'my_action',
id: 42
},
})
});
});
</script>
functions.php
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback($post) {
$post_id = $_POST["id"];
$post = get_post($post_id);
if ($post->post_author == get_current_user_id()) {
wp_update_post(array(
'ID' => $post_id,
'post_author' => 1
));
}
wp_die();
}
Update to my question, I was able to resolve the issue I was facing.
A couple of issues I was able to isolate were as follows.
I had a conflicting function that was triggering off of the save_post hook, which was causing the author to change back to the current user when triggering the wp_update_post() function. To resolve that I added a remove action before the function happens. See below.
remove_action('save_post', 'change_pos_auth');
remove_action('acf/save_post', 'change_pos_auth');
I used the following to get the ID of the current post when making an ajax request on that post page.
$url = wp_get_referer();
$post_id = url_to_postid( $url );

WooCommerce set cart quantity with AJAX?

I've now been scratching my head about this for several days and need some pointers.
I'm making a custom theme totally from scratch for a WooCommerce site and now I'm trying to get the cart functionality to work. I'm stuck at trying to have buttons (+/-) for updating the quantity of a product item in the cart.
The problem to me seems to be that the WC() I use inside functions.php is not the same instance as the current frontend-session, or something among those lines. At least my thought for now.
If I've debugged correctly the WC()->cart->set_quantity($cart_item_key, 0) gives no error (if using number 0), all other numbers gives '500 (Internal Server Error)'. But even with 0 quantity in cart is never changed nonetheless.
I've enqueued the scripts correctly so the AJAX function call executes fine when the button is clicked.
Here's my HTML and PHP (simplified)
<div class="cart-items">
<?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
<div class="cart-item">
<div class="quantity" id="cart-qty-<?php echo $cart_item_key ?>">
<button class="minus" id="cart-subtract"
onclick="updateCartQuantity('<?php echo $cart_item_key ?>', '<?php echo $cart_item['quantity'] ?>', -1)">-</button>
<p><?php echo $cart_item['quantity'] ?></p>
<button class="plus" id="cart-add">+</button>
</div>
</div>
<? endforeach; ?>
</div>
Here's my JS (inside a file called shopping-ajax.js)
function updateCartQuantity(cart_item_key, current_qty, value) {
function qty_cart() {
jQuery.ajax({
type: "POST",
url: my_ajax_object.ajax_url,
data: {
action: "update_cart",
hash: cart_item_key,
quantity: current_qty,
value: value,
},
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
},
});
}
qty_cart();
}
Here's my PHP function (inside functions.php)
function updateCartQuantity(){
$cart_item_key = $_REQUEST['cart_item_key'];
$quantity = $_REQUEST['quantity'];
$value = $_REQUEST['value'];
WC()->cart->set_quantity($cart_item_key, $quantity + $value);
echo $quantity + $value;
wp_die();
}
add_action( 'wp_ajax_nopriv_update_cart', 'updateCartQuantity' );
add_action( 'wp_ajax_update_cart', 'updateCartQuantity' );
A massive thanks for any help or pointer in advance!
You should manage product qty according to the qty input box(change qty).
My JS:
location: theme directory -> js -> custom.js
jQuery( function( $ ) {
$( document ).on( 'change', 'input.qty', function() {
var $thisbutton = $(this);
var item_hash = $( this ).attr( 'name' ).replace(/cart\[([\w]+)\]\[qty\]/g, "$1");
var item_quantity = $( this ).val();
var currentVal = parseFloat(item_quantity);
$.ajax({
type: 'POST',
url: cart_qty_ajax.ajax_url,
data: {
action: 'my_cart_qty',
hash: item_hash,
quantity: currentVal
},
success: function(response) {
jQuery(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);
//jQuery(document.body).trigger('update_checkout');
}
});
});
});
fuctions.php -
Setup Enqueue Ajax Scripts:
function enqueue_cart_qty_ajax() {
wp_register_script( 'my_cart_qty-ajax-js', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ), '', true );
wp_localize_script( 'my_cart_qty-ajax-js', 'cart_qty_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
wp_enqueue_script( 'my_cart_qty-ajax-js' );
}
add_action('wp_enqueue_scripts', 'enqueue_cart_qty_ajax');
Ajax call -
function ajax_my_cart_qty() {
// Set item key as the hash found in input.qty's name
$cart_item_key = $_POST['hash'];
// Get the array of values owned by the product we're updating
$threeball_product_values = WC()->cart->get_cart_item( $cart_item_key );
// Get the quantity of the item in the cart
$threeball_product_quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key );
// Update cart validation
$passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $threeball_product_values, $threeball_product_quantity );
// Update the quantity of the item in the cart
if ( $passed_validation ) {
WC()->cart->set_quantity( $cart_item_key, $threeball_product_quantity, true );
}
// Refresh the page
echo do_shortcode( '[woocommerce_cart]' );
die();
}
add_action('wp_ajax_my_cart_qty', 'ajax_my_cart_qty');
add_action('wp_ajax_nopriv_my_cart_qty', 'ajax_my_cart_qty');

How to load more logo's with ajax?

I found a solution how to get a load more button that displays more content on click, but it was for posts, I want to make it work for my custom post type 'Klanten'.
I tried editing the code to match my post type, but I get an error: "Undefined index: offset"
functions.php
wp_enqueue_script( 'dfib-theme-custom', get_template_directory_uri() .'/js/custom.js', array('jquery') );
wp_localize_script( 'dfib-theme-custom', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')) );
add_action( 'wp_ajax_load_more_posts', 'load_more_posts' );
add_action( 'wp_ajax_nopriv_load_more_posts', 'load_more_posts' );
function load_more_posts(){
global $post;
$args = array('post_type'=>'klanten', 'posts_per_page'=> 4, 'offset'=> $_POST['offset']);
$rst=[];
$query = new WP_Query($args);
if($query->have_posts()):
while($query->have_posts()):$query->the_post();
$rst[] = $post;
endwhile;
wp_reset_postdata();
$offset = $_POST['offset']+4;
endif;
wp_send_json_success(array('klanten'=>$rst, 'offset'=>$offset));
}
custom.js
$('#load_more_posts').on('click', function(e){
console.log('hi');
e.preventDefault();
var $offset = $(this).data('offset');
console.log('var'+$offset);
$.ajax({
method: 'POST',
url: ajax_object.ajax_url,
type: 'JSON',
data: {
offset: $offset,
action: 'load_more_posts'
},
success:function(response){
console.log(response);
$('#load_more_posts').data('offset', parseInt(response.data.offset));
}
});
})
php-file
$query = new WP_Query( array(
'post_type' => 'klanten',
'posts_per_page' => 4,
'offset' => 0,
'paged' => 1,
'order' => 'ASC',
'orderby' => 'rand',
) );
if ( $query->have_posts() ) { ?>
<div class="klanten__wrapper">
<?php
while ( $query->have_posts() ) :
$query->the_post();
?>
<div class="logo__wrapper">
<img class="klant__logo" src="<?php the_post_thumbnail_url(); ?>">
</div>
<?php endwhile; ?>
<div id="load_more_posts" class="loadmore">Load More...</div>
</div>
<?php
wp_reset_postdata();
return ob_get_clean();
}
Console log
I want to show 4 logo's (elements), and load 4 more each time someone clicks the loadmore button
Replace this
<div id="load_more_posts" class="loadmore" data-offset="4">Load More...</div>
You need to return ajax data with logo array and then append data like below code.
AJAX call
$('#load_more_posts').on('click', function(e){
console.log('hi');
e.preventDefault();
var $offset = $(this).data('offset');
console.log('var'+$offset);
$.ajax({
method: 'POST',
url: ajax_object.ajax_url,
type: 'JSON',
data: {
offset: $offset,
action: 'load_more_posts'
},
success:function(response){
console.log(response);
var html = "";
$(response.data.klanten).each(function(index,value) {
html += '<div class="logo__wrapper"> <img class="klant__logo" src="'+value.post_thumbnail+'"></div>'
});
$('.logo_wrapper').append(html);
$('#load_more_posts').data('offset',
parseInt(response.data.offset));
}
});
})
HTML Code
<div class="klanten__wrapper">
<div class="logo_wrapper">
<?php
while ( $query->have_posts() ) :
$query->the_post();
?>
<div class="logo__wrapper">
<img class="klant__logo" src="<?php the_post_thumbnail_url(); ?>">
</div>
<?php endwhile; ?>
<div>
<div id="load_more_posts" class="loadmore">Load More...</div>
</div>
function.php
wp_enqueue_script( 'dfib-theme-custom', get_template_directory_uri() .'/js/custom.js', array('jquery') );
wp_localize_script( 'dfib-theme-custom', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')) );
add_action( 'wp_ajax_load_more_posts', 'load_more_posts' );
add_action( 'wp_ajax_nopriv_load_more_posts', 'load_more_posts' );
function load_more_posts(){
global $post;
$args = array('post_type'=>'klanten', 'posts_per_page'=> 4, 'offset'=> $_POST['offset']);
$rst=[];
$query = new WP_Query($args);
if($query->have_posts()):
while($query->have_posts()):$query->the_post();
$rst[] = $post;
$post_thumbnail = get_the_post_thumbnail($post->id);
$rst['post_thumbnail'] = $post_thumbnail;
endwhile;
wp_reset_postdata();
$offset = $_POST['offset']+4;
endif;
wp_send_json_success(array('klanten'=>$rst, 'offset'=>$offset));
}
I got help from a colleague and he figured it out. I added this in my js-file (jQuery)
// Counter for logos
var logoCount = $('.logo__wrapper').length;
var counter = 12;
// Show only first 12 logos
$('.logo__wrapper:nth-of-type(1n+13)').addClass('is-hidden');
// Load more logos button click
$('#load_more_posts').on('click', function (e) {
// Loop hidden logo's
$('.logo__wrapper.is-hidden').each(function (i) {
// Hide button if no more logo's
if (counter++ === logoCount) {
$('#load_more_posts').hide();
$('.loadmore__end').toggle();
}
// Show next 12 logos
if (i < 12) {
$(this).removeClass('is-hidden');
}
// Break loop after 12 logos
else {
return false;
}
});
});

Wordpress AJAX search not working

I am trying to create a search functionality with AJAX so it will load posts. It currently does not show the results.
I took this code from another post and played around with it as the completed code was sent privately.
Any help would be greatly appreciated.
functions.php file code
// the ajax function
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => 'post' ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h2><?php the_title();?></h2>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}}
Script (in functions.php)
// add the ajax fetch js
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() {
?>
<script type="text/javascript">
function fetch(){
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
</script>
html
<input type="text" name="keyword" id="keyword" onkeyup="fetch()">
<div id="datafetch">Search results will appear here</div>
You might want to update the method name to 'POST' as javascript is case sensitive
function fetch(){
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
You also might want to do an async call which needs callback as above approach will do synchronous call. Check this answer for callback approach
jQuery: Return data after ajax call success
there are some typos in your code like an extra } and a mising } later in php code. Please try:
functions.php
// the ajax function
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => 'post' ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h2><?php the_title();?></h2>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
// add the ajax fetch js
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() {
?>
<script type="text/javascript">
function fetch_search() {
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
</script>
<?php
}
html
<input type="text" name="keyword" id="keyword" onkeyup="fetch_search()">
<div id="datafetch">Search results will appear here</div>

Autocomplete implementation in cakephp 2.4

Hello Guys i am very new to cakephp and i want to implement autocomplete in my project. I have downloaded two javascript file jquery.autocomplete.js and jquery.autocomplete.min.js and placed them both in my webroot directory. i have a field named city in my database which i have to autocomplete. the problem is my sutocomple is not firing or even not showing alert when key is pressed.
my javascript code is
<script src="../../webroot/js/jquery.autocomplete.js"
type="text/javascript"></script>
<script src="../../webroot/js/jquery.autocomplete.min.js"
type="text/javascript"></script>
$(function() {
$('#Usercity').autocomplete({
alert("ashish");
//dataType: "json"
minLength: 1,
source: function( request, response ) {
$.ajax({
url: "/User/autoComplete",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
term: request.term
},
success: function( data ) {
response( $.map( data, function( el ) {
return { label: el.id, value: el.city }
}));
}
});
}
});
});
</script>
echo $this->Form-
>input('city',array('type'=>'text','label'=>'City'));
Controller code
public function autoComplete() {
Configure::write('debug', 0);
$this->layout = 'ajax';
$query = $_GET['term'];
$items = $this->User->find('all', array(
'conditions' => array('User.city LIKE' => $query . '%'),
'fields' => array('city')));
foreach ($items as $item) {
$data[] = $item['Item'];
}
$data = json_encode($data);
echo $data;
exit;
}
}
To fix problem
the problem is my sutocomple is not firing or even not showing alert
when key is pressed.
you need to load jQuery lib before autocomplete.js something like
<script src="../js/jquery-last.version.number.js"></script>
or if you want cakephp to do it for you (no need to write '.js')
echo $this->Html->script(array(
'jquery-1.10.2.min',
'jquery.autocomplete'
));

Categories

Resources