0byt3m1n1
Path:
/
data
/
applications
/
aps
/
magento
/
1.1.3-2
/
standard
/
htdocs
/
js
/
varien
/
[
Home
]
File: product.js
/** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/osl-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. * * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 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('main-product-img'); return; } this.imageX = 0; this.imageY = 0; 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; //TODO: hide selects for IE only 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 ? '999' : '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; this.imageZoom = this.floorZoom+(v*(this.ceilingZoom-this.floorZoom)); this.imageEl.style.width = (this.imageZoom*this.containerDim.width)+'px'; if(this.containerDim.ratio){ this.imageEl.style.height = (this.imageZoom*this.containerDim.width*this.containerDim.ratio)+'px'; // for safari } 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() { this.zoomBtnPressed = true; this.sliderAccel = .002; this.periodicalZoom(); this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05); return this; }, startZoomOut: function() { 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; 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.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]); } // try retireve options from url var separatorIndex = window.location.href.indexOf('#'); if (separatorIndex!=-1) { var paramsStr = window.location.href.substr(separatorIndex+1); this.values = paramsStr.toQueryParams(); this.settings.each(function(element){ var attributeId = element.attributeId; element.value = 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); var str = option.label; if(price){ 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 = parseFloat(this.config.basePrice); var price = 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); } } if (price < 0) price = 0; // price = this.formatPrice(price); optionsPrice.changePrice('config', price); 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.productPrice = config.productPrice; this.skipCalculate = config.skipCalculate; this.duplicateIdSuffix = config.idSuffix; this.optionPrices = {}; this.containers = {}; 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; }, changePrice: function(key, price) { this.optionPrices[key] = parseFloat(price); }, getOptionPrices: function() { var result = 0; $H(this.optionPrices).each(function(pair) { result += pair.value; }); return result; }, reload: function() { var price; var formattedPrice; var optionPrices = this.getOptionPrices(); $H(this.containers).each(function(pair) { if ($(pair.value)) { var price = optionPrices+parseFloat(this.productPrice) 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.defaultTax / 100); var excl = price; var incl = excl + tax; } if (pair.value == 'price-including-tax-'+this.productId) { price = incl; } else { if (this.showIncludeTax) { price = incl; } else { if (!this.skipCalculate || this.productPrice == 0) { price = excl; } else { price = optionPrices+parseFloat(this.productPrice); } } } if (price < 0) price = 0; formattedPrice = this.formatPrice(price); if ($(pair.value).getElementsBySelector('.price')[0]) { $(pair.value).getElementsBySelector('.price')[0].innerHTML = formattedPrice; if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).getElementsBySelector('.price')[0]) { $(pair.value+this.duplicateIdSuffix).getElementsBySelector('.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); } }