7

I was trying to remove the price which Magento adds to the options in a Select field but can't seem to get rid of the price. From what I could find on the internet it should be edited on the following location: app\code\Magento\Catalog\Block\Product\View\Options\Type\Select.php

At rule 62

$_value->getTitle() . ' ' . strip_tags($priceStr) . '',

And the following bit at rule 170 - 173

$_value->getTitle() .
'</span> ' .
$priceStr .
'</label>';

I changed these but the price still shows up in the select field as can be seen on the Image below. enter image description here

Does anyone know where I can change this?

1
  • You need to override that Class using di.xml. Jul 27 '18 at 14:39
5

This is an update for Magento 2.2 and 2.3 --- the proper way to remove this is to override a JavaScript file into the active theme, and remove a section of code

The culprit is

vendor/magento/module-configurable-product/view/frontend/web/js/configurable.js - line 415

// vendor/magento/module-configurable-product/view/frontend/web/js/configurable.js
// ... Line 415 on Magento 2.2.x, 2.3.x

if (optionPriceDiff !== 0) {
    options[i].label = options[i].label + ' ' + priceUtils.formatPrice(
        optionPriceDiff,
        this.options.priceFormat,
        true);
}
// ...

Commenting out the above code block will remove the price increase without the need to add an additional binding onto the page.

Full article here: https://www.cadence-labs.com/2019/07/magento-2-remove-price-from-select-dropdown-on/

EDIT - 8th June 2020: The lines to comment out for Magento 2.3.5 are lines 460 - 466.

1
  • this man F**ks! Thanks
    – Herbert
    Nov 11 at 13:45
2

Better than completely overwriting /vendor/magento/module-configurable-product/view/frontend/web/js/configurable.js would be a small JS mixin:

In your custom module, create these two files:

Vendor/Module/view/frontend/requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_ConfigurableProduct/js/configurable': {
                'Vendor_Module/js/configurable': true
            }
        }
    }
};

Vendor/Module/view/frontend/web/js/configurable.js

define([
    'jquery'
], function ($) {
    'use strict';

    /**
     * This mixin removes the price increase labels from configurable attribute dropdown options,
     * if the attribute code equals "my_attribute_code".
     *
     * Example:
     *   "Foo +5,00 €" => "Foo"
     */
    var configurableWidgetMixin = {
        _fillSelect: function (element) {
            var _result = this._super(element);

            // optionally check for an attribute code if you don't want to hide prices for all attribute dropdowns
            if (element.config.code === 'my_attribute_code') {
                if (element.options) {
                    for (var i = 0; i < element.options.length; i++) {
                        element.options[i].label = element.options[i].label.replace(/^(.*)(\s[+-][\d,]+\s€)$/, '$1');
                    }
                }
            }

            return _result;
        }
    };

    return function (targetWidget) {
        $.widget('mage.configurable', targetWidget, configurableWidgetMixin); // the widget alias should be like for the target widget
        return $.mage.configurable; //  the widget by parent alias should be returned
    };
});

This is tested with Magento 2.3.5 You should customize the Regex so that it suits your needs. With some improvement, this could also be made a bit locale agnostic.

2

I found an easier solution for this:

In configurable.js in your element.options you already have the option label without price: enter image description here

As you can see, you just have to use the initialLabel instead of label. So create a mixin as said above:

var config = {
    config: {
        mixins: {
            'Magento_ConfigurableProduct/js/configurable': {
                'Vendor_Module/js/configurable': true
            }
        }
    }
};

And in your mixin just change the output of the _getOptionLabel function to initialLabel:

define([
    'jquery'
], function ($) {
    'use strict';
    return function (widget) {
        $.widget('mage.configurable', widget, {
            _getOptionLabel: function (option) {
                return option.initialLabel;
            }
        });
        return $.mage.configurable;
    }
});
1

You need to create your own module and can manage to work by following code:

Add the below code to your di.xml. Location of di.xml will:

app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\View\Options\Type\Select" type="Vendor\Module\Block\Product\View\Options\Type\Select" />
</config>

Create one file Select.php at below location:

app/code/Vendor/Module/Block/Product/View/Options/Type/Select.php

Content of Select.php:

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\Module\Block\Product\View\Options\Type;

/**
 * Product options text type block
 *
 * @api
 * @since 100.0.2
 */
