Skip to content

Instantly share code, notes, and snippets.

@Garconis
Last active September 27, 2023 03:26
Show Gist options
  • Save Garconis/b750bee39aed5f0e8e596bb2fac16cab to your computer and use it in GitHub Desktop.
Save Garconis/b750bee39aed5f0e8e596bb2fac16cab to your computer and use it in GitHub Desktop.
WooCommerce | Expand and collapse child categories with custom toggle in the sidebar widget | https://i.gyazo.com/e1a39ed551096444134324bb429722bb.mp4
/* - woo cat toggling elements, injected via jQuery - */
/* make list item be relative, to be able to position toggle within this item, if desired */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent {
position: relative;
}
/* the new toggle element wrapper, which is added via jQuery */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle {
cursor: pointer;
display: inline-block;
text-align: center;
margin-left: 0.5em;
width: 1.5em;
line-height: 1em;
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
transition: all 0.4s ease;
width: 20px;
height: 20px;
background: rgba(0,0,0,0.05);
text-align: center;
line-height: 20px;
border-radius: 50%;
}
/* when it's popped, style the toggle wrapper differently */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle.cat-popped {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
background: rgba(0,24,113,1);
color: white;
}
/* toggle icon */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle::before {
font-weight: normal;
font-style: normal;
font-size: 24px;
text-transform: none;
speak: none;
content: '+';
line-height: 20px;
width: 20px;
height: 20px;
text-align: center;
}
/* toggle icon when triggered */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle.cat-popped::before {
content: '\2013';
}
/* hide sub cats by default */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle ~ ul.children {
overflow: hidden;
max-height: 0;
transition: all 0.4s ease;
}
/* show sub cats when triggered via jQuery toggle */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle.cat-popped ~ ul.children {
max-height: 300px;
}
jQuery(function($){
// add a new toggle element after the parent category anchor
$( "<div class='woo-cat-toggle'></div>" ).insertAfter( "#sidebar .widget_product_categories .product-categories > .cat-item.cat-parent > a" );
// when the new toggle element is clicked, add/remove the class that controls visibility of children
$( "#sidebar .widget_product_categories .product-categories .woo-cat-toggle" ).click(function () {
$(this).toggleClass("cat-popped");
});
// if the parent category is the current category or a parent of an active child, then show the children categories too
$('#sidebar .widget_product_categories .product-categories > .cat-item.cat-parent').each(function(){
if($(this).is('.current-cat, .current-cat-parent')) {
$(this).children('.woo-cat-toggle').toggleClass("cat-popped");
}
});
});
@PythonMillionaire
Copy link

Sorry to bother you but do you happen to have the link to the page for which you built this solution so that I can take a look at its source code? The structure of my website is completely different (https://saddhustore.com.br/moda/?product_cat=feminino). I don't know much CSS or JQuery and I'm trying to make it work for my website as well.

image

Thanks a lot!

@escozul
Copy link

escozul commented Jan 19, 2022

Why don't you test it by making a copy of my fiddle?
https://jsfiddle.net/escozul/nrxek35q/30/
you need to play around with the classes and the ids to match your product categories tree

@PythonMillionaire
Copy link

Hi @escozul!

Thanks a lot for replying. Perfect!! Exactly what I was looking for. Thanks a lot!

@PythonMillionaire
Copy link

PythonMillionaire commented Jan 21, 2022

I struggled to make it work but, in the end, failed (though I learn a bunch of JQuery and CSS, which was neat). Then it occurred to me that I should check my theme to see if it was the culprit for the different structure. It wasn't, so I researched and found out it was all because of the shittyass Gutenberg block thing so all I had to do was install a plugin called "Disable Gutenberg" and, in its settings, mark both checkboxes.

image

After that, all I needed to do is replace "sidebar" with "secondary" as described above. Now IT WORKS and I can customize it to fit my own needs.

EDIT: JUST ONE THING. I just noticed that when a sub-category is expanded the new items that should have appear are cut off and become invisible instead of being moved downThis can be seen in @escozul's JSFiddle as well under category "ΒΡΕΦΙΚΟ". Simply changing

/* show sub cats when triggered via jQuery toggle */
#sidebar .widget_product_categories ul.product-categories > li.cat-parent .woo-cat-toggle.cat-popped ~ ul.children {
max-height: 300px;
}

from 300px to something enormous fixed it.

Thank you all so much for all your help! I love you forever

@tacuar
Copy link

tacuar commented Feb 12, 2022

So amazing codes! Worked like a charm!!!

Just one question, can anyone tell how to put the toggle icon on the left side, i mean, before the "category name"?

@PythonMillionaire
Copy link

What do you mean? It should appear on the left by default. I had to change the CSS to position it to the right instead

@tacuar
Copy link

tacuar commented Feb 13, 2022

well, just realized i could simply replace that After with Before, as simple as that. Thanks all guys!!!

@Garconis
Copy link
Author

FYI, here is a version for use with a widget that uses the block method. You'll need to update the block ID to your proper ID:

jQuery(function($){
	// add a new toggle element after the category count
	$( "<div class='woo-cat-toggle'></div>" ).insertAfter( "#block-12 .wp-block-woocommerce-product-categories .wc-block-product-categories-list > .wc-block-product-categories-list-item > .wc-block-product-categories-list-item-count" );
	// when the new toggle element is clicked, add/remove the class that controls visibility of children
	$( "#block-12 .wp-block-woocommerce-product-categories .wc-block-product-categories-list .woo-cat-toggle" ).click(function () {
		$(this).toggleClass("cat-popped");
	});
	// check each of the list items (each li)
	$('#block-12 .wp-block-woocommerce-product-categories .wc-block-product-categories-list > .wc-block-product-categories-list-item').each(function(){
		// see if the list item DOES have a ul child in it with a class used for category wrapper, meaning this list DOES seem to have any subcategories
		if($(this).find('ul.wc-block-product-categories-list').length !== 0) {
			// if it did have a ul with that class, then we add a class to the list item to let us know it does have children
			$(this).addClass("cat-children-yes");
		}
		else {
			// otherwise it did not find a ul child with that class, so it seems to not have any child categories, so we add a class to let us know
			$(this).addClass("cat-children-no");
			// we also then find and remove the toggle div we added earlier
			$(this).find('.woo-cat-toggle').remove();
		}
	});
	// if the parent category is the current category or a parent of an active child, then show the children categories too
	$('#block-12 .wp-block-woocommerce-product-categories .wc-block-product-categories-list > .wc-block-product-categories-list-item').each(function(){
		// FYI this doesn't work for block sidebar, since it doesn't have proper classes to know if it's the current category or not, so this won't actually auto pop them as coded
		if($(this).is('.current-cat, .current-cat-parent')) {
			$(this).children('.woo-cat-toggle').toggleClass("cat-popped");
		} 
	});
});

@escozul
Copy link

escozul commented May 19, 2022

Hello @PythonMillionaire,

I'm trying to find where in the jsfiddle those categories disappear. I can't find it. Could you please explain more thoroughly?
I think I'm missing an error here that is right in front of me.

@GeriSoft
Copy link

Thank you for this great solution :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment