How to display Total cost of products added in wishlist using yith woocommerce wishlist plugin? - wordpress

I'm developing E-Commerce website using Wordpress and Woocommerce plugins.
I've installed yith Woocommerce wishlist plugin for user to add product in wishlist, it's display unit product cost, add to cart button and product image.
I want to display Total product cost added in wishlist and for that add to cart button also. Please help.

To display Total product cost with YITH Woocommerce Wishlist plugin, you can do this with Jquery :
var myArray = $(".wishlist_table .amount"); // Recover all product cost
var result = 0;
for (var i = 0; i<myArray.length; i++) {
result += parseFloat(myArray[i].childNodes["0"].data); // Make the sum
}
$("#som").text(result); // Place total in a HTML element - my ID is "som" but no matter what it is
$(".remove_from_wishlist").live('click', function(){ // When user remove item with AJAX
var href = $(this).attr('href'); // Find parent
href = href.replace(/\D/g,'');
var arrayTo = $('#yith-wcwl-row-'+href+' .amount').text();
arrayTo = parseFloat(arrayTo.replace(/\u20ac/g, '')); // u20ac is unicode character for euro sign but works with just 'D' instead
var recoverTotal = $("#som").text(); // Recover the total
var result2 = recoverTotal - arrayTo;
$("#som").text(result2); // Display the final result
});
You have to put this code in a shortcode function. It works for me.

I am not sure which wishlist plugin you're using as there are a few wishlist plugins.
However, I have written a solution for this while using YITH Woocommerce Wishlist plugin. Sharing that code here if that helps.
function tnc_wishlist_summary_cart(){
global $woocommerce;
$wl_items = YITH_WCWL()->get_products();
$product_price = 0;
foreach ($wl_items as $key => $item) {
$the_product = wc_get_product($item['prod_id']);
$product_price += $the_product->get_price();
if(isset($_REQUEST['add_all_to_cart'])){
$woocommerce->cart->add_to_cart($item['prod_id']);
}
}
$output = 'Total Price: '.$product_price;
$output .= "<a href='?add_all_to_cart'>Add All to Cart</a>";
return $output;
}
add_shortcode( 'tnc-wishlist-summary', 'tnc_wishlist_summary_cart' );
Put This code in functions.php or inside a standalone plugin and put the following shortcode on the Wishlist page.
[tnc-wishlist-summary]
It will output Total Price and a link for adding all to cart. Not styled though. You need to style it according to your needs.
Thanks

Related

WooCommerce - Open the new product that the category is selected

I've been searching all over the internet for hours how to automatically assign a category to new products. When you open the new product that the category is selected.
I have two product categories (Books and FIlms) and I would like that every time we open a new product, Books are selected. In this way it will directly show the custom fields of that product category and we will speed up the creation process.
It's possible?
thanks
UPDATE
I found a code that seems to work with the posts. Any idea how I can adapt the code for products and where should I put the category I care about?
https://wordpress.stackexchange.com/questions/243462/automatically-select-categories-on-new-post-based-on-get-value
When it comes to the checkbox that should already be checked when creating a new product, you can use jQuery
Replace in-product_cat-15 with in-product_cat-{YOUR-CAT-ID}
// Define the admin_head callback
function action_admin_head() {
global $post, $pagenow;
// Only on new product pages
if( $pagenow != 'post-new.php' ) return;
?>
<script>
jQuery(function($){
$( '#in-product_cat-15' ).attr( 'checked', true );
});
</script>
<?php
}
add_action( 'admin_head', 'action_admin_head', 10, 0 );
In product categories click the Make default action of your desired category to make it as default category. For more details refer the image:
You can visit this page using this URL (replace the domain with your domain):
www.example.com/wp-admin/edit-tags.php?taxonomy=product_cat&post_type=product

Woocommerce product variation selection with buttons instead dropdown menu?

I am new to wordpress.
I am creating a ecommerge website with wordpress 4.5(latest) + woocommerge 2.5.5(latest) + storefront theme.
I have a product with 2 variations with different prices.
When I select a variation from dropdown menu displaying variation price under dropdown.
Product detail page with 2 variations shown as below:
I want to select variantions with buttons instead dropdown, and update product price on product page instead show below of dropdown.
If I create different products for each variantion and add custom html for buttons and link each variation products with each other, this works but this is very painful.
How to make variations selection with buttons instead dropdown shown as below picture
I was made variantion selection with buttons instead select box with javascript plugin.
I created a plugin and included a js file to product page that creates buttons for each variant at product page and hide select box.
Pros:
Not changed any file of wordpress core, woocommerce and storefront theme.
myplugin.php
define('MYPLUGIN__VERSION', '1.0');
function variant_selection_with_buttons() {
if (is_product()) {
#TODO serve .min.js on production
$js_file = plugins_url('/js/variant-selection-with-buttons.js', __FILE__);
wp_register_script(
'variant_selection_with_buttons_js',
$js_file,
array('jquery'),
MYPLUGIN__VERSION,
true
);
wp_enqueue_script('variant_selection_with_buttons_js');
}
}
add_action( 'wp_enqueue_scripts', 'variant_selection_with_buttons');
js/variations-selection-with-buttons.js
;(function($, window, document, undefined){
var variations = $('.variations_form').data('product_variations'),
requiredVals = {},
selectedVariation;
$('.woocommerce-variation').remove();
$('table.variations').hide();
$(variations).each(function(i, item){
var variationSlug;
$.each(item['attributes'], function(key, value){
variationSlug = value;
return;
});
requiredVals[variationSlug] = {
'price_html': item['price_html'],
'variation_description': item['variation_description'],
};
});
var $variationChangerCon = $('<div/>', {
'id': 'variationChangerCon',
'style': 'margin-bottom:5px',
});
$variationChangerCon.append('<div class="variationBtns"/>');
$('table.variations').find('select option').each(function(index){
var $option = $(this);
if (!$option.val()) return;
if ($option.is(':selected')){
selectedVariation =$option.val();
}
var $button = $('<a/>', {
'class': 'variation-btn single_add_to_cart_button button btn-info PvariationLink',
'text': $option.text(),
'style': 'margin-right:2px;',
});
$button.attr('data-slug', $option.val());
$variationChangerCon.find('.variationBtns').append($button);
});
$variationChangerCon.append('<div class="variationDesc"/>');
$variationChangerCon.insertBefore('.entry-summary div[itemprop="description"]');
$('div.product').on('click', '.variation-btn', function(){
var $this = $(this),
item = requiredVals[$this.data('slug')];
itemDesc = requiredVals[$this.data('slug')];
$('.variation-btn').removeClass('disabled');
$this.addClass('disabled');
$('table.variations select').val($this.data('slug')).trigger('change')
$('.entry-summary div[itemprop="offers"] p.price')
.html(item['price_html'])
$variationChangerCon.find('.variationDesc').html(item['variation_description']);
});
if (selectedVariation) {
$('.variationBtns .variation-btn[data-slug="'+ selectedVariation +'"]').trigger('click');
} else {
/*
If default variation not selected in admin pane
`selectedVariation` become undefined . So select first variation/
*/
$('.variationBtns .variation-btn:eq(0)').trigger('click');
}
})( jQuery, window, document, undefined );

WooCommerce Product Gallery: Swap Featured Image with Selected Thumbnail

