the.rampage.rado Posted October 24 Posted October 24 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. 2
x97wehner Posted October 24 Posted October 24 (edited) 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 October 24 by x97wehner 2
the.rampage.rado Posted October 26 Author Posted October 26 Something that I think is working, of course not perfect as some things are done in js and not at backend but... Warehouse's product.tpl {elseif ($group.group_type == 'radio')} <div id="product-options"> {foreach from=$group.attributes key=id_attribute item=group_attribute} <input type="radio" id="attribute_{$id_attribute}" class="attribute_radio" name="{$groupName|escape:'html':'UTF-8'}" value="{$id_attribute}" {if ($group.default == $id_attribute)} checked="checked"{/if} hidden /> <label for="attribute_{$id_attribute}" class="btn {if $group.default == $id_attribute}active{/if}"> <span class="label-text">{$group_attribute|escape:'html':'UTF-8'}</span> </label> {/foreach} </div> {/if} css: /* Warehouse buttons css START */ /* Ensure buttons behave like inline blocks and center content */ #product-options .btn { display: inline-block; padding-left: 10px !important; padding-right: 10px !important; text-align: center; border: 1px solid #ccc; border-color: #ccc; background-color: white; color: #333; font-weight: normal; margin: 3px; min-width: 65px; white-space: nowrap; transition: background-color 0.3s ease; outline: none; box-shadow: none !important; } /* Style for the selected state (checked radio button) */ #product-options .btn.active { background-color: #55c65e; color: white; } /* Hover effect for inactive buttons */ #product-options .btn:hover { background-color: #d3d3d3; } /* 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 { display: inline-block; width: 100%; text-align: center; } /* Warehouse buttons css END */ js: $(document).ready(function () { // Handling click events for selecting attributes $('#product-options .btn').on('click', function () { $(this).siblings('.btn').removeClass('active'); $(this).addClass('active'); $(this).prev('input[type="radio"]').prop('checked', true).trigger('change'); // Trigger PrestaShop's findCombination to update the combination details findCombination(); }); }); I would like to move the sorting to BO but for now it is what it is. EDIT: Corrected code as there was no need to reorder using js.
yaniv14 Posted October 26 Posted October 26 did you try to set the desire position of each attribute in the back office? based on the code it should works fine. ORDER BY ag.`position` ASC, a.`position` ASC, agl.`name` ASC'; unless you have an override for ProductController "assignAttributesGroups" or Product class "getAttributesGroups"
the.rampage.rado Posted October 26 Author Posted October 26 Thanks for your reply! It does not sort them. They are displayed in the order I have added them to the product: I was under the impression that the drop-down is also sorted but no, when I add them assorted in BO, they appear assorted in FO.
Yabber Posted October 26 Posted October 26 16 minutes ago, the.rampage.rado said: It does not sort them. They are displayed in the order I have added them to the product I checked on TB 1.6 and sorting attribute values in BO by “Position” also works correctly on the front end on the product page. 1
the.rampage.rado Posted October 26 Author Posted October 26 Thanks. I'll have to dig and find what have I done to mess this up.
the.rampage.rado Posted October 26 Author Posted October 26 1 hour ago, Yabber said: I checked on TB 1.6 and sorting attribute values in BO by “Position” also works correctly on the front end on the product page. Just a quick question - if you add your attributes in random order in BO so they look like this in Product->Attributes: You see them in FO ordered, right? EDIT: just tested a brand new install - yes, they are ordering in FO.
Yabber Posted October 26 Posted October 26 @the.rampage.rado The order of attribute combinations in the product configuration has no meaning. If I change the “Position” in the attribute values then the order on the store front changes identically. 1
the.rampage.rado Posted October 26 Author Posted October 26 The values on the installation I was testing my code were not ordered...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now