Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Magento product image vertical align middle /js/varien/product.js
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE_AFL.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category Varien
* @package js
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
*/
if(typeof Product=='undefined') {
var Product = {};
}
/********************* IMAGE ZOOMER ***********************/
Product.Zoom = Class.create();
/**
* Image zoom control
*
* @author Magento Core Team <core@magentocommerce.com>
*/
Product.Zoom.prototype = {
initialize: function(imageEl, trackEl, handleEl, zoomInEl, zoomOutEl, hintEl){
this.containerEl = $(imageEl).parentNode;
this.imageEl = $(imageEl);
this.handleEl = $(handleEl);
this.trackEl = $(trackEl);
this.hintEl = $(hintEl);
this.containerDim = Element.getDimensions(this.containerEl);
this.imageDim = Element.getDimensions(this.imageEl);
this.imageDim.ratio = this.imageDim.width/this.imageDim.height;
this.floorZoom = 1;
if (this.imageDim.width > this.imageDim.height) {
this.ceilingZoom = this.imageDim.width / this.containerDim.width;
} else {
this.ceilingZoom = this.imageDim.height / this.containerDim.height;
}
if (this.imageDim.width <= this.containerDim.width
&& this.imageDim.height <= this.containerDim.height) {
this.trackEl.up().hide();
this.hintEl.hide();
this.containerEl.removeClassName('product-image-zoom');
return;
}
this.imageX = 0;
if (this.imageDim.width > this.containerDim.width) {
myY = ((this.containerDim.width/this.imageDim.width)*this.imageDim.height)/2 - this.containerDim.height/2;
} else { myY = 0; }
this.imageY = '-' + myY;
this.imageZoom = 1;
this.sliderSpeed = 0;
this.sliderAccel = 0;
this.zoomBtnPressed = false;
this.showFull = false;
this.selects = document.getElementsByTagName('select');
this.draggable = new Draggable(imageEl, {
starteffect:false,
reverteffect:false,
endeffect:false,
snap:this.contain.bind(this)
});
this.slider = new Control.Slider(handleEl, trackEl, {
axis:'horizontal',
minimum:0,
maximum:Element.getDimensions(this.trackEl).width,
alignX:0,
increment:1,
sliderValue:0,
onSlide:this.scale.bind(this),
onChange:this.scale.bind(this)
});
this.scale(0);
Event.observe(this.imageEl, 'dblclick', this.toggleFull.bind(this));
Event.observe($(zoomInEl), 'mousedown', this.startZoomIn.bind(this));
Event.observe($(zoomInEl), 'mouseup', this.stopZooming.bind(this));
Event.observe($(zoomInEl), 'mouseout', this.stopZooming.bind(this));
Event.observe($(zoomOutEl), 'mousedown', this.startZoomOut.bind(this));
Event.observe($(zoomOutEl), 'mouseup', this.stopZooming.bind(this));
Event.observe($(zoomOutEl), 'mouseout', this.stopZooming.bind(this));
},
toggleFull: function () {
this.showFull = !this.showFull;
//Hide selects for IE6 only
if (typeof document.body.style.maxHeight == "undefined") {
for (i=0; i<this.selects.length; i++) {
this.selects[i].style.visibility = this.showFull ? 'hidden' : 'visible';
}
}
val_scale = !this.showFull ? this.slider.value : 1;
this.scale(val_scale);
this.trackEl.style.visibility = this.showFull ? 'hidden' : 'visible';
this.containerEl.style.overflow = this.showFull ? 'visible' : 'hidden';
this.containerEl.style.zIndex = this.showFull ? '1000' : '9';
return this;
},
scale: function (v) {
var centerX = (this.containerDim.width*(1-this.imageZoom)/2-this.imageX)/this.imageZoom;
var centerY = (this.containerDim.height*(1-this.imageZoom)/2-this.imageY)/this.imageZoom;
var overSize = (this.imageDim.width > this.containerDim.width || this.imageDim.height > this.containerDim.height);
this.imageZoom = this.floorZoom+(v*(this.ceilingZoom-this.floorZoom));
if (overSize) {
if (this.imageDim.width > this.containerDim.width) {
this.imageEl.style.width = (this.imageZoom*this.containerDim.width)+'px';
} else if (this.imageDim.height > this.containerDim.height) {
this.imageEl.style.height = (this.imageZoom*this.containerDim.height)+'px';
}
if(this.containerDim.ratio){
this.imageEl.style.height = (this.imageZoom*this.containerDim.width*this.containerDim.ratio)+'px'; // for safari
}
} else {
this.slider.setDisabled();
}
this.imageX = this.containerDim.width*(1-this.imageZoom)/2-centerX*this.imageZoom;
this.imageY = this.containerDim.height*(1-this.imageZoom)/2-centerY*this.imageZoom;
this.contain(this.imageX, this.imageY, this.draggable);
return true;
},
startZoomIn: function()
{
if (!this.slider.disabled) {
this.zoomBtnPressed = true;
this.sliderAccel = .002;
this.periodicalZoom();
this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
}
return this;
},
startZoomOut: function()
{
if (!this.slider.disabled) {
this.zoomBtnPressed = true;
this.sliderAccel = -.002;
this.periodicalZoom();
this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
}
return this;
},
stopZooming: function()
{
if (!this.zoomer || this.sliderSpeed==0) {
return;
}
this.zoomBtnPressed = false;
this.sliderAccel = 0;
},
periodicalZoom: function()
{
if (!this.zoomer) {
return this;
}
if (this.zoomBtnPressed) {
this.sliderSpeed += this.sliderAccel;
} else {
this.sliderSpeed /= 1.5;
if (Math.abs(this.sliderSpeed)<.001) {
this.sliderSpeed = 0;
this.zoomer.stop();
this.zoomer = null;
}
}
this.slider.value += this.sliderSpeed;
this.slider.setValue(this.slider.value);
this.scale(this.slider.value);
return this;
},
contain: function (x,y,draggable) {
var dim = Element.getDimensions(draggable.element);
var xMin = 0, xMax = this.containerDim.width-dim.width;
var yMin = 0, yMax = this.containerDim.height-dim.height;
x = x>xMin ? xMin : x;
x = x<xMax ? xMax : x;
y = y>yMin ? yMin : y;
y = y<yMax ? yMax : y;
if (this.containerDim.width > dim.width) {
x = (this.containerDim.width/2) - (dim.width/2);
}
if (this.containerDim.height > dim.height) {
y = (this.containerDim.height/2) - (dim.height/2);
}
this.imageX = x;
this.imageY = y;
this.imageEl.style.left = this.imageX+'px';
this.imageEl.style.top = this.imageY+'px';
return [x,y];
}
}
/**************************** CONFIGURABLE PRODUCT **************************/
Product.Config = Class.create();
Product.Config.prototype = {
initialize: function(config){
this.config = config;
this.taxConfig = this.config.taxConfig;
this.settings = $$('.super-attribute-select');
this.state = new Hash();
this.priceTemplate = new Template(this.config.template);
this.prices = config.prices;
this.settings.each(function(element){
Event.observe(element, 'change', this.configure.bind(this))
}.bind(this));
// fill state
this.settings.each(function(element){
var attributeId = element.id.replace(/[a-z]*/, '');
if(attributeId && this.config.attributes[attributeId]) {
element.config = this.config.attributes[attributeId];
element.attributeId = attributeId;
this.state[attributeId] = false;
}
}.bind(this))
// Init settings dropdown
var childSettings = [];
for(var i=this.settings.length-1;i>=0;i--){
var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
if(i==0){
this.fillSelect(this.settings[i])
}
else {
this.settings[i].disabled=true;
}
$(this.settings[i]).childSettings = childSettings.clone();
$(this.settings[i]).prevSetting = prevSetting;
$(this.settings[i]).nextSetting = nextSetting;
childSettings.push(this.settings[i]);
}
// Set default values - from config and overwrite them by url values
if (config.defaultValues) {
this.values = config.defaultValues;
}
var separatorIndex = window.location.href.indexOf('#');
if (separatorIndex != -1) {
var paramsStr = window.location.href.substr(separatorIndex+1);
var urlValues = paramsStr.toQueryParams();
if (!this.values) {
this.values = {};
}
for (var i in urlValues) {
this.values[i] = urlValues[i];
}
}
this.configureForValues();
document.observe("dom:loaded", this.configureForValues.bind(this));
},
configureForValues: function () {
if (this.values) {
this.settings.each(function(element){
var attributeId = element.attributeId;
element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
this.configureElement(element);
}.bind(this));
}
},
configure: function(event){
var element = Event.element(event);
this.configureElement(element);
},
configureElement : function(element) {
this.reloadOptionLabels(element);
if(element.value){
this.state[element.config.id] = element.value;
if(element.nextSetting){
element.nextSetting.disabled = false;
this.fillSelect(element.nextSetting);
this.resetChildren(element.nextSetting);
}
}
else {
this.resetChildren(element);
}
this.reloadPrice();
// Calculator.updatePrice();
},
reloadOptionLabels: function(element){
var selectedPrice;
if(element.options[element.selectedIndex].config){
selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
}
else{
selectedPrice = 0;
}
for(var i=0;i<element.options.length;i++){
if(element.options[i].config){
element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price-selectedPrice);
}
}
},
resetChildren : function(element){
if(element.childSettings) {
for(var i=0;i<element.childSettings.length;i++){
element.childSettings[i].selectedIndex = 0;
element.childSettings[i].disabled = true;
if(element.config){
this.state[element.config.id] = false;
}
}
}
},
fillSelect: function(element){
var attributeId = element.id.replace(/[a-z]*/, '');
var options = this.getAttributeOptions(attributeId);
this.clearSelect(element);
element.options[0] = new Option(this.config.chooseText, '');
var prevConfig = false;
if(element.prevSetting){
prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
}
if(options) {
var index = 1;
for(var i=0;i<options.length;i++){
var allowedProducts = [];
if(prevConfig) {
for(var j=0;j<options[i].products.length;j++){
if(prevConfig.config.allowedProducts
&& prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
allowedProducts.push(options[i].products[j]);
}
}
} else {
allowedProducts = options[i].products.clone();
}
if(allowedProducts.size()>0){
options[i].allowedProducts = allowedProducts;
element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
element.options[index].config = options[i];
index++;
}
}
}
},
getOptionLabel: function(option, price){
var price = parseFloat(price);
if (this.taxConfig.includeTax) {
var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
var excl = price - tax;
var incl = excl*(1+(this.taxConfig.currentTax/100));
} else {
var tax = price * (this.taxConfig.currentTax / 100);
var excl = price;
var incl = excl + tax;
}
if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
price = incl;
} else {
price = excl;
}
var str = option.label;
if(price){
if (this.taxConfig.showBothPrices) {
str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
} else {
str+= ' ' + this.formatPrice(price, true);
}
}
return str;
},
formatPrice: function(price, showSign){
var str = '';
price = parseFloat(price);
if(showSign){
if(price<0){
str+= '-';
price = -price;
}
else{
str+= '+';
}
}
var roundedPrice = (Math.round(price*100)/100).toString();
if (this.prices && this.prices[roundedPrice]) {
str+= this.prices[roundedPrice];
}
else {
str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
}
return str;
},
clearSelect: function(element){
for(var i=element.options.length-1;i>=0;i--){
element.remove(i);
}
},
getAttributeOptions: function(attributeId){
if(this.config.attributes[attributeId]){
return this.config.attributes[attributeId].options;
}
},
reloadPrice: function(){
var price = 0;
var oldPrice = 0;
for(var i=this.settings.length-1;i>=0;i--){
var selected = this.settings[i].options[this.settings[i].selectedIndex];
if(selected.config){
price += parseFloat(selected.config.price);
oldPrice += parseFloat(selected.config.oldPrice);
}
}
optionsPrice.changePrice('config', {'price': price, 'oldPrice': oldPrice});
optionsPrice.reload();
return price;
if($('product-price-'+this.config.productId)){
$('product-price-'+this.config.productId).innerHTML = price;
}
this.reloadOldPrice();
},
reloadOldPrice: function(){
if ($('old-price-'+this.config.productId)) {
var price = parseFloat(this.config.oldPrice);
for(var i=this.settings.length-1;i>=0;i--){
var selected = this.settings[i].options[this.settings[i].selectedIndex];
if(selected.config){
price+= parseFloat(selected.config.price);
}
}
if (price < 0)
price = 0;
price = this.formatPrice(price);
if($('old-price-'+this.config.productId)){
$('old-price-'+this.config.productId).innerHTML = price;
}
}
}
}
/**************************** SUPER PRODUCTS ********************************/
Product.Super = {};
Product.Super.Configurable = Class.create();
Product.Super.Configurable.prototype = {
initialize: function(container, observeCss, updateUrl, updatePriceUrl, priceContainerId) {
this.container = $(container);
this.observeCss = observeCss;
this.updateUrl = updateUrl;
this.updatePriceUrl = updatePriceUrl;
this.priceContainerId = priceContainerId;
this.registerObservers();
},
registerObservers: function() {
var elements = this.container.getElementsByClassName(this.observeCss);
elements.each(function(element){
Event.observe(element, 'change', this.update.bindAsEventListener(this));
}.bind(this));
return this;
},
update: function(event) {
var elements = this.container.getElementsByClassName(this.observeCss);
var parameters = Form.serializeElements(elements, true);
new Ajax.Updater(this.container, this.updateUrl + '?ajax=1', {
parameters:parameters,
onComplete:this.registerObservers.bind(this)
});
var priceContainer = $(this.priceContainerId);
if(priceContainer) {
new Ajax.Updater(priceContainer, this.updatePriceUrl + '?ajax=1', {
parameters:parameters
});
}
}
}
/**************************** PRICE RELOADER ********************************/
Product.OptionsPrice = Class.create();
Product.OptionsPrice.prototype = {
initialize: function(config) {
this.productId = config.productId;
this.priceFormat = config.priceFormat;
this.includeTax = config.includeTax;
this.defaultTax = config.defaultTax;
this.currentTax = config.currentTax;
this.productPrice = config.productPrice;
this.showIncludeTax = config.showIncludeTax;
this.showBothPrices = config.showBothPrices;
this.productOldPrice = config.productOldPrice;
this.priceInclTax = config.priceInclTax;
this.priceExclTax = config.priceExclTax;
this.skipCalculate = config.skipCalculate;//@deprecated after 1.5.1.0
this.duplicateIdSuffix = config.idSuffix;
this.specialTaxPrice = config.specialTaxPrice;
this.oldPlusDisposition = config.oldPlusDisposition;
this.plusDisposition = config.plusDisposition;
this.oldMinusDisposition = config.oldMinusDisposition;
this.minusDisposition = config.minusDisposition;
this.optionPrices = {};
this.containers = {};
this.displayZeroPrice = true;
this.initPrices();
},
setDuplicateIdSuffix: function(idSuffix) {
this.duplicateIdSuffix = idSuffix;
},
initPrices: function() {
this.containers[0] = 'product-price-' + this.productId;
this.containers[1] = 'bundle-price-' + this.productId;
this.containers[2] = 'price-including-tax-' + this.productId;
this.containers[3] = 'price-excluding-tax-' + this.productId;
this.containers[4] = 'old-price-' + this.productId;
},
changePrice: function(key, price) {
this.optionPrices[key] = price;
},
getOptionPrices: function() {
var price = 0;
var nonTaxable = 0;
var oldPrice = 0;
var priceInclTax = 0;
var currentTax = this.currentTax;
$H(this.optionPrices).each(function(pair) {
if ('undefined' != typeof(pair.value.price) && 'undefined' != typeof(pair.value.oldPrice)) {
price += parseFloat(pair.value.price);
oldPrice += parseFloat(pair.value.oldPrice);
} else if (pair.key == 'nontaxable') {
nonTaxable = pair.value;
} else if (pair.key == 'priceInclTax') {
priceInclTax += pair.value;
} else if (pair.key == 'optionsPriceInclTax') {
priceInclTax += pair.value * (100 + currentTax) / 100;
} else {
price += parseFloat(pair.value);
oldPrice += parseFloat(pair.value);
}
});
var result = [price, nonTaxable, oldPrice, priceInclTax];
return result;
},
reload: function() {
var price;
var formattedPrice;
var optionPrices = this.getOptionPrices();
var nonTaxable = optionPrices[1];
var optionOldPrice = optionPrices[2];
var priceInclTax = optionPrices[3];
optionPrices = optionPrices[0];
$H(this.containers).each(function(pair) {
var _productPrice;
var _plusDisposition;
var _minusDisposition;
if ($(pair.value)) {
if (pair.value == 'old-price-'+this.productId && this.productOldPrice != this.productPrice) {
_productPrice = this.productOldPrice;
_plusDisposition = this.oldPlusDisposition;
_minusDisposition = this.oldMinusDisposition;
} else {
_productPrice = this.productPrice;
_plusDisposition = this.plusDisposition;
_minusDisposition = this.minusDisposition;
}
if (pair.value == 'old-price-'+this.productId && optionOldPrice !== undefined) {
price = optionOldPrice+parseFloat(_productPrice);
} else if (this.specialTaxPrice == 'true' && this.priceInclTax !== undefined && this.priceExclTax !== undefined) {
price = optionPrices+parseFloat(this.priceExclTax);
priceInclTax += this.priceInclTax;
} else {
price = optionPrices+parseFloat(_productPrice);
priceInclTax += parseFloat(_productPrice) * (100 + this.currentTax) / 100;
}
if (this.specialTaxPrice == 'true') {
var excl = price;
var incl = priceInclTax;
} else if (this.includeTax == 'true') {
// tax = tax included into product price by admin
var tax = price / (100 + this.defaultTax) * this.defaultTax;
var excl = price - tax;
var incl = excl*(1+(this.currentTax/100));
} else {
var tax = price * (this.currentTax / 100);
var excl = price;
var incl = excl + tax;
}
excl += parseFloat(_plusDisposition);
incl += parseFloat(_plusDisposition);
excl -= parseFloat(_minusDisposition);
incl -= parseFloat(_minusDisposition);
//adding nontaxlable part of options
excl += parseFloat(nonTaxable);
incl += parseFloat(nonTaxable);
if (pair.value == 'price-including-tax-'+this.productId) {
price = incl;
} else if (pair.value == 'price-excluding-tax-'+this.productId) {
price = excl;
} else if (pair.value == 'old-price-'+this.productId) {
if (this.showIncludeTax || this.showBothPrices) {
price = incl;
} else {
price = excl;
}
} else {
if (this.showIncludeTax) {
price = incl;
} else {
price = excl;
}
}
if (price < 0) price = 0;
if (price > 0 || this.displayZeroPrice) {
formattedPrice = this.formatPrice(price);
} else {
formattedPrice = '';
}
if ($(pair.value).select('.price')[0]) {
$(pair.value).select('.price')[0].innerHTML = formattedPrice;
if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).select('.price')[0]) {
$(pair.value+this.duplicateIdSuffix).select('.price')[0].innerHTML = formattedPrice;
}
} else {
$(pair.value).innerHTML = formattedPrice;
if ($(pair.value+this.duplicateIdSuffix)) {
$(pair.value+this.duplicateIdSuffix).innerHTML = formattedPrice;
}
}
};
}.bind(this));
},
formatPrice: function(price) {
return formatCurrency(price, this.priceFormat);
}
}
@creativetags

I added lines 67 - 70 to start the image centered vertically instead of at the top.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.