class Select extends \Magento\Catalog\Block\Product\View\Options\Type\Select
{
    /**
     * Return html for control element
     *
     * @return string
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function getValuesHtml()
    {
        $_option = $this->getOption();
        $configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
        $store = $this->getProduct()->getStore();

        $this->setSkipJsReloadPrice(1);
        // Remove inline prototype onclick and onchange events

        if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN ||
            $_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE
        ) {
            $require = $_option->getIsRequire() ? ' required' : '';
            $extraParams = '';
            $select = $this->getLayout()->createBlock(
                \Magento\Framework\View\Element\Html\Select::class
            )->setData(
                [
                    'id' => 'select_' . $_option->getId(),
                    'class' => $require . ' product-custom-option admin__control-select'
                ]
            );
            if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN) {
                $select->setName('options[' . $_option->getId() . ']')->addOption('', __('-- Please Select --'));
            } else {
                $select->setName('options[' . $_option->getId() . '][]');
                $select->setClass('multiselect admin__control-multiselect' . $require . ' product-custom-option');
            }
            foreach ($_option->getValues() as $_value) {
                $priceStr = $this->_formatPrice(
                    [
                        'is_percent' => $_value->getPriceType() == 'percent',
                        'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
                    ],
                    false
                );
                $select->addOption(
                    $_value->getOptionTypeId(),
                    $_value->getTitle(),
                    ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)]
                );
            }
            if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE) {
                $extraParams = ' multiple="multiple"';
            }
            if (!$this->getSkipJsReloadPrice()) {
                $extraParams .= ' onchange="opConfig.reloadPrice()"';
            }
            $extraParams .= ' data-selector="' . $select->getName() . '"';
            $select->setExtraParams($extraParams);

            if ($configValue) {
                $select->setValue($configValue);
            }

            return $select->getHtml();
        }

        if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO ||
            $_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX
        ) {
            $selectHtml = '<div class="options-list nested" id="options-' . $_option->getId() . '-list">';
            $require = $_option->getIsRequire() ? ' required' : '';
            $arraySign = '';
            switch ($_option->getType()) {
                case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO:
                    $type = 'radio';
                    $class = 'radio admin__control-radio';
                    if (!$_option->getIsRequire()) {
                        $selectHtml .= '<div class="field choice admin__field admin__field-option">' .
                            '<input type="radio" id="options_' .
                            $_option->getId() .
                            '" class="' .
                            $class .
                            ' product-custom-option" name="options[' .
                            $_option->getId() .
                            ']"' .
                            ' data-selector="options[' . $_option->getId() . ']"' .
                            ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
                            ' value="" checked="checked" /><label class="label admin__field-label" for="options_' .
                            $_option->getId() .
                            '"><span>' .
                            __('None') . '</span></label></div>';
                    }
                    break;
                case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX:
                    $type = 'checkbox';
                    $class = 'checkbox admin__control-checkbox';
                    $arraySign = '[]';
                    break;
            }
            $count = 1;
            foreach ($_option->getValues() as $_value) {
                $count++;

                $priceStr = $this->_formatPrice(
                    [
                        'is_percent' => $_value->getPriceType() == 'percent',
                        'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
                    ]
                );

                $htmlValue = $_value->getOptionTypeId();
                if ($arraySign) {
                    $checked = is_array($configValue) && in_array($htmlValue, $configValue) ? 'checked' : '';
                } else {
                    $checked = $configValue == $htmlValue ? 'checked' : '';
                }

                $dataSelector = 'options[' . $_option->getId() . ']';
                if ($arraySign) {
                    $dataSelector .= '[' . $htmlValue . ']';
                }

                $selectHtml .= '<div class="field choice admin__field admin__field-option' .
                    $require .
                    '">' .
                    '<input type="' .
                    $type .
                    '" class="' .
                    $class .
                    ' ' .
                    $require .
                    ' product-custom-option"' .
                    ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
                    ' name="options[' .
                    $_option->getId() .
                    ']' .
                    $arraySign .
                    '" id="options_' .
                    $_option->getId() .
                    '_' .
                    $count .
                    '" value="' .
                    $htmlValue .
                    '" ' .
                    $checked .
                    ' data-selector="' . $dataSelector . '"' .
                    ' price="' .
                    $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false) .
                    '" />' .
                    '<label class="label admin__field-label" for="options_' .
                    $_option->getId() .
                    '_' .
                    $count .
                    '"><span>' .
                    $_value->getTitle() .
                    '</span> ' .
                    //$priceStr .
                    '</label>';
                $selectHtml .= '</div>';
            }
            $selectHtml .= '</div>';

            return $selectHtml;
        }
    }
}
6
  • Hmm I created my own module following your code and that part works when I change the code I can make the select field dissappear. However I can still see the price after the option while i commented the $priceStr. Jul 30 '18 at 9:27
  • Could it be that the price is generated somewhere else? Jul 30 '18 at 9:27
  • This is working fine for me for custom options select. Jul 30 '18 at 9:35
  • Okay something else is happening right know, the "option + €0,00" is gone at first but is added a few seconds later. Is there another piece of code somewhere that interferes with this code? Jul 30 '18 at 10:17
  • I think you are using some extension or js which includes it. Jul 31 '18 at 14:15
1

I created a JS solution which removes the price from the option. This function fires when the select changes which occurs when the price is added to the option field. It then checks each option for "+€" and "-€" this could be any currency however. It then removes everything from this sign so it returns the option without the price behind it.

$('select.product-custom-option').change(function(){
    $('option').each(function(){
        var selectedOption = $(this).text();
        if (selectedOption.indexOf('+€') > -1) {
            selectedOption = selectedOption.substring(0, selectedOption.indexOf('+€'));
            $(this).text(selectedOption);
        } else if (selectedOption.indexOf('-€') > -1) {
            selectedOption = selectedOption.substring(0, selectedOption.indexOf('-€'));
            $(this).text(selectedOption);
        }
    });     
}); 

The result:

The result

2
1

I found another way to hide the "+price" from dropdown

I've just edited

pub/static/frontend/(vendor)/(theme)/(Language)/Magento_Catalog/js/price-options.js

var globalOptions = {
    productId: null,
    priceHolderSelector: '.price-box', //data-role="priceBox"
    optionsSelector: '.product-custom-option',
    optionConfig: {},
    optionHandlers: {},
    optionTemplate: '<%= data.label %>' 

    /*edited +
    '<% if (data.finalPrice.value) { %>' +
    ' +<%- data.finalPrice.formatted %>' +
    '<% } %>'
    edited*/,

    controlContainer: 'dd'
};

Then "php bin/magento cache:clean && php bin/magento cache:flush"

Many thanks to the analysts who pointed out other answers.

1
  • 2
    This might temporarily solve it but when you refresh the static content you have to change it again. Oct 12 '18 at 7:07
1

This is done via javascript, which is loaded via vendor/Magento/module-configurable-product/view/frontend/web/js/configurable.js file.

In order to change the default behavior, we are going to over-ride the configurable.js file inside your theme.

In my example, I am using the Ultimo theme and have a child theme called custom.

So I create a folder in app/design/frontend/vendor/<your_theme_name>/<your_vendor_name>/Magento_ConfigurableProduct/web/js/ and upload the vendor/Magento/module-configurable-product/view/frontend/web/js/configurable.js file into that folder. The configurable.js file path will be app/design/frontend/<your_vendor_name>/<your_theme_name>/Magento_ConfigurableProduct/web/js/configurable.js.

Once that’s done, you can open the configurable file and look for line 415.

You are going to want to comment out line 415 thru 420.

// if (optionPriceDiff !== 0) {
// options[i].label = options[i].label + ' ' + priceUtils.formatPrice(
// optionPriceDiff,
// this.options.priceFormat,
// true);
// }

0

You can Extend JS Function _getOptionLabel.

app/code/VendorName/ModuleName/view/frontend/web/js/configurable.js

define(['jquery', 'mage/utils/wrapper'], function($, wrapper) {
    'use strict';

    return function(target) {
        target.prototype._getOptionLabel = wrapper.wrap(target.prototype._getOptionLabel, function(original, option) {
            return option.initialLabel;
        });

        return target;
    };
});

app/code/VendorName/ModuleName/view/frontend/requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_ConfigurableProduct/js/configurable': {'VendorName_ModuleName/js/configurable': true},
        },
    },
};

I made VCT Price Diff on Magento Marketplace module that solves this problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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