3

I am attempting to override the _onQtyFieldChanged event in the mage.priceBundle widget in the module-bundle/view/base/web/js/price-bundle.js file.

I am referencing the Magento dev docs (http://devdocs.magento.com/guides/v2.0/javascript-dev-guide/javascript/custom_js.html) and this Magento StackExchange question (Magento2: How can I override core js module price-box.js), but I can't manage to get my custom _onQtyFieldChanged event method to execute. As of now I only have a console.log statement in that method.

A little background: My custom price-bundle.js file is found in Endertech/BundleExtended/view/base/web/js directory. My requirejs-config.js is in Endertech/BundleExtended/view/frontend.

requirejs-config.js:

var config = {
    map: {
        "*": {
            priceBundle: 'Endertech_BundleExtended/js/price-bundle',
            'Magento_Bundle/js/price-bundle': 'Endertech_BundleExtended/js/price-bundle'
        }
    }

};

Endertech/BundleExtended/view/base/web/js/price-bundle.js:

define([
    'jquery',
    'underscore',
    'mage/template',
    'priceUtils',
    'priceBox',
    'priceBundle',
], function ($, _, mageTemplate, utils) {
    'use strict';

    $.widget('Endertech.priceBundle', $.mage.priceBundle, {

        _onQtyFieldChanged: function onQtyFieldChanged(event) {
            console.log("Endertech Module"); 
            var field = $(event.target),
                optionInstance,
                optionConfig;

            if (field.data('optionId') && field.data('optionValueId')) {
                optionInstance = field.data('option');
                optionConfig = this.options.optionConfig
                    .options[field.data('optionId')]
                    .selections[field.data('optionValueId')];
                optionConfig.qty = field.val();

                optionInstance.trigger('change');
            }
        }
    });

    return $.Endertech.priceBundle;

});

EDIT:

So I realized that probably the issue I am coming across is the fact that the widget method I am trying to modify is a private method in module-bundle/view/base/web/js/price-bundle.js. Which is the reason why I can't override it or extend it. I am not sure if there is a way to get around this or a different approach I need to take to this issue that I don't know about.

Any help and suggestions are greatly appreciated.

5
  • 1
    We may have architecture for this. Checking.
    – benmarks
    Jun 7, 2016 at 16:06
  • 2
    Confirmed, we have JavaScript mixins which can do this. You'll get a response soon.
    – benmarks
    Jun 8, 2016 at 15:34
  • @benmarks thank you so much for looking into my issue, I had also thought about JavaScript mixins, but the first time I attempted it I was having issues accessing some of the $.mage.priceBundle parameters and methods. Jun 8, 2016 at 21:26
  • @NoemiQuezada Please mark the correct answer
    – tread
    Jan 13, 2017 at 15:00
  • Hi @NoemiQuezada have you got solution for it. please share the piece of code if you find any solution regrading it
    – Himanshu
    Mar 4, 2019 at 4:52

4 Answers 4

2

I had the same issue like you and found a workaround, but don't know if it is helpful. I am going to share it anyway.

I resigned to override the function. Then I was trying to override the whole widget, but couldn't get it to work either. The widget wasn't overridden and the magento standard widget was loaded.

I inspected the generated pub/static/_requirejs/frontend/<Vendor>/<theme>/<location>/requirejs-config.js file. It seems to me, that the modules' requirejs configurations are inserted in a alphabetical order. Thus, the priceBundle variable of my module was overridden by the one of the magento-bundle module, because my vendor starts with a 'C'.

For testing purposes I created a new module and changed the vendor to 'XC...'. After that the overriding of the whole widget works.

But I am still interested in how to override just one function.

2
  • I tried this adding a Z in front of Endertech for the vendor name and now for the first time my price-bundle.js file gets loaded. Thank you! Like you though, I would like to understand how I can just override one method. However, after testing the solution I realized that another method has to be modified slightly because when you update a product that is in the cart the product summary is not updated correctly. Jun 9, 2016 at 19:47
  • I'm glad that the workaround is working for you, too. Now, I'm wondering about the quantity of the radios when you update a product that is in the cart. It seams to me, that the quantity is being set to the default instead of to the user configured one. I did not changed anything about radios and can reproduce this behavior in other online demo shops. I already opened an issue at github: github.com/magento/magento2/issues/4942. Thus, don't waste your time, if you experience the same issue.
    – Densen
    Jun 15, 2016 at 8:48
2

You should intrude in requrejs sequence be adding dependencies for your extension, config will be:

var config = {

             map: {
                    "*": {
                          priceBundle: 'SOURCE_TO_EXTENDED_PRICE_BUNDLE'
                         },
                         'Endertech_BundleExtended/js/price-bundle': {'priceBundle': 'SOURCE_TO_ORIGINAL_PRICE_BUNDLE'}
                         }

            };  
1
  • 1
    I tried this approach, but my file did not load at all. Jun 9, 2016 at 19:44
1

What I also found that worked was the following

In the module requirejs-config:

var config = {
    map: {
        '*': {
            'mage/SwatchRenderer': 'Magento_Swatches/js/swatch-renderer',
            'Magento_Swatches/js/swatch-renderer': 'MyVendor_MyModule/js/swatch-renderer'
        }
    }
};

And then I created a mymodule/view/frontend/web/js/swatch-renderer.js that contained:

define([
    'jquery',
    'jquery/ui',
    'mage/SwatchRenderer',
], function ($) {
    $.widget('myvendor.SwatchRenderer', $.mage.SwatchRenderer, {
        _Rewind: function (controls) {
            controls.find('div[option-id], option[option-id]').removeClass('disabled').removeAttr('disabled');
            controls.find('div[option-empty], option[option-empty]').attr('disabled', true).addClass('disabled');
            console.log('test');
        },
    });

    return $.myvendor.SwatchRenderer;
});
0

If your core js use widget then you also call that widget and return that widget variable in a mixin.

Bundle mixin you have to create requirejs-config.js in your custom module at Vendor/Extension/view/frontend/requirejs-config.js put below code in appropriate js

requirejs-config.js :

var config = {
    config: {
        mixins: {
            'Magento_Bundle/js/price-bundle': {
                'Vendor_Extension/js/price-bundle-mixin': true
            }
        }
    },
};

price-bundle-mixin :

define([
    'jquery',
    'underscore',
    'mage/template',
    'priceUtils',
    'priceBox'
], function ($, _, mageTemplate, utils) {
    'use strict';

    return function (priceBundle) {

        $.widget('mage.priceBundle', priceBundle, {
            // function which you want to overwrite
        });

        // don't forget to add a function which is used by your  
        // functions, else it will show undefined function error

        return $.mage.priceBundle;
    };
});

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.