Add WooCommerce Add to Cart Button to Menu with Offscreen content like Outfitter Pro

This is a guide to add a WooCommerce Add to Cart button icon to a main menu with a toggle effect that displays added shop items in a mini-cart in an overlay.

This is offscreen content displayed and closed on click, this is how the new Outfitter Pro theme uses it, in this guide it is applied to Genesis Sample Theme.

woocommerce-add-to-cart-menu

 

woocommerce-add-to-cart-toggle-items

Toggle Cart Items

 

The code snippets are prefixed with ‘prefix_’ and the language text domain set to ‘your-theme’ which you’ll need to replace with your own

 

The code in functions.php calls in additional files header-icon-menu.php and woocommerce-functions.php which will need to filed appropriately to the include path. You could lump all the code in functions.php but better practice to modularise the code into relevant directories.

The woocommerce-functions.php also calls a javascript  file in your-theme-woocommerce.js 

<?php //<~ Don't add me in
/*
* WooCommerce Add Cart to Menu - Genesis Sample Theme
*
*/
// Setup the header search icon menu.
include_once( get_stylesheet_directory() . '/lib/header-icon-menu.php' );
// Includes functions for the WooCommerce plugin.
include_once( get_stylesheet_directory() . '/lib/woocommerce/woocommerce-functions.php' );
// Repositions primary navigation menu.
remove_action( 'genesis_after_header', 'genesis_do_nav' );
add_action( 'genesis_header', 'genesis_do_nav', 13 );
// Enqueues ionicons.
add_action( 'wp_enqueue_scripts', 'prefix_offscreen_scripts_styles' );
function prefix_offscreen_scripts_styles() {
wp_enqueue_style( 'ionicons', '//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css', array(), CHILD_THEME_VERSION );
}
view raw functions1.php hosted with ❤ by GitHub

So in the above the 2 external files are being referenced, then the menu is repositioned and finally the icon file is called in – if you have your own icon then don’t bother using the last function just style it in the CSS.

<?php
add_action( 'genesis_meta', 'prefix_setup_header_icons' );
/**
* Sets up the header icon menu markup, if any.
*
* @return void
*
* @since 1.0.0
*/
function prefix_setup_header_icons() {
// Outputs the header navigation container markup.
add_action( 'genesis_header', 'prefix_header_nav_markup_open', 10 );
// Outputs the header icons markup.
add_action( 'genesis_header', 'prefix_header_icons_markup_open', 11 );
if ( class_exists( 'WooCommerce' ) && current_theme_supports( 'woocommerce' ) ) {
add_action( 'genesis_header', 'prefix_do_woocommerce_cart_icon', 12 );
}
add_action( 'genesis_header', 'prefix_header_icons_markup_close', 12 );
add_action( 'genesis_header', 'prefix_header_nav_markup_close', 13 );
}
/**
* Outputs the header icon navigation markup.
*
* @since 1.0.0
*/
function prefix_header_nav_markup_open() {
genesis_markup( array(
'context' => 'nav-container',
'open' => '<div %s>',
) );
}
/**
* Outputs the header icon navigation markup closing tags.
*
* @since 1.0.0
*/
function prefix_header_nav_markup_close() {
genesis_markup( array(
'context' => 'nav-container',
'open' => '</div>',
) );
}
/**
* Outputs the header icon navigation markup.
*
* @since 1.0.0
*/
function prefix_header_icons_markup_open() {
genesis_markup( array(
'context' => 'nav-header-icons',
'open' => '<nav itemscope="" %s>',
) );
genesis_markup( array(
'context' => 'menu-header-icons',
'open' => '<ul %s>',
) );
}
/**
* Outputs the header icon navigation markup closing tags.
*
* @since 1.0.0
*/
function prefix_header_icons_markup_close() {
genesis_markup( array(
'context' => 'menu-header-icons',
'close' => '</ul>',
) );
genesis_markup( array(
'context' => 'nav-header-icons',
'close' => '</nav>',
) );
}
/**
* Adds appropriate attributes to the header icon navigation element.
*
* @since 1.0.0
*/
add_filter( 'genesis_attr_nav-header-icons', 'prefix_header_icons_nav_attr' );
function prefix_header_icons_nav_attr( $attr ) {
$attr['itemtype'] = 'https://schema.org/SiteNavigationElement';
$attr['id'] = 'genesis-nav-header-icons';
$attr['aria-label'] = __( 'Additional navigation', 'your-theme' );
return $attr;
}
/**
* Adds appropriate attributes to the header icon menu element.
*
* @since 1.0.0
*/
add_filter( 'genesis_attr_menu-header-icons', 'prefix_header_icons_menu_attr' );
function prefix_header_icons_menu_attr( $attr ) {
$attr['id'] = 'menu-header-icons-navigation';
$attr['class'] = $attr['class'] . ' menu genesis-nav-menu';
return $attr;
}
view raw header-icon-menu.php hosted with ❤ by GitHub

This header-icon-menu.php contains all the mark up around the cart icon

<?php
add_action( 'wp_enqueue_scripts', 'prefix_woocommerce_scripts' );
function prefix_woocommerce_scripts() {
wp_enqueue_script( 'your-theme-woocommerce', get_stylesheet_directory_uri() . '/lib/woocommerce/js/your-theme-woocommerce.js', array( 'jquery' ), '1.0.0', true );
}
/**
* Outputs the WooCommerce cart button.
*
* @return string HTML output of the Show Cart button.
*
* @since 1.0.0
*/
function prefix_get_off_screen_cart_toggle() {
global $woocommerce;
$cartcount = $woocommerce->cart->cart_contents_count;
return '<a href="#" class="toggle-off-screen-cart"><span class="screen-reader-text">' . __( 'Show Shopping Cart', 'your-theme' ) . '</span> <span class="ionicons ion-android-cart"></span><span class="cart-count">' . $cartcount . '</span></a>';
}
// Adds Mini Cart.
add_action( 'genesis_after_header', 'prefix_off_screen_woocommerce_cart_output' );
function prefix_off_screen_woocommerce_cart_output( $args = array() ) {
if ( class_exists( 'WooCommerce' ) && current_theme_supports( 'woocommerce' ) ) {
$button = '<button class="toggle-off-screen-cart close"><span class="screen-reader-text">' . __( 'Hide Shopping Cart', 'your-theme' ) . '</span> <span class="ionicons ion-android-close"></span></button>';
echo '<div class="off-screen-content off-screen-cart"><div class="off-screen-container"><div class="off-screen-wrapper"><div class="wrap"><section class="widget woocommerce widget_shopping_cart">';
$defaults = array(
'list_class' => '',
);
$args = wp_parse_args( $args, $defaults );
wc_get_template( 'cart/mini-cart.php', $args );
echo '</section></div>' . $button . '</div></div></div>';
}
}
// Function to print a cart icon menu item.
function prefix_do_woocommerce_cart_icon() {
printf( '<li class="menu-item menu-item-has-toggle cart-item">%s</li>', prefix_get_off_screen_cart_toggle() );
}

This file woocommerce-functions.php calls the woocommerce needed javascript as well as adding actual cart button and mini cart in the off-screen content area.

/**
* This script adds the WooCommerce jquery cart toggle.
*
* @package your-theme\JS
* @author StudioPress
* @license GPL-2.0+
*/
( function($) {
var $body = $( 'body' ),
$content = $( '.off-screen-cart' ),
sOpen = false;
$(document).ready(function() {
// Toggles the off-screen cart content on click.
$( '.toggle-off-screen-cart' ).click(function() {
__toggleOffscreenCartContent();
});
});
// Toggles the off-screen cart content.
function __toggleOffscreenCartContent() {
if (sOpen) {
$content.fadeOut();
$body.toggleClass( 'no-scroll' );
sOpen = false;
} else {
$content.fadeIn();
$body.toggleClass( 'no-scroll' );
sOpen = true;
}
}
})(jQuery);

This javascript file your-theme-woocommerce.js is for the toggle between cart button and mini-cart in the off-screen content.

/* # WooCommerce Add to Cart Menu Icon - Number of Items
---------------------------------------------------------------------------------------------------- */
/* Site Header Navigation
--------------------------------------------- */
.site-header .nav-primary,
.site-header .nav-header-icons {
float: right;
max-width: 940px;
}
.nav-primary {
border-top: none;
}
.site-header .genesis-nav-menu li li {
margin-left: 0;
}
.header-full-width .title-area {
float: left;
width: auto;
}
.title-area {
float: left;
height: 40px;
margin-top: 5px;
padding: 0 0 0 10px;
min-width: 200px;
}
.genesis-nav-menu > .menu-item {
padding: 23px 20px;
text-align: center;
}
.genesis-nav-menu > .menu-item > a {
position: relative;
padding: 0;
}
.genesis-nav-menu .menu-item-has-toggle,
.close {
height: 60px;
padding: 18px 15px 12px 15px;
width: 60px;
vertical-align: middle;
}
button.close:focus,
button.close:hover,
.menu-toggle:focus,
.menu-toggle:hover,
.menu-item-has-toggle > a:focus,
.menu-item-has-toggle > a:hover,
.off-screen-content .genesis-nav-menu a:focus,
.off-screen-content .genesis-nav-menu a:hover {
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
.genesis-nav-menu .ionicons::before {
vertical-align: middle;
}
.genesis-nav-menu .ionicons::before, .close .ionicons::before {
font-size: 25px;
line-height: 1;
width: 30px;
height: 30px;
text-align: center;
}
.menu-item-has-toggle .cart-count {
background-color: #548200;
border-radius: 50%;
color: #fff;
font-size: 10px;
font-size: 1rem;
height: 20px;
line-height: 2;
position: absolute;
right: -10px;
top: -10px;
width: 20px;
}
/* Off-screen Content
---------------------------------------------------------------------------------------------------- */
.no-scroll {
overflow: hidden;
}
.off-screen-content {
background-color: rgba( 255, 255, 255, 1 );
display: none;
height: 100vh;
left: 0;
overflow-y: scroll;
padding: 20px;
position: fixed;
text-align: center;
top: 0;
width: 100%;
z-index: 9998;
}
.off-screen-container {
display: table;
height: 100vh;
overflow: hidden;
table-layout: fixed;
text-align: center;
width: 100%;
}
.off-screen-wrapper {
display: table-cell;
padding-bottom: 20px;
vertical-align: middle;
width: 100%;
}
.off-screen-container .close {
background-color: #fff;
color: #000;
position: absolute;
top: 40px;
right: 40px;
}
.admin-bar .off-screen-container .close {
top: 72px;
}
.off-screen-content .wrap {
margin-left: auto;
margin-right: auto;
max-width: 720px;
}
view raw style.css hosted with ❤ by GitHub

Finally some style for the cart icon, change it to suit your theme and design.

Ajax Adding Behaviour

To add items from a woocommerce archive page and update the cart items number circle immediately ensure the ajax option is unchecked in woocommerce settings.

woocommerce-uncheck-ajax

 

Demo site

 

Leave a Comment





%d bloggers like this: