Jump to content
thirty bees forum

Buttons instead of radio buttons


the.rampage.rado

Recommended Posts

I've been playing around with this idea for 2 days.

Up until now I've always used dropdowns for my size selections but I would like to make them buttons. Of course thirty bees does not offer such thing currently.

I tried editing the radio button case in product.tpl to display bootstrap buttons and hide the circle. Some js, some css and it works for Niara:

Product.tpl changes:

{elseif ($group.group_type == 'radio')}
  <div id="product-options" class="btn-group" data-toggle="buttons">
    {foreach from=$group.attributes key=id_attribute item=group_attribute}
      <label class="btn btn-outline-primary {if ($group.default == $id_attribute)} active{/if}" for="group_{$id_attribute}">
        <input type="radio" id="group_{$id_attribute}" class="d-none" name="{$groupName|escape:'html':'UTF-8'}" value="{$id_attribute}" {if ($group.default == $id_attribute)} checked="checked"{/if} autocomplete="off">
        {$group_attribute|escape:'html':'UTF-8'}
      </label>
    {/foreach}
  </div>
{/if}

Additional css in my example to make them 'table-like' (when I have mutliple sizes): 

/* Ensure buttons behave like inline blocks and center content */
#product-options .btn {
  display: inline-block; /* Inline block to align buttons horizontally */
  padding-left: 10px !important;
  padding-right: 10px !important;/* Adjust padding as needed */
  text-align: center; /* Center text horizontally */
  border: 1px solid #ccc; /* Border style */
  background-color: white; /* Background color */
  color: #333; /* Text color */
  border-radius: 3px; /* Rounded corners */
  margin: 3px; /* Space between buttons */
  min-width: 65px; /* Ensure minimum button width */
  white-space: nowrap; /* Prevent text wrapping */
  transition: background-color 0.3s ease; /* Smooth background transitions */
  outline: none; /* Remove focus outline */
  box-shadow: none !important; /* Remove any shadow */
}

/* Style for the selected state (checked radio button) */
#product-options .btn.active {
  background-color: #43b775; /* Green background for active buttons */
  color: white; /* White text for active buttons */
  border-color: #ccc; /* Keep the border color unchanged */
  box-shadow: none !important; /* Remove any box-shadow on active buttons */
}

/* Hover effect for inactive buttons */
#product-options .btn:hover {
  background-color: #d3d3d3; /* Light grey background on hover */
  color: #333; /* Keep the original text color on hover */
  border-color: #ccc; /* Keep the same border color as unselected buttons */
  box-shadow: none !important; /* Remove any box-shadow on hover */
}

/* Remove the black frame (focus outline) */
#product-options .btn:focus, #product-options .btn:active {
  outline: none; /* Remove the black focus/active border */
  box-shadow: none !important; /* Remove any shadow effect */
}

/* Style the radio button (which is hidden) */
#product-options input[type="radio"] {
  position: absolute;
  opacity: 0;
}

/* Ensure uniform text size */
#product-options .btn .label-text {
  font-weight: bold; /* Bold text */
  display: inline-block;
  width: 100%;
  text-align: center;
}

Additinal js to assign the selected button to the radio buttons and sort the buttons alphabetically (as they appear in the order they are created in BO, unlike with dropdown where it sorts them):

 

document.addEventListener('DOMContentLoaded', function() {
    const productOptionsContainer = document.querySelector('#product-options');
    
    if (productOptionsContainer) {
        const buttons = productOptionsContainer.querySelectorAll('.btn');
        
        buttons.forEach(function(button) {
            button.addEventListener('click', function() {
                buttons.forEach(function(btn) {
                    btn.classList.remove('active');
                });
                
                button.classList.add('active');
                
                const radioInput = button.querySelector('input[type="radio"]');
                if (radioInput) {
                    radioInput.checked = true;
                    
                    // Manually trigger the combination update in Thirty Bees
                    if (typeof findCombination === "function") {
                        findCombination();
                    }
                }
            });
        });
    }
});


document.addEventListener('DOMContentLoaded', function() {
    const productOptionsContainer = document.querySelector('#product-options');

    if (productOptionsContainer) {
        const buttons = Array.from(productOptionsContainer.querySelectorAll('.btn')); // Get all buttons
        
        // Extract the text values and sort them numerically or alphabetically
        buttons.sort((a, b) => {
            let valueA = a.textContent.trim();
            let valueB = b.textContent.trim();
            
            // Convert to numbers if possible, else compare as strings
            if (!isNaN(valueA) && !isNaN(valueB)) {
                return parseFloat(valueA) - parseFloat(valueB);
            } else {
                return valueA.localeCompare(valueB);
            }
        });

        // Clear the container and re-append sorted buttons
        productOptionsContainer.innerHTML = '';
        buttons.forEach(button => productOptionsContainer.appendChild(button));
    }
});

The issue is that this change does not work with Warehouse theme, I'm unable to make the button change the active combination, also the sorting does not work.

My questions are:
1. Which functions were changed for detecting the combinations in this section? Currently Warehouse's implementation only adds to the cart the default combination so the js I have here does not work.

2. Can we move the sorting in the core for radio buttons? Currently it's done with a js during the output.

3. Is somebody else interested in such development and migration of the community themes? Are there people that use radio buttons in their pages in 2024? If we implement something similar for FO, the BO should still refer to them as 'radio buttons' as this is interwoven in many many parts of the system.

4. Can this be pulled into a module that replaces this part of the theme so this module could be theme-agnostic? Something similar to https://addons.prestashop.com/it/combinazioni-personalizzazione/49820-product-combination-images-swatch-attributes.html but for the buttons.

5. Shopify has a nice functionality - Swatch King - if we can implement something similar it will be nice - https://apps.shopify.com/variant-swatch-king

The PS module and this also implement color swatches for combinations. The color swatches per combination is also a nice feature to have.
image.thumb.png.6447fdfa5f2b30545c3461bc6f2ca925.png
image.thumb.png.0f46092a009269ed504b63614c1ab7a5.png

Link to comment
Share on other sites

I did something a little different, but similar within the warehouse theme. It's not perfect, but works pretty well still. It's a construct of CSS and JS primarily on the radios. It was with @wakabayashi's help. You can see the result here https://twighockeycompany.com/hockey-sticks/senior-sticks/rogue-c-hockey-stick-senior

document.querySelector('#buy_block').addEventListener("click", function(event) {
    updateLabelsSelectedClass();
});

updateLabelsSelectedClass();

function updateLabelsSelectedClass() {

    var attributes_options = document.querySelectorAll('#attributes input');

    if (attributes_options) {
        attributes_options.forEach(function (element) {
            var label = element.closest('li').querySelector('label');
            if (label) {
                (element.checked) ? label.classList.add('labelSelected') : label.classList.remove('labelSelected');
            }
        })
    }
}

 

 

Edited by x97wehner
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...