Chrysippus
Chrysippus

Reputation: 119

How do I override a JS function in js/varien/product.js?

I am making a Magento extension that calls a custom JS file on the product view page. This custom JS file will load last and needs to override the formatPrice() function found at the bottom of /js/varien/product.js.

The original formatPrice function is as follows:

formatPrice: function(price) {
return formatCurrency(price, this.priceFormat);
}

I would like to replace / override this function with the following:

formatPrice: function(price) {
if (price % 1 == 0) { this.priceFormat.requiredPrecision = 0; }

return formatCurrency(price, this.priceFormat);
}

How do I write the JS code in my custom JS file so that it will properly override this function? I'm not familiar with JS enough to know.

Upvotes: 0

Views: 3169

Answers (2)

nevvermind
nevvermind

Reputation: 3392

While @jholloman's answer is correct from a functional standpoint, you might consider doing this the Prototype's way, inheriting from Product.OptionsPrice and using that new class instead. This is from app\design\frontend\base\default\template\catalog\product\view.phtml, line 36 (where I presume you need it changed):

Original

<script type="text/javascript">
    var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
</script>

Modified

<script type="text/javascript">
    var MyOptionPrice = Class.create(Product.OptionsPrice, { // inherit from Product.OptionsPrice
        formatPrice: function($super, price) { // $super references the original method (see link below)
            if (price % 1 === 0) { 
                this.priceFormat.requiredPrecision = 0; 
            }
            return $super(price);
        }        
    });
    var optionsPrice = new MyOptionPrice(<?php echo $this->getJsonConfig() ?>); // use yours instead
</script>

Using wrap() (this way, you don't have to change the original method name):

<script type="text/javascript">
    Product.OptionsPrice.prototype.formatPrice = Product.OptionsPrice.prototype.formatPrice.wrap(function(parent, price) {
        if (price % 1 === 0) { 
            this.priceFormat.requiredPrecision = 0; 
        }
        return parent(price);        
    });
    var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
</script>

See this link about Prototype's inheritance and the $super var.
Again, I saw code similar to @jholloman's suggestion used in Magento, so there's no problem going his way, but I thought you might want to know how to do this Prototype's way.

Upvotes: 0

jholloman
jholloman

Reputation: 1979

If it is global then you can just do window.formatPrice = myNewFormatPrice; if it is a member of an object then you would do something like: anObject.formatPrice = myNewFormatPrice;

If you need to edit the prototype of an object use: Product.OptionsPrice.prototype.formatPrice = myFormatPrice;

Also you need to look into the access to requiredPrecision. If it is "private" or "protected" then you won't be able to access it.

Upvotes: 2

Related Questions