1

Magento 2.3 custom options

Magento2.3. I would like to change the + amount to the actual price of the item with option - the base price added to the custom option. Also remove the plus sign.

I know there are plugins that do this however I would like to achieve this by modifying my theme. I would very much appreciate help.

2 Answers 2

7

I have researched the way Magento goes about to calculate the price of the product. It is complicated and it is unnecessary to recreate that entire process just for the sake of displaying the total price. So I have made an approach which may seem dirty and quick, but you can achieve solution to your problem.

I took the approach of injecting a custom javascript file to every product page and simply using the DOM Manipulation to achieve the result.

Read the answer to the end and implement the solution.

The first step is to create the following files and folders in order to implement the solution.

In your theme folder create

  1. Magento_Catalog/layout/catalog_product_view.xml

  2. Magento_Catalog/templates/product/customjs.phtml

The content for catalog_product_view.xml is

<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <referenceContainer name="content">
        <block class="Magento\Framework\View\Element\Template"
               name="custom.js" as="custom.js" 
template="Magento_Catalog::product/customjs.phtml"/>
    </referenceContainer>
</page>

The content for customjs.phtml is

<script>// <![CDATA[
    require([
        'jquery',
        'hello'
    ], function ($) {
        $('.product-info-main').changePrice();
    });
    // ]]>
</script>

Now go on and create Vendorname/Themename/web/js/custom.js and the content is

define('jquery', function($) {
    var priceDomain = "";
        $.fn.changePrice = function(){
            try{
                const theElements = document.getElementsByClassName("price-notice");
                const productPrice = parseFloat(removeSpaceFromMainPrice(document.getElementsByClassName("price")[0].innerText));
                for(let i=0;i<theElements.length;i++){
                    theElements[i].innerText = generateText((parseFloat(removeSpaceFromCustomPrice(theElements[i].innerText)) + productPrice));
                }
            }
            catch (e) {
                console.log(e);
            }
        }
    let removeSpaceFromMainPrice = function (price) {
            priceDomain = ""+price.charAt(0);
            return price.substr(1);
    }
    let removeSpaceFromCustomPrice = function (price) {
        return price.substr(3);
    }
    let generateText = function (price) {
            return " will cost you a total of "+priceDomain+" "+parseFloat(price).toFixed(2);
    }
    }(jQuery)
);

Then create the Vendorname\Themename\requirejs-config.js and the content is

var config = {
    map: {
        '*' : {
            'hello' : 'js/custom'
        }
    }
}

Now go on and deploy the static content and clear the cache to see the effect.

Note:

  1. This way of doing it has it's drawbacks. For instance, the above method only works for simple product that has radio buttons as custom options. Also, if MSRP is applied the above code won't work. But don't worry as long as you know how to error handle and do DOM manipulation you can add the code and make it work.
  2. Keep in mind that this is just a boilerplate code and customise this code to suit your needs.

This piece of code can be further improved and if there is any other way to achieve this then the answers are welcome.

Hope this helps.

4
  • Thank you so much for your reply, however it does not appear to work. I followed you instructions but I am still getting both the option price alone (not added to base price) and the plus symbol. Are you sure the configurable.js controls simple products with custom options? I have cleared cache and var files. Commented Feb 27, 2020 at 12:59
  • @DianaDavey I have updated my answer. Commented Feb 28, 2020 at 4:53
  • This worked perfectly. Perfect for my purposes. Thank you so much for your assistance. Commented Mar 2, 2020 at 16:15
  • This solution works great! however, the options that have no price increase are displayed with no price: 6mm, 8mm, 10mm, 12mm - £ 34.17, 14mm - £ 37.19, 16mm - £ 39.75, Is it possible to display the base price (£30.00) of the product, so they will look like: 6mm - £ 30.00, 8mm - £ 30.00, 10mm - £ 30.00, 12mm - £ 34.17, 14mm - £ 37.19, 16mm - £ 39.75, Commented Aug 18, 2021 at 17:19
0

Create the following file structure to avoid making any changes to the Magento Core files.

app/code/local/Mage/Catalog/Block/Product/View/Options/Abstract.php

Then open and and copy the content from app/code/core/Mage/Catalog/Block/Product/View/Options/Abstract.php into the Abstract.php file you just created in your local folder.

In your new Abstract.php file run a search for $sign = ‘+’; (It’s in the _formatPrice function if your search doesn’t work)

Replace the ‘+’ with ‘ ‘. or you can write the logic to show the original prize

Your Answer

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

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