Archived topic
How To Make a Toggle Switch Pricing Table
11 replies · Started by _blank on November 24, 2021
Hello,
How To Make a Toggle Switch Pricing Table using GeneratePress Premium and GenerateBlocks Pro with a clean and light code please? Price table with monthly/annual button, example
Thanks :)
Best regards.
Hi Olivier,
This is possible with a bit of custom JS.
Here's what you can do:
1.) Create the button layout for toggle. Add an HTML anchor to the buttons. (example: annual-price, monthly-price.) Add class as well (example: price-toggle-btn)
2.) Create the grid layout for the first tab and second tab to be toggled. Add class to both of their wrapper containers (example: price-table ). Add an HTML anchor to their container wrappers as well. (example: annual-price-table, monthly-price-table.)
After making layout, add this CSS:
.price-tables.active-tab { display: flex; }
.price-tables { display: none; }
and then hook this script on the wp_footer of the site. (you can do this with Hook Element).
<script>
let pricing_toggle_btn = document.querySelectorAll('.price-toggle-btn');
let PriceTables = document.getElementsByClassName('price-tables');
function toggle_price_handle_click(evt) {
for (var y = 0; y < pricing_toggle_btn.length; y++) {
if ( pricing_toggle_btn[y] == evt.target ) {
evt.preventDefault();
targetElement = document.querySelector(evt.target.hash+'-table');
remove_active_tables();
targetElement.classList.add('active-tab');
}
}
}
function remove_active_tables() {
for (var i = 0; i < PriceTables.length; i++) {
PriceTables[i].classList.remove('active-tab');
}
}
window.addEventListener("click", toggle_price_handle_click);
</script>
Note: If you want one of the tables to display by default, add active-tab on its additional CSS.
Hi Elvin,
Thanks :)
Best regards.
No problem. Glad to be of any help. :D
Hi Elvin,
This solution did not work for me. What I did can be seen @ https://grafabric.com/ink/pricing-table/ and I have created a 2,5 minutes screenshot video showing the block entries @ https://grafabric.com/videos/toggle.mp4
Could this have something to do with the GP updates (This post is dated 2021)?
I can provide admin login if needed. Thank you very much
Hi there,
its probably this:
1.) Create the button layout for toggle. Add an HTML anchor to the buttons. (example: annual-price, monthly-price.) Add class as well (example: price-toggle-btn)
I think Elvin meant the URL should include the anchor eg. URL = #annual-price
As this line of the JS:
targetElement = document.querySelector(evt.target.hash+'-table');
is grabbing the hash from the URL not the blocks ID.
Thank you very much but I have tried with both buttons and containers anchors as links but nothing changes. I have also tried full URLs as links for the buttons eg: https://grafabric.com/ink/pricing-table/#monthly-price-table but still no luck. I think problem is both grid containers are always visible hence links don't work.
Personally i would approach it like so:
1. for the tab buttons i would use a custom HTML radio form. This allows a correct Toggle option ie. its either Monthly or its Yearly:
<form id="diggeddy-pricing-form" class="diggeddy-pricing-form">
<input type="radio" id="diggeddy-monthly" name="diggeddy-form-switch" value="monthly" checked="">
<label for="diggeddy-monthly">Monthly</label>
<input type="radio" id="diggeddy-yearly" name="diggeddy-form-switch" value="yearly">
<label for="diggeddy-yearly">Yearly</label>
<span class="radio-slider"></span>
</form>
2. Which can be styled with some CSS:
input[name="diggeddy-form-switch"] {
width: 0;
height: 0;
position: absolute;
left: -9999px;
}
input[name="diggeddy-form-switch"]+label {
display: block;
padding: 15px;
position: relative;
cursor: pointer;
box-sizing: border-box;
}
input[name="diggeddy-form-switch"]:not(:checked)+label {
opacity: 0.7;
}
.diggeddy-pricing-form {
display: flex;
box-sizing: border-box;
position: relative;
z-index: 1;
width: 100%;
background-color: #eee;
border-radius: 8px;
overflow: hidden;
}
.diggeddy-pricing-form label {
flex: 1 0 50%;
text-align: center;
}
.diggeddy-pricing-form .radio-slider {
display: block;
width: calc(50% - 10px);
border-radius: 6px;
background-color: #fff;
position: absolute;
left: 5px;
top: 5px;
bottom: 5px;
transform: translate3d(0, 0, 0);
transition: transform 0.3s ease-in-out;
z-index: -1;
}
.diggeddy-pricing-form.active .radio-slider {
transform: translate3d(calc(100% + 10px), 0, 0);
}
3. Now for our Javscript:
// Select the target Table element
const diggeddyPricingTable = document.querySelector('#diggeddy-price-table');
// Select the Input Form and Input Fields
const diggeddyPricingForm = document.querySelector('#diggeddy-pricing-form');
const diggeddyRadios = document.querySelectorAll('input[name="diggeddy-form-switch"]');
// Add event listener on form buttons
diggeddyRadios.forEach(radio => {
radio.addEventListener('click', function () {
// get the selected inputs value
diggeddyRadioVal = radio.value;
// add remove the yearly class from the table
if (diggeddyRadioVal == 'yearly') {
diggeddyPricingTable.classList.add('yearly');
diggeddyPricingForm.classList.add('active');
} else {
diggeddyPricingTable.classList.remove('yearly');
diggeddyPricingForm.classList.remove('active');
}
});
});
4. Now after the Radio button form add a Container Block with the ID of #diggeddy-price-table
The script will do toggle two classes:
1. On the radio form it will toggle the active class which is used in the above CSS
2. On the container it will toggle the yearly class which you can use in your own CSS.
5. Inside your Container add your two grids, one for Monthly with a class of monthly-price and one for yearly with a class of yearly-price
6. You can use the parent container class to to hide them on condition:
#diggeddy-price-table:not(.yearly) .yearly-price,
#diggeddy-price-table.yearly .monthly-price {
display: none !important;
}
Many thanks David,
This solution did not work because I could not find a way to add custom div ID to the container and when I do it manually Gutenberg changes the blocks into a classic block which stops the functions. Is there a way to add custom ID to the container bu using add custom attribute function? By the way I managed to find a way in youtube https://www.youtube.com/watch?v=91bCzjUb49I and it works nicely :)
Any block including the Container Block, in Advanced there is the HTML Anchor field that is the ID field.
Many thanks, I didn't know anchors could be used for div ID as well :) Now I know.. Great support :)
Yeah they could have made that clearer !