Woocommerce displays the product gallery on a lightbox or new tab by default. I would like to display the product gallery on the box where the product image is displayed. I tried WooCommerce Dynamic Gallery but the LITE version doesn't allow me to display all the product gallery images on each product. Also, it displays the image on the product description.
Can anyone suggest me a wordpress plugin or coding that can display the product gallery dynamically ? Thanks a lot.
It's possible with some straightforward jquery (see below). You'll also need to override the default lightbox that WooCommerce includes for the gallery.
I believe that it's possible to disable it from the admin under WC -> Settings -> Products -> Display. But you can also remove the styles and scripts directly.
I haven't tested this code on a fresh install of WooCommerce--this is some modified code from a site with a heavily customized product gallery that includes video support.
You'll need to include this in your theme's functons.php file, etc. etc.
add_action( 'wp_enqueue_scripts', 'wc_remove_lightboxes', 99 );
/**
* Remove WooCommerce default prettyphoto lightbox
*/
function wc_remove_lightboxes() {
// Styles
wp_dequeue_style( 'woocommerce_prettyPhoto_css' );
// Scripts
wp_dequeue_script( 'prettyPhoto' );
wp_dequeue_script( 'prettyPhoto-init' );
wp_dequeue_script( 'fancybox' );
wp_dequeue_script( 'enable-lightbox' );
}
/* Customize Product Gallery */
/**
* Click on thumbnail to view image for single product page gallery. Includes
* responsive image support using 'srcset' attribute introduced in WP 4.4
* #link https://make.wordpress.org/core/2015/11/10/responsive-images-in-wordpress-4-4/
*/
add_action( 'wp_footer', 'wc_gallery_override' );
function wc_gallery_override()
{
// Only include if we're on a single product page.
if (is_product()) {
?>
<script type="text/javascript">
( function( $ ) {
// Override default behavior
$('.woocommerce-main-image').on('click', function( event ) {
event.preventDefault();
});
// Find the individual thumbnail images
var thumblink = $( '.thumbnails .zoom' );
// Add our active class to the first thumb which will already be displayed
//on page load.
thumblink.first().addClass('active');
thumblink.on( 'click', function( event ) {
// Override default behavior on click.
event.preventDefault();
// We'll generate all our attributes for the new main
// image from the thumbnail.
var thumb = $(this).find('img');
// The new main image url is formed from the thumbnail src by removing
// the dimensions appended to the file name.
var photo_fullsize = thumb.attr('src').replace('-300x300','');
// srcset attributes are associated with thumbnail img. We'll need to also change them.
var photo_srcset = thumb.attr('srcset');
// Retrieve alt attribute for use in main image.
var alt = thumb.attr('alt');
// If the selected thumb already has the .active class do nothing.
if ($(this).hasClass('active')) {
return false;
} else {
// Remove .active class from previously selected thumb.
thumblink.removeClass('active');
// Add .active class to new thumb.
$(this).addClass('active');
// Fadeout main image and replace various attributes with those defined above. Once the image is loaded we'll make it visible.
$('.woocommerce-main-image img').css( 'opacity', '0' ).attr('src', photo_fullsize).attr('srcset', photo_srcset).attr('alt', alt).load(function() {
$(this).animate({ opacity: 1 });
});
return false;
}
});
} )( jQuery );
</script>
<?php
}
}

Display additional product information (e.g. image caption) when hovering product image

I'm using using the WooCommerce plugin for WordPress to display my products. The thing is, when you are viewing the product category (archive), you can see the product name, image and price, but that doesn't really say all that much about exactly what the product is.
What I would like is for some more information to become available when you hover the product images. Something a bit like this.
Would it be possible to retrieve some of the information about the image, that I can enter in the WordPress media libray: title, caption alt text or description?
You can check the webshop here.
EDIT:
I found that editing the content-product.php file in the WooCommerce plugin folder, if I put this:
?>
random text
<?php
somewhere inside the php tags in the <li> section of that file, I could get 'random text' to show either above or below the product image on the product archive page. So, if I could replace that with a function that would retreive for instance the product image caption or some custom field that I can fill out for each product, that would go a long way towards solving the issue.
So, if anyone knows of a function that does this, please share it here.
hello sir just use this plugin
https://wordpress.org/plugins/woocommerce-custom-product-data-fields/
for retrieving any costume fields do like this
Retrieving multiselect value
global $wc_cpdf;
$multiselect = $wc_cpdf->get_value($post->ID, '_mymultiselect');
foreach ($multiselect as $value) {
echo $value;
}
Retrieving image value
global $wc_cpdf;
$image_id = $wc_cpdf->get_value($post->ID, '_myimage');
$size = 'thumbnail';
$image_attachment = wp_get_attachment_image($image_id, $size);
echo $image_attachment;
}
I recently did this with a website for a client. I changed the hover text for each product from "Add to Cart" to the product short description. Here is my code:
add_filter( 'woocommerce_product_add_to_cart_text', 'woo_archive_custom_cart_button_text' ); // 2.1 +
function woo_archive_custom_cart_button_text() {
//get the product object
global $product;
$id = $product->get_id();
$descript = $product->get_short_description();
//take out html from description
$descript1 = strip_tags($descript);
//shorten description length to fit the product image box
if (strlen($descript1) > 100){
$descript1 = substr($descript1, 0, 99) . '...';
}
return __( $descript1, 'woocommerce' );
}

How to update cart item meta - woocommerce

I know we can add meta for woocommerce cart item using woocommerce_add_cart_item_data hook.
Is there any way to update existing cart item meta.?
Yes, but it seems, only via accessing the cart directly:
global $woocommerce;
$woocommerce->cart->cart_contents[$cart_item_key]['whatever_meta'] = 'testing';
$woocommerce->cart->set_session(); // when in ajax calls, saves it.
I would recommend to remove and re-add the product, as other meta data could be lost (as in Phong Tran's answer).
Based on #DanielSalcedos answer, only keeping the absolute minimum required to answer the question.
I know It's been a while, but as it's still not answered, and it took me lots of sweat and a pint of blood, I share my solution here.
First
I'll assume you know how to add metadata to a cart and into an order. If not, you can have a look at pwnewbie's solution but I recommend you the full article at Wisdm labs
Wisdm's method takes many steps. First you create a PHP's session variable trough Ajax. Second, you intercept woocommerce_add_cart_item_data filter to add your Session variable to woocommerce session.
The thing about woocommerce_add_cart_item_data filter is that it gets executed in the middle of the add to cart process, so, if you add your variable to the main $wooocmmerce object, at some point, it get's stored as the add-to-cart event. (Sort of)
The idea
What if I want to edit that metadata and not any of the standard cart properties. The ideal would be to get a filter or an action that runs in the middle of saving something. The problem is that as long as we don't change anything else, there's no hook to run (I tried with woocommerce_update_cart_action_cart_updated hook that runs after coupons, quantities and removals from cart had happened, but it never fired as I never passed the validations)
My approach
In a shell, rebuild as little as possible, as much as needed. I added a synchronous ajax event to the cart form OnSubmit event. (I want my UI to be updated with my changes, so the reload must happen after my update)
AJAX:
var myFlag33322805 = true;
$('form').submit(function(e){
if(myFlag33322805){
myFlag33322805 = false;
e.preventDefault(); // Flag and prevent default to syncronize submits
var kart = []; // Will retrieve every cart item's meta
$('.cartRow').each(function(){
//This object will store your meta data and be pushed into kart array
var kitm = {
'p' : $(this).data('product_id'),
'm' : $(this).find('select[name=myMetaData]').val(),
'k' : $(this).data('key')
};
kart.push(kitm);
});
var data = {
'action': 'Ajax_Update_My_MetaData_33322805',
'k': kart
};
$.post(VKVAjax.ajaxurl, data, function (response) {
// Might do something with the response here
});
$('form').submit(); // This time, the form will submit, but AJAX wont run because of myFlag33322805 = false
}
});
The magic:
The php ajax response is a function that will receive my meta data to update (actually, all of it, updated or not), and will take the global $woocommerceobject to insert the meta data AND save it to the session:
PHP:
function fn_Update_My_MetaData_33322805(){
global $woocommerce;
$cart = $woocommerce->cart->cart_contents;
$updt = Array();
foreach ($_POST['k'] AS $item){
$product = new stdClass();
$updtCL = new stdClass();
$product->{'id'} = $item['p']; //This is product id
$product->{'mymeta'} = $item['m']; //This is metadata
$updtCL->{'krtkey'} = $item['k']; //This is product key in cart
$updtCL->{'meta'} = $product;
$updt[] = $updtCL;
}
// cycle the cart replace the meta of the correspondant key
foreach ($cart as $key => $item) {
foreach($updt as $updtitem){
if($key == $updtitem->krtkey){ // if this kart item corresponds with the received, the meta data is updated
// Update the content of the kart
$woocommerce->cart->cart_contents[$key]['vkv_AlternCart_value'] = $updtitem->meta;
}
}
}
// This is the magic: With this function, the modified object gets saved.
$woocommerce->cart->set_session();
wp_die('{"e":"ok", "Updt": "'.count($arrupdt).'"}');
}
Of course, this should be hooked as any other ajax event.
add_action('wp_ajax_nopriv_Ajax_Update_My_MetaData_33322805', 'fn_Ajax_Update_My_MetaData_33322805');
add_action('wp_ajax_Ajax_Update_My_MetaData_33322805', 'fn_Ajax_Update_My_MetaData_33322805');
Conclussion
You can update the meta data of a cart item with a synchronous Ajax call, overwritting the object directly to the $woocommerce global variable and saving it with the $woocommerce->cart->set_session(); method.
Footnotes
It's not the ideal method, and is quite risky to work directlly with the $woocommerce global. I would love to know of a better approach.
I'm newbie and my English is not good so the answer may be a little confusing.
Thank vlad274 for the advice.
My approach:
Same with Daniel Salcedo, I also try to change the metadata by editing woocommerce_sessions, but there is a problem. When adding an item to the cart, the woocommerce will create a unique cart_item_key for it by md5 (product_id + ... + metadata), then look for this cart_item_key already exists, if available, this item will be updated in quantity, otherwise will create a new item.
This means that if you change the meta value of the hat product from blue to red, then add the hat product with blue, instead of creating a new item blue hat, it will only increase the quantity of red hat, you need to change the cart_item_key if you want the cart to be updated correctly.
Changing cart_item_key is quite risky, instead we can simply remove and re-add the product. Like this
// get cart_item_key of item you want to change
$cart_item_key_old = $_POST['cart_item_key'];
// retrieve its information
$cart_item_old = WC()->cart->cart_contents[ $cart_item_key_old ];
$product_id_old = $cart_item_old['product_id'];
$quantity_old = $cart_item_old['quantity'];
$variation_id_old = $cart_item_old['variation_id'];
$variation_old = $cart_item_old['variation'];
// creating a cart_item_key with the same information except metadata
$cart_item_key_new = WC()->cart->generate_cart_id( $product_id_old, $variation_id_old, $variation_old, ['color'=>'red'] );
// check new cart_item_key already exists
$found = WC()->cart->find_product_in_cart( $cart_item_key_new );
// if true, update its quantity
if ($found != '') {
$new_quantity = $cart_item_old['quantity'] + WC()->cart->cart_contents[ $cart_item_key_new ]['quantity'];
WC()->cart->set_quantity( $cart_item_key_new, $new_quantity );
}
// else, re-add with new metadata
else {
WC()->cart->add_to_cart($product_id_old, $quantity_old, $variation_id_old, $variation_old, ['color'=>'red'] );
}
// finally delete the old item
WC()->cart->remove_cart_item($cart_item_key_old);
wp_die();
Note: If you want to submit cart form instead of page refreshes after running the above ajax, the quantity of item is likely to be overridden by the set_quantity method when woocommerce update_cart. In this case you just need to return new_quantity and change the input value by js before submitting the form.
Full code:
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
...
?>
<!-- place it anywhere within the foreach -->
<div class="box-type-field">
<select class="box-type" name="box-type" cart_item_key="<?php echo $cart_item_key ?>">
<option <?php echo $cart_item['box-type']=='boxes'?"selected":""; ?> value="boxes"><?php _e( 'Boxes', 'woocommerce' ); ?></option>
<option <?php echo $cart_item['box-type']=='bags'?"selected":""; ?> value="bags"><?php _e( 'Bags', 'woocommerce' ); ?></option>
</select>
</div>
<?php
...
}
AJAX:
$('.box-type-field .box-type').live('change', function () {
var cartItemKey = $(this).attr("cart_item_key");
var boxType = $(this).val();
$.ajax({
type : "post",
url : '<?php echo admin_url('admin-ajax.php');?>',
datatype: 'json',
data : {
action : "update_cart_boxtype",
cart_item_key : cartItemKey,
box_type : boxType,
},
success: function(cartItem) {
cartItemKey = cartItem[0];
cartItemQty = cartItem[1];
if (cartItem) $('input[name="cart['+cartItemKey+'][qty]"]').val(cartItemQty); // update quantity
$('.woocommerce-cart-form button[type="submit"]').click(); // submit form
}
})
})
PHP:
add_action( 'wp_ajax_update_cart_boxtype', 'update_cart_boxtype_init' );
add_action( 'wp_ajax_nopriv_update_cart_boxtype', 'update_cart_boxtype_init' );
function update_cart_boxtype_init() {
if ( ! WC()->cart->is_empty() ) {
$cart_item_key = (isset($_POST['cart_item_key']))?$_POST['cart_item_key'] : '';
$cart_item = WC()->cart->cart_contents[ $cart_item_key ];
$box_type = (isset($_POST['box_type']))?$_POST['box_type'] : '';
$cart_updated = false;
$cart_item_key_new = WC()->cart->generate_cart_id( $cart_item['product_id'], $cart_item['variation_id'], $cart_item['variation'], ['box-type'=>$box_type] );
$found = WC()->cart->find_product_in_cart( $cart_item_key_new );
if ($found != '') {
$new_qty = $cart_item['quantity'] + WC()->cart->cart_contents[ $cart_item_key_new ]['quantity'];
WC()->cart->remove_cart_item($cart_item_key);
wp_send_json_success([$cart_item_key_new, $new_qty]);
} else {
WC()->cart->add_to_cart($cart_item['product_id'], $cart_item['quantity'], $cart_item['variation_id'], $cart_item['variation'], ['box-type' => $box_type]);
$cart_updated = true;
WC()->cart->remove_cart_item($cart_item_key);
wp_send_json_success(false);
}
}
wp_die();
}
Step 1: Add Data in a Custom Session, on ‘Add to Cart’ Button Click
For those of you who have worked with WooCommerce might know that on the click of the ‘Add to Cart’ button the product page gets refreshed and the user data is lost. Hence, we should add the custom data from our product page to a custom session created using Ajax. This code is invoked before the WooCommerce session is created.
<?php
add_action('wp_ajax_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');
add_action('wp_ajax_nopriv_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');
function wdm_add_user_custom_data_options_callback()
{
//Custom data - Sent Via AJAX post method
$product_id = $_POST['id']; //This is product ID
$user_custom_data_values = $_POST['user_data']; //This is User custom value sent via AJAX
session_start();
$_SESSION['wdm_user_custom_data'] = $user_custom_data_values;
die();
}
Step 2: Add Custom Data in WooCommerce Session
At this step, the WooCommerce session has been created and is now available for us to add our custom data. We use the following code to add the custom data from the session we have created into the WooCommerce session. At this step, our session is also unset since the data in it has been captured and it is not needed anymore.
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,2);
if(!function_exists('wdm_add_item_data'))
{
function wdm_add_item_data($cart_item_data,$product_id)
{
/*Here, We are adding item in WooCommerce session with, wdm_user_custom_data_value name*/
global $woocommerce;
session_start();
if (isset($_SESSION['wdm_user_custom_data'])) {
$option = $_SESSION['wdm_user_custom_data'];
$new_value = array('wdm_user_custom_data_value' => $option);
}
if(empty($option))
return $cart_item_data;
else
{
if(empty($cart_item_data))
return $new_value;
else
return array_merge($cart_item_data,$new_value);
}
unset($_SESSION['wdm_user_custom_data']);
//Unset our custom session variable, as it is no longer needed.
}
}
Step 3: Extract Custom Data from WooCommerce Session and Insert it into Cart Object
At this stage, we have default product details along with the custom data in the WooCommerce session. The default data gets added to the cart object owing to the functionality provided by the plugin. However, we need to explicitly extract the custom data from the WooCommerce session and insert it into the cart object. This can be implemented with the following code.
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );
if(!function_exists('wdm_get_cart_items_from_session'))
{
function wdm_get_cart_items_from_session($item,$values,$key)
{
if (array_key_exists( 'wdm_user_custom_data_value', $values ) )
{
$item['wdm_user_custom_data_value'] = $values['wdm_user_custom_data_value'];
}
return $item;
}
}
Step 4: Display User Custom Data on Cart and Checkout page
Now that we have our custom data in the cart object all we need to do now is to display this data in the Cart and the Checkout page. This is how your cart page should look after the custom data has been added from the WooCommerce session to your Cart.
My-Cart-Page

Resources