Guest User

check

a guest
Mar 2nd, 2016
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.24 KB | None | 0 0
  1. /*
  2. Some of these override earlier varien/product.js methods, therefore
  3. varien/product.js must have been included prior to this file.
  4. */
  5.  
  6. Product.Config.prototype.getMatchingSimpleProduct = function(){
  7. var inScopeProductIds = this.getInScopeProductIds();
  8. if ((typeof inScopeProductIds != 'undefined') && (inScopeProductIds.length == 1)) {
  9. return inScopeProductIds[0];
  10. }
  11. return false;
  12. };
  13.  
  14. /*
  15. Find products which are within consideration based on user's selection of
  16. config options so far
  17. Returns a normal array containing product ids
  18. allowedProducts is a normal numeric array containing product ids.
  19. childProducts is a hash keyed on product id
  20. optionalAllowedProducts lets you pass a set of products to restrict by,
  21. in addition to just using the ones already selected by the user
  22. */
  23. Product.Config.prototype.getInScopeProductIds = function(optionalAllowedProducts) {
  24.  
  25. var childProducts = this.config.childProducts;
  26. var allowedProducts = [];
  27.  
  28. if ((typeof optionalAllowedProducts != 'undefined') && (optionalAllowedProducts.length > 0)) {
  29. // alert("starting with: " + optionalAllowedProducts.inspect());
  30. allowedProducts = optionalAllowedProducts;
  31. }
  32.  
  33. for(var s=0, len=this.settings.length-1; s<=len; s++) {
  34. if (this.settings[s].selectedIndex <= 0){
  35. break;
  36. }
  37. var selected = this.settings[s].options[this.settings[s].selectedIndex];
  38. if (s==0 && allowedProducts.length == 0){
  39. allowedProducts = selected.config.allowedProducts;
  40. } else {
  41. // alert("merging: " + allowedProducts.inspect() + " with: " + selected.config.allowedProducts.inspect());
  42. allowedProducts = allowedProducts.intersect(selected.config.allowedProducts).uniq();
  43. // alert("to give: " + allowedProducts.inspect());
  44. }
  45. }
  46.  
  47. //If we can't find any products (because nothing's been selected most likely)
  48. //then just use all product ids.
  49. if ((typeof allowedProducts == 'undefined') || (allowedProducts.length == 0)) {
  50. productIds = Object.keys(childProducts);
  51. } else {
  52. productIds = allowedProducts;
  53. }
  54. return productIds;
  55. };
  56.  
  57.  
  58. Product.Config.prototype.getProductIdOfCheapestProductInScope = function(priceType, optionalAllowedProducts) {
  59.  
  60. var childProducts = this.config.childProducts;
  61. var productIds = this.getInScopeProductIds(optionalAllowedProducts);
  62.  
  63. var minPrice = Infinity;
  64. var lowestPricedProdId = false;
  65.  
  66. //Get lowest price from product ids.
  67. for (var x=0, len=productIds.length; x<len; ++x) {
  68. var thisPrice = Number(childProducts[productIds[x]][priceType]);
  69. if (thisPrice < minPrice) {
  70. minPrice = thisPrice;
  71. lowestPricedProdId = productIds[x];
  72. }
  73. }
  74. return lowestPricedProdId;
  75. };
  76.  
  77.  
  78. Product.Config.prototype.getProductIdOfMostExpensiveProductInScope = function(priceType, optionalAllowedProducts) {
  79.  
  80. var childProducts = this.config.childProducts;
  81. var productIds = this.getInScopeProductIds(optionalAllowedProducts);
  82.  
  83. var maxPrice = 0;
  84. var highestPricedProdId = false;
  85.  
  86. //Get highest price from product ids.
  87. for (var x=0, len=productIds.length; x<len; ++x) {
  88. var thisPrice = Number(childProducts[productIds[x]][priceType]);
  89. if (thisPrice >= maxPrice) {
  90. maxPrice = thisPrice;
  91. highestPricedProdId = productIds[x];
  92. }
  93. }
  94. return highestPricedProdId;
  95. };
  96.  
  97.  
  98.  
  99. Product.Config.prototype.updateFormProductId = function(productId){
  100. if (!productId) {
  101. return false;
  102. }
  103. var currentAction = $('product_addtocart_form').action;
  104. newcurrentAction = currentAction.sub(/product\/\d+\//, 'product/' + productId + '/');
  105. $('product_addtocart_form').action = newcurrentAction;
  106. $('product_addtocart_form').product.value = productId;
  107. };
  108.  
  109.  
  110. Product.Config.prototype.addParentProductIdToCartForm = function(parentProductId) {
  111. if (typeof $('product_addtocart_form').cpid != 'undefined') {
  112. return; //don't create it if we have one..
  113. }
  114. var el = document.createElement("input");
  115. el.type = "hidden";
  116. el.name = "cpid";
  117. el.value = parentProductId.toString();
  118. $('product_addtocart_form').appendChild(el);
  119. };
  120.  
  121.  
  122.  
  123. Product.OptionsPrice.prototype.updateSpecialPriceDisplay = function(price, finalPrice) {
  124.  
  125. var prodForm = $('product_addtocart_form');
  126.  
  127. var specialPriceBox = prodForm.select('p.special-price');
  128. var oldPricePriceBox = prodForm.select('p.old-price, p.was-old-price');
  129. var magentopriceLabel = prodForm.select('span.price-label');
  130.  
  131. if (price == finalPrice) {
  132. specialPriceBox.each(function(x) {x.hide();});
  133. magentopriceLabel.each(function(x) {x.hide();});
  134. oldPricePriceBox.each(function(x) {
  135. x.removeClassName('old-price');
  136. x.addClassName('was-old-price');
  137. });
  138. }else{
  139. specialPriceBox.each(function(x) {x.show();});
  140. magentopriceLabel.each(function(x) {x.show();});
  141. oldPricePriceBox.each(function(x) {
  142. x.removeClassName('was-old-price');
  143. x.addClassName('old-price');
  144. });
  145. }
  146. };
  147.  
  148. //This triggers reload of price and other elements that can change
  149. //once all options are selected
  150. Product.Config.prototype.reloadPrice = function() {
  151. var childProductId = this.getMatchingSimpleProduct();
  152. var childProducts = this.config.childProducts;
  153. var usingZoomer = false;
  154. if(this.config.imageZoomer){
  155. usingZoomer = true;
  156. }
  157.  
  158. if(childProductId){
  159. var price = childProducts[childProductId]["price"];
  160. var finalPrice = childProducts[childProductId]["finalPrice"];
  161. optionsPrice.productPrice = finalPrice;
  162. optionsPrice.productOldPrice = price;
  163. optionsPrice.reload();
  164. optionsPrice.reloadPriceLabels(true);
  165. optionsPrice.updateSpecialPriceDisplay(price, finalPrice);
  166. this.updateProductShortDescription(childProductId);
  167. this.updateProductDescription(childProductId);
  168. this.updateProductName(childProductId);
  169. this.updateProductAttributes(childProductId);
  170. this.updateFormProductId(childProductId);
  171. this.addParentProductIdToCartForm(this.config.productId);
  172. this.showCustomOptionsBlock(childProductId, this.config.productId);
  173. if (usingZoomer) {
  174. this.showFullImageDiv(childProductId, this.config.productId);
  175. }else{
  176. this.updateProductImage(childProductId);
  177. }
  178.  
  179.  
  180.  
  181. var discountAmount = ((price - finalPrice) / price) * 100;
  182. jQuery('.you_save_price').text(discountAmount + '%');
  183.  
  184. } else {
  185. var cheapestPid = this.getProductIdOfCheapestProductInScope("finalPrice");
  186. //var mostExpensivePid = this.getProductIdOfMostExpensiveProductInScope("finalPrice");
  187. var price = childProducts[cheapestPid]["price"];
  188. var finalPrice = childProducts[cheapestPid]["finalPrice"];
  189. optionsPrice.productPrice = finalPrice;
  190. optionsPrice.productOldPrice = price;
  191. optionsPrice.reload();
  192. optionsPrice.reloadPriceLabels(false);
  193. optionsPrice.updateSpecialPriceDisplay(price, finalPrice);
  194. this.updateProductShortDescription(false);
  195. this.updateProductDescription(false);
  196. this.updateProductName(false);
  197. this.updateProductAttributes(false);
  198. this.showCustomOptionsBlock(false, false);
  199. if (usingZoomer) {
  200. this.showFullImageDiv(false, false);
  201. }else{
  202. this.updateProductImage(false);
  203. }
  204. }
  205. };
  206.  
  207.  
  208.  
  209. Product.Config.prototype.updateProductImage = function(productId) {
  210. var imageUrl = this.config.imageUrl;
  211. if(productId && this.config.childProducts[productId].imageUrl) {
  212. imageUrl = this.config.childProducts[productId].imageUrl;
  213. }
  214.  
  215. if (!imageUrl) {
  216. return;
  217. }
  218.  
  219. if($('image')) {
  220. $('image').src = imageUrl;
  221. } else {
  222. $$('#product_addtocart_form p.product-image img').each(function(el) {
  223. var dims = el.getDimensions();
  224. el.src = imageUrl;
  225. el.width = dims.width;
  226. el.height = dims.height;
  227. });
  228. }
  229. };
  230.  
  231. Product.Config.prototype.updateProductName = function(productId) {
  232. var productName = this.config.productName;
  233. if (productId && this.config.childProducts[productId].productName) {
  234. productName = this.config.childProducts[productId].productName;
  235. }
  236. $$('#product_addtocart_form div.product-name h1').each(function(el) {
  237. el.innerHTML = productName;
  238. });
  239. };
  240.  
  241. Product.Config.prototype.updateProductShortDescription = function(productId) {
  242. var shortDescription = this.config.shortDescription;
  243. if (productId && this.config.childProducts[productId].shortDescription) {
  244. shortDescription = this.config.childProducts[productId].shortDescription;
  245. }
  246. $$('#product_addtocart_form div.short-description div.std').each(function(el) {
  247. el.innerHTML = shortDescription;
  248. });
  249. };
  250.  
  251. Product.Config.prototype.updateProductDescription = function(productId) {
  252. var description = this.config.description;
  253. if (productId && this.config.childProducts[productId].description) {
  254. description = this.config.childProducts[productId].description;
  255. }
  256. $$('div.box-description div.std').each(function(el) {
  257. el.innerHTML = description;
  258. });
  259. };
  260.  
  261. Product.Config.prototype.updateProductAttributes = function(productId) {
  262. var productAttributes = this.config.productAttributes;
  263. if (productId && this.config.childProducts[productId].productAttributes) {
  264. productAttributes = this.config.childProducts[productId].productAttributes;
  265. }
  266. //If config product doesn't already have an additional information section,
  267. //it won't be shown for associated product either. It's too hard to work out
  268. //where to place it given that different themes use very different html here
  269. $$('div.product-collateral div.box-additional').each(function(el) {
  270. el.innerHTML = productAttributes;
  271. decorateTable('product-attribute-specs-table');
  272. });
  273. };
  274.  
  275. Product.Config.prototype.showCustomOptionsBlock = function(productId, parentId) {
  276. var coUrl = this.config.ajaxBaseUrl + "co/?id=" + productId + '&pid=' + parentId;
  277. var prodForm = $('product_addtocart_form');
  278.  
  279. if ($('SCPcustomOptionsDiv')==null) {
  280. return;
  281. }
  282.  
  283. Effect.Fade('SCPcustomOptionsDiv', { duration: 0.5, from: 1, to: 0.5 });
  284. if(productId) {
  285. //Uncomment the line below if you want an ajax loader to appear while any custom
  286. //options are being loaded.
  287. //$$('span.scp-please-wait').each(function(el) {el.show()});
  288.  
  289. //prodForm.getElements().each(function(el) {el.disable()});
  290. new Ajax.Updater('SCPcustomOptionsDiv', coUrl, {
  291. method: 'get',
  292. evalScripts: true,
  293. onComplete: function() {
  294. $$('span.scp-please-wait').each(function(el) {el.hide()});
  295. Effect.Fade('SCPcustomOptionsDiv', { duration: 0.5, from: 0.5, to: 1 });
  296. //prodForm.getElements().each(function(el) {el.enable()});
  297. }
  298. });
  299. } else {
  300. $('SCPcustomOptionsDiv').innerHTML = '';
  301. try{window.opConfig = new Product.Options([]);} catch(e){}
  302. }
  303. };
  304.  
  305.  
  306. Product.Config.prototype.showFullImageDiv = function(productId, parentId) {
  307. var imgUrl = this.config.ajaxBaseUrl + "image/?id=" + productId + '&pid=' + parentId;
  308. var prodForm = $('product_addtocart_form');
  309. var destElement = false;
  310. var defaultZoomer = this.config.imageZoomer;
  311.  
  312. prodForm.select('div.product-img-box').each(function(el) {
  313. destElement = el;
  314. });
  315.  
  316. //TODO: This is needed to reinitialise Product.Zoom correctly,
  317. //but there's still a race condition (in the onComplete below) which can break it
  318. try {product_zoom.draggable.destroy();} catch(x) {}
  319.  
  320. if(productId) {
  321. new Ajax.Updater(destElement, imgUrl, {
  322. method: 'get',
  323. evalScripts: false,
  324. onComplete: function() {
  325. //Product.Zoom needs the *image* (not just the html source from the ajax)
  326. //to have loaded before it works, hence image object and onload handler
  327. if ($('image')){
  328. var imgObj = new Image();
  329. imgObj.onload = function() {product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint'); };
  330. imgObj.src = $('image').src;
  331. } else {
  332. destElement.innerHTML = defaultZoomer;
  333. product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint')
  334. }
  335. }
  336. });
  337. } else {
  338. destElement.innerHTML = defaultZoomer;
  339. product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint');
  340. }
  341. };
  342.  
  343.  
  344.  
  345. Product.OptionsPrice.prototype.reloadPriceLabels = function(productPriceIsKnown) {
  346. var priceFromLabel = '';
  347. var prodForm = $('product_addtocart_form');
  348.  
  349. if (!productPriceIsKnown && typeof spConfig != "undefined") {
  350. priceFromLabel = spConfig.config.priceFromLabel;
  351. }
  352.  
  353. var priceSpanId = 'configurable-price-from-' + this.productId;
  354. var duplicatePriceSpanId = priceSpanId + this.duplicateIdSuffix;
  355.  
  356. if($(priceSpanId) && $(priceSpanId).select('span.configurable-price-from-label'))
  357. $(priceSpanId).select('span.configurable-price-from-label').each(function(label) {
  358. label.innerHTML = priceFromLabel;
  359. });
  360.  
  361. if ($(duplicatePriceSpanId) && $(duplicatePriceSpanId).select('span.configurable-price-from-label')) {
  362. $(duplicatePriceSpanId).select('span.configurable-price-from-label').each(function(label) {
  363. label.innerHTML = priceFromLabel;
  364. });
  365. }
  366. };
  367.  
  368.  
  369.  
  370. //SCP: Forces the 'next' element to have it's optionLabels reloaded too
  371. Product.Config.prototype.configureElement = function(element) {
  372. this.reloadOptionLabels(element);
  373. if(element.value){
  374. this.state[element.config.id] = element.value;
  375. if(element.nextSetting){
  376. element.nextSetting.disabled = false;
  377. this.fillSelect(element.nextSetting);
  378. this.reloadOptionLabels(element.nextSetting);
  379. this.resetChildren(element.nextSetting);
  380. }
  381. }
  382. else {
  383. this.resetChildren(element);
  384. }
  385. this.reloadPrice();
  386. };
  387.  
  388.  
  389. //SCP: Changed logic to use absolute price ranges rather than price differentials
  390. Product.Config.prototype.reloadOptionLabels = function(element){
  391. var selectedPrice;
  392. var childProducts = this.config.childProducts;
  393.  
  394. //Don't update elements that have a selected option
  395. if(element.options[element.selectedIndex].config){
  396. return;
  397. }
  398.  
  399. for(var i=0;i<element.options.length;i++){
  400. if(element.options[i].config){
  401. var cheapestPid = this.getProductIdOfCheapestProductInScope("finalPrice", element.options[i].config.allowedProducts);
  402. var mostExpensivePid = this.getProductIdOfMostExpensiveProductInScope("finalPrice", element.options[i].config.allowedProducts);
  403. var cheapestFinalPrice = childProducts[cheapestPid]["finalPrice"];
  404. var mostExpensiveFinalPrice = childProducts[mostExpensivePid]["finalPrice"];
  405. element.options[i].text = this.getOptionLabel(element.options[i].config, cheapestFinalPrice, mostExpensiveFinalPrice);
  406. }
  407. }
  408. };
  409.  
  410. //SCP: Changed label formatting to show absolute price ranges rather than price differentials
  411. Product.Config.prototype.getOptionLabel = function(option, lowPrice, highPrice){
  412.  
  413. var str = option.label;
  414.  
  415. if (!this.config.showPriceRangesInOptions) {
  416. return str;
  417. }
  418.  
  419. var to = ' ' + this.config.rangeToLabel + ' ';
  420. var separator = ': ';
  421.  
  422. lowPrices = this.getTaxPrices(lowPrice);
  423. highPrices = this.getTaxPrices(highPrice);
  424.  
  425. if(lowPrice && highPrice){
  426. if (lowPrice != highPrice) {
  427. if (this.taxConfig.showBothPrices) {
  428. str+= separator + this.formatPrice(lowPrices[2], false) + ' (' + this.formatPrice(lowPrices[1], false) + ' ' + this.taxConfig.inclTaxTitle + ')';
  429. str+= to + this.formatPrice(highPrices[2], false) + ' (' + this.formatPrice(highPrices[1], false) + ' ' + this.taxConfig.inclTaxTitle + ')';
  430. } else {
  431. str+= separator + this.formatPrice(lowPrices[0], false);
  432. str+= to + this.formatPrice(highPrices[0], false);
  433. }
  434. } else {
  435. if (this.taxConfig.showBothPrices) {
  436. str+= separator + this.formatPrice(lowPrices[2], false) + ' (' + this.formatPrice(lowPrices[1], false) + ' ' + this.taxConfig.inclTaxTitle + ')';
  437. } else {
  438. str+= separator + this.formatPrice(lowPrices[0], false);
  439. }
  440. }
  441. }
  442. return str;
  443. };
  444.  
  445.  
  446. //SCP: Refactored price calculations into separate function
  447. Product.Config.prototype.getTaxPrices = function(price) {
  448. var price = parseFloat(price);
  449.  
  450. if (this.taxConfig.includeTax) {
  451. var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
  452. var excl = price - tax;
  453. var incl = excl*(1+(this.taxConfig.currentTax/100));
  454. } else {
  455. var tax = price * (this.taxConfig.currentTax / 100);
  456. var excl = price;
  457. var incl = excl + tax;
  458. }
  459.  
  460. if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
  461. price = incl;
  462. } else {
  463. price = excl;
  464. }
  465.  
  466. return [price, incl, excl];
  467. };
  468.  
  469.  
  470. //SCP: Forces price labels to be updated on load
  471. //so that first select shows ranges from the start
  472. document.observe("dom:loaded", function() {
  473. //Really only needs to be the first element that has configureElement set on it,
  474. //rather than all.
  475. $('product_addtocart_form').getElements().each(function(el) {
  476. if(el.type == 'select-one') {
  477. if(el.options && (el.options.length > 1)) {
  478. el.options[0].selected = true;
  479. spConfig.reloadOptionLabels(el);
  480. }
  481. }
  482. });
  483. });
Add Comment
Please, Sign In to add comment