PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/js/varien/configurable.js

https://bitbucket.org/sevenly/magento-ce
JavaScript | 319 lines | 254 code | 33 blank | 32 comment | 65 complexity | a578e6e7aeba8e4588aecb068fe8b3f9 MD5 | raw file
  1. /**
  2. * Magento
  3. *
  4. * NOTICE OF LICENSE
  5. *
  6. * This source file is subject to the Academic Free License (AFL 3.0)
  7. * that is bundled with this package in the file LICENSE_AFL.txt.
  8. * It is also available through the world-wide-web at this URL:
  9. * http://opensource.org/licenses/afl-3.0.php
  10. * If you did not receive a copy of the license and are unable to
  11. * obtain it through the world-wide-web, please send an email
  12. * to license@magentocommerce.com so we can send you a copy immediately.
  13. *
  14. * DISCLAIMER
  15. *
  16. * Do not edit or add to this file if you wish to upgrade Magento to newer
  17. * versions in the future. If you wish to customize Magento for your
  18. * needs please refer to http://www.magentocommerce.com for more information.
  19. *
  20. * @category Varien
  21. * @package js
  22. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  23. * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
  24. */
  25. if (typeof Product == 'undefined') {
  26. var Product = {};
  27. }
  28. /**************************** CONFIGURABLE PRODUCT **************************/
  29. Product.Config = Class.create();
  30. Product.Config.prototype = {
  31. initialize: function(config){
  32. this.config = config;
  33. this.taxConfig = this.config.taxConfig;
  34. if (config.containerId) {
  35. this.settings = $$('#' + config.containerId + ' ' + '.super-attribute-select');
  36. } else {
  37. this.settings = $$('.super-attribute-select');
  38. }
  39. this.state = new Hash();
  40. this.priceTemplate = new Template(this.config.template);
  41. this.prices = config.prices;
  42. // Set default values from config
  43. if (config.defaultValues) {
  44. this.values = config.defaultValues;
  45. }
  46. // Overwrite defaults by url
  47. var separatorIndex = window.location.href.indexOf('#');
  48. if (separatorIndex != -1) {
  49. var paramsStr = window.location.href.substr(separatorIndex+1);
  50. var urlValues = paramsStr.toQueryParams();
  51. if (!this.values) {
  52. this.values = {};
  53. }
  54. for (var i in urlValues) {
  55. this.values[i] = urlValues[i];
  56. }
  57. }
  58. // Overwrite defaults by inputs values if needed
  59. if (config.inputsInitialized) {
  60. this.values = {};
  61. this.settings.each(function(element) {
  62. if (element.value) {
  63. var attributeId = element.id.replace(/[a-z]*/, '');
  64. this.values[attributeId] = element.value;
  65. }
  66. }.bind(this));
  67. }
  68. // Put events to check select reloads
  69. this.settings.each(function(element){
  70. Event.observe(element, 'change', this.configure.bind(this))
  71. }.bind(this));
  72. // fill state
  73. this.settings.each(function(element){
  74. var attributeId = element.id.replace(/[a-z]*/, '');
  75. if(attributeId && this.config.attributes[attributeId]) {
  76. element.config = this.config.attributes[attributeId];
  77. element.attributeId = attributeId;
  78. this.state[attributeId] = false;
  79. }
  80. }.bind(this))
  81. // Init settings dropdown
  82. var childSettings = [];
  83. for(var i=this.settings.length-1;i>=0;i--){
  84. var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
  85. var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
  86. if (i == 0){
  87. this.fillSelect(this.settings[i])
  88. } else {
  89. this.settings[i].disabled = true;
  90. }
  91. $(this.settings[i]).childSettings = childSettings.clone();
  92. $(this.settings[i]).prevSetting = prevSetting;
  93. $(this.settings[i]).nextSetting = nextSetting;
  94. childSettings.push(this.settings[i]);
  95. }
  96. // Set values to inputs
  97. this.configureForValues();
  98. document.observe("dom:loaded", this.configureForValues.bind(this));
  99. },
  100. configureForValues: function () {
  101. if (this.values) {
  102. this.settings.each(function(element){
  103. var attributeId = element.attributeId;
  104. element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
  105. this.configureElement(element);
  106. }.bind(this));
  107. }
  108. },
  109. configure: function(event){
  110. var element = Event.element(event);
  111. this.configureElement(element);
  112. },
  113. configureElement : function(element) {
  114. this.reloadOptionLabels(element);
  115. if(element.value){
  116. this.state[element.config.id] = element.value;
  117. if(element.nextSetting){
  118. element.nextSetting.disabled = false;
  119. this.fillSelect(element.nextSetting);
  120. this.resetChildren(element.nextSetting);
  121. }
  122. }
  123. else {
  124. this.resetChildren(element);
  125. }
  126. this.reloadPrice();
  127. },
  128. reloadOptionLabels: function(element){
  129. var selectedPrice;
  130. if(element.options[element.selectedIndex].config && !this.config.stablePrices){
  131. selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
  132. }
  133. else{
  134. selectedPrice = 0;
  135. }
  136. for(var i=0;i<element.options.length;i++){
  137. if(element.options[i].config){
  138. element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price-selectedPrice);
  139. }
  140. }
  141. },
  142. resetChildren : function(element){
  143. if(element.childSettings) {
  144. for(var i=0;i<element.childSettings.length;i++){
  145. element.childSettings[i].selectedIndex = 0;
  146. element.childSettings[i].disabled = true;
  147. if(element.config){
  148. this.state[element.config.id] = false;
  149. }
  150. }
  151. }
  152. },
  153. fillSelect: function(element){
  154. var attributeId = element.id.replace(/[a-z]*/, '');
  155. var options = this.getAttributeOptions(attributeId);
  156. this.clearSelect(element);
  157. element.options[0] = new Option(this.config.chooseText, '');
  158. var prevConfig = false;
  159. if(element.prevSetting){
  160. prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
  161. }
  162. if(options) {
  163. var index = 1;
  164. for(var i=0;i<options.length;i++){
  165. var allowedProducts = [];
  166. if(prevConfig) {
  167. for(var j=0;j<options[i].products.length;j++){
  168. if(prevConfig.config.allowedProducts
  169. && prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
  170. allowedProducts.push(options[i].products[j]);
  171. }
  172. }
  173. } else {
  174. allowedProducts = options[i].products.clone();
  175. }
  176. if(allowedProducts.size()>0){
  177. options[i].allowedProducts = allowedProducts;
  178. element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
  179. if (typeof options[i].price != 'undefined') {
  180. element.options[index].setAttribute('price', options[i].price);
  181. }
  182. element.options[index].config = options[i];
  183. index++;
  184. }
  185. }
  186. }
  187. },
  188. getOptionLabel: function(option, price){
  189. var price = parseFloat(price);
  190. if (this.taxConfig.includeTax) {
  191. var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
  192. var excl = price - tax;
  193. var incl = excl*(1+(this.taxConfig.currentTax/100));
  194. } else {
  195. var tax = price * (this.taxConfig.currentTax / 100);
  196. var excl = price;
  197. var incl = excl + tax;
  198. }
  199. if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
  200. price = incl;
  201. } else {
  202. price = excl;
  203. }
  204. var str = option.label;
  205. if(price){
  206. if (this.taxConfig.showBothPrices) {
  207. str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
  208. } else {
  209. str+= ' ' + this.formatPrice(price, true);
  210. }
  211. }
  212. return str;
  213. },
  214. formatPrice: function(price, showSign){
  215. var str = '';
  216. price = parseFloat(price);
  217. if(showSign){
  218. if(price<0){
  219. str+= '-';
  220. price = -price;
  221. }
  222. else{
  223. str+= '+';
  224. }
  225. }
  226. var roundedPrice = (Math.round(price*100)/100).toString();
  227. if (this.prices && this.prices[roundedPrice]) {
  228. str+= this.prices[roundedPrice];
  229. }
  230. else {
  231. str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
  232. }
  233. return str;
  234. },
  235. clearSelect: function(element){
  236. for(var i=element.options.length-1;i>=0;i--){
  237. element.remove(i);
  238. }
  239. },
  240. getAttributeOptions: function(attributeId){
  241. if(this.config.attributes[attributeId]){
  242. return this.config.attributes[attributeId].options;
  243. }
  244. },
  245. reloadPrice: function(){
  246. if (this.config.disablePriceReload) {
  247. return;
  248. }
  249. var price = 0;
  250. var oldPrice = 0;
  251. for(var i=this.settings.length-1;i>=0;i--){
  252. var selected = this.settings[i].options[this.settings[i].selectedIndex];
  253. if(selected.config){
  254. price += parseFloat(selected.config.price);
  255. oldPrice += parseFloat(selected.config.oldPrice);
  256. }
  257. }
  258. optionsPrice.changePrice('config', {'price': price, 'oldPrice': oldPrice});
  259. optionsPrice.reload();
  260. return price;
  261. if($('product-price-'+this.config.productId)){
  262. $('product-price-'+this.config.productId).innerHTML = price;
  263. }
  264. this.reloadOldPrice();
  265. },
  266. reloadOldPrice: function(){
  267. if (this.config.disablePriceReload) {
  268. return;
  269. }
  270. if ($('old-price-'+this.config.productId)) {
  271. var price = parseFloat(this.config.oldPrice);
  272. for(var i=this.settings.length-1;i>=0;i--){
  273. var selected = this.settings[i].options[this.settings[i].selectedIndex];
  274. if(selected.config){
  275. price+= parseFloat(selected.config.price);
  276. }
  277. }
  278. if (price < 0)
  279. price = 0;
  280. price = this.formatPrice(price);
  281. if($('old-price-'+this.config.productId)){
  282. $('old-price-'+this.config.productId).innerHTML = price;
  283. }
  284. }
  285. }
  286. }