13

I'm working on a new Magento 2 theme at the moment. For this theme I want to show all product options (custom options and options form configurable product) in the product listing. This way the user can quickly add products to it's cart.

I tried adding the product.info block in catalog_category_view.xml and set the product for that block. Options are shown for every product, the problem is that the option shown is only from the first product. So all other products have this options.

--- UPDATE ---

I managed to show the product options, but the prices are not updated. Can someone point me in the right direction?

<form id='product_addtocart_form_<?php echo $product->getId(); ?>' class="c-product__details__add-to-cart" data-role="tocart-form" action="<?php echo $postParams[ 'action' ]; ?>" method="post">
    <input type="hidden" name="product" value="<?php echo $postParams[ 'data' ][ 'product' ]; ?>">
    <input type="hidden" name="<?php echo Action::PARAM_NAME_URL_ENCODED; ?>" value="<?php echo $postParams[ 'data' ][ Action::PARAM_NAME_URL_ENCODED ]; ?>">
    <?php echo $block->getBlockHtml('formkey') ?>
    <div class="product-options-wrapper" id="product-options-wrapper" data-hasrequired="* Verplichte velden">
        <?php if($product->getTypeId() === 'configurable') : ?>
            <?php foreach($product->getTypeInstance()->getConfigurableAttributes($product) as $attribute) : ?>
                <div class="field">
                    <label class="label" for="select_<?php echo $attribute->getAttributeId(); ?>"><span><?php echo $attribute->getLabel() ?></span></label>
                    <?php $values = $attribute->getOptions(); ?>
                    <div class="control">
                        <select id="select_<?php echo $attribute->getAttributeId() ?>" name="options[<?php echo $attribute->getAttributeId() ?>]" class="product-option product-custom-option-<?php echo $attribute->getAttributeId() ?> admin__control-select" data-selector="options[<?php echo $attribute->getAttributeId() ?>]">
                            <?php foreach($values as $value): ?>

                                <option value="<?php echo $value['value_index'] ?>" price="2"><?php echo  $value['label'] ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                </div>
            <?php endforeach; ?>
        <?php else : ?>
            <?php foreach($customOptions as $option): ?>
                <div class="field">
                    <label class="label" for="select_<?php echo $option->getId(); ?>"><span><?php echo $option->getTitle() ?></span></label>
                    <?php $values = $option->getValues(); ?>
                    <div class="control">
                        <select id="select_<?php echo $option->getId() ?>" data-id="<?php echo $product->getId() ?>" name="options[<?php echo $option->getId() ?>]" class="product-option product-custom-option-<?php echo $product->getId() ?> admin__control-select" data-selector="options[<?php echo $option->getId() ?>]">
                            <?php foreach($values as $value): ?>

                                <option value="<?php echo $value->getData('option_type_id') ?>" price="3"><?php echo $value->getTitle() ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                </div>
            <?php endforeach; ?>
        <?php endif; ?>
        <script>
            require([
                'jquery',
                'Magento_Catalog/js/price-box'
            ], function($){
                var priceBoxes = $('[data-product-id=<?php echo $product->getId(); ?>]');

                priceBoxes = priceBoxes.filter(function(index, elem){
                    return !$(elem).find('.price-from').length;
                });
                var priceBox = priceBoxes.priceBox({'priceConfig': <?php /* @escapeNotVerified */ echo $block->getJsonConfig($product, $customOptions) ?>});

                $('.product-option').on('change', function() {
                    priceBox.trigger('updatePrice');
                });
            });
        </script>
    </div>
    <button type="submit" title="<?php echo $block->escapeHtml(__('Add to Cart')); ?>" class="action tocart primary im">
        <span><?php echo __('Add to cart'); ?></span>
    </button>
</form>

I also implemented the getJsonConfig function in my own ListProduct class.

4

3 Answers 3

1

You can take as an example the module Magento_Swatch.

The block Magento\Swatches\Block\Product\Renderer\Listing\Configurable is added to the block with name category.product.type.details.renderers.

As in here: https://github.com/magento/magento2/blob/develop/app/code/Magento/Swatches/view/frontend/layout/catalog_category_view.xml

The template initialises the JS used on swatches: Magento_Swatches::product/listing/renderer.phtml

https://github.com/magento/magento2/blob/develop/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml

And everything important is done into the swatch JS. https://github.com/magento/magento2/blob/develop/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js Like functions: _RenderControls, _RenderFormInput, _EventListener, _UpdatePrice and other. The JS looks big. But it has a lot of code around rendering swatches images that are fetched via AJAX. You probably don't need it, it's easier to implement.

Here, the options (super attributes and associated products) html tags (swatches divs) are created and manipulated. The price is handled here too. In your case you'll have dropdowns.

You'd need to write your own module to implement all above. Theoretically you can add any options from all type of products (bundle, grouped, ..). The cost is performance, since you'd need to load more data into models to every product on a category page that has options.

As an alternative, you can try to set to the configurable/simple associated products non-visual swatches (without images).

0

For configurable products: You must set the attribute type "Text Swatch" and modify the template to display the swatch's (It's default on Magento 2), if desired, this is the simplest, or extend functionality swatch through a module, which adds a new option at the type of attribute and create a new template for that option.

1
  • This does not seems to be the best option, see my updated question, only the prices don't work at the moment.
    – Silvan
    Apr 6, 2017 at 7:15
0

In left Menu List -> Go To attribute section and click on Product -> Search Product Option That you have to show & Click on that attribute -> Go To Storefront Properties -> And Change ->in Visible on Catalog Pages on Storefront & Used in Product Listing -> NO to YES.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.