Skip to main content
GUIDE: Make conditional steps

Conditionally disable step products based on steps above it

Updated over a week ago

Biscuits Bundles frontend UI displaying conditional steps


Customisation Guide

In this guide we will customise Biscuits Bundles App to conditionally disable products in a related step.

What this custom code will change:

  • Create data to dictate which products will trigger another steps products to become disabled

  • Use toggleStepProducts to ensure only 1 product is selected in the Parent Step

  • Use linkConditionalProducts to disable products matching the "selected product" from the master step


Terminology

For this customisation we will be using the following terminology:

In our example above the Cake is our "Selected Product",

Step 1 is our "Parent Step",

Step 2 is our "Child Step",

Cookie Bag is a "Disabled Product"

Selected Product

The selected (active) product in the Parent Step

Parent Step

The step in which a Selected Product can be chosen

Child Step

The step containing the products that will be disabled from the Parent Step

Disabled Product

The product belonging to the Child Step that has been marked by the Selected Product to be disabled

App block settings are template specific.

If you have multiple bundles and you need to set different Custom JS on each bundle, you will need to create a product template for each bundle.


1. Configure in Biscuits Bundle App

To have our bundle setup correctly for this customisation you will need to make sure your bundle step matches the following settings.

  1. All steps have "Auto Disable" feature turned off. You can find this under Display Options

2. Both your Parent Step (Step 1) and Child Step (Step 2) products are set to variant cards.

3. Your Master Step (Step 1) is selection type: Single


2. Add the Custom JS

  1. Customise the custom codes data

    • Set StepNumbers to the step we want the toggle effect on (Step 1) - the Parent Step

    • Create our related steps array

Key

Description

Value Example

Related Step

parentStep

step number of the Parent Step

1

childStep

step number of the Child Step

conditions

object of key value pairs,

value1: value2
Where value1 is a Selected Product and value2 is

CUSTOM JS CODE

document.addEventListener('BiscuitsBundleForm:ready', () => {
let stepNumbers = [1];
let relatedSteps = [
{
parentStep: 1,
childStep: 2,
conditions: {
40856963383369: 40941625245769,
40941624623177: 40941626064969,
40941624655945: 40941626064969,
40856963416137: 40941625245769
}
}
];

toggleStepProducts(stepNumbers);
linkConditionalProducts(relatedSteps);
});

function toggleStepProducts(stepNumbers){
if (!stepNumbers){
return;
}
stepNumbers.forEach(function(stepNumber){
let step = document.querySelector('[data-biscuits-step="'+ stepNumber+'"');
if (step.dataset.biscuitsSelection != 's'){
return;
}
let productItems = step.querySelectorAll('.biscuits-bundle-item');

productItems.forEach(function(productItem){
productItem.addEventListener('biscuits--product-selection', function(event){
if (event.detail.active){
let alreadySelectedItems = step.querySelectorAll('.biscuits-bundle-item.biscuits--active');
alreadySelectedItems.forEach(function(selectedItem){
if (selectedItem != productItem){
selectedItem.click();
}
});
}
});
});
});
}

function linkConditionalProducts(relatedSteps) {
if (!relatedSteps){
return;
}
relatedSteps.forEach(function(relatedGroup){
let parentStep = document.querySelector('[data-biscuits-step="'+ relatedGroup.parentStep+'"');
let childStep = document.querySelector('[data-biscuits-step="'+ relatedGroup.childStep+'"');
if (parentStep.dataset.biscuitsSelection != 's' || childStep.dataset.biscuitsSelection != 's'){
return;
}

let productItems = parentStep.querySelectorAll('.biscuits-bundle-item');
if (!productItems){
return;
}
productItems.forEach(function(productItem){
productItem.addEventListener('biscuits--product-selection', function(event){
if (!event.detail.active){
return;
}
let selectedVariantId = event.detail.variant_id;
let variantIdToDisable = relatedGroup.conditions[selectedVariantId];
if (variantIdToDisable){
let currentDisabledItems = childStep.querySelectorAll('.biscuits-bundle-item.biscuits--disabled');
currentDisabledItems.forEach(function(disabledItem){
if (disabledItem.dataset.biscuitsId != variantIdToDisable){
disabledItem.classList.remove('biscuits--disabled');
}
});
let itemToDisable = childStep.querySelector('[data-biscuits-id="'+ variantIdToDisable +'"]');
if (itemToDisable){
if (itemToDisable.classList.contains('biscuits--active')){
itemToDisable.click();
}
itemToDisable.classList.add('biscuits--disabled');
}
}
else {
let currentDisabledItems = childStep.querySelectorAll('.biscuits-bundle-item.biscuits--disabled');
currentDisabledItems.forEach(function(disabledItem){
disabledItem.classList.remove('biscuits--disabled');
});
}
});
});
});
}

Paste your edited code into the custom JS field in the biscuits bundle app block

  • If you need help finding where this is follow this guide.


3. Add the Custom CSS

We need to add some CSS to tell our disabled grid items they can't be clicked.

CUSTOM CSS CODE

.biscuits-bundle-item.biscuits--disabled {
opacity: 0.5;
pointer-events: none;
}

CUSTOM CSS CODE

Paste your edited code into the custom CSS field in the biscuits bundle app block

  • If you need help finding where this is follow this guide.


Testing

Always thoroughly test your custom JS to ensure if behaves as expected across all supported browsers and devices.

Stuck or got questions?

Use the chat widget below, or reach out to us at [email protected]

Happy coding, and thanks for teaming up with Biscuits Bundles!

Did this answer your question?