Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

403 рядки
13 KiB

  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. define([
  6. 'jquery',
  7. 'Magento_Catalog/js/price-utils',
  8. 'underscore',
  9. 'jquery-ui-modules/widget',
  10. 'mage/dropdown',
  11. 'mage/template'
  12. ], function ($, priceUtils, _) {
  13. 'use strict';
  14. $.widget('mage.addToCart', {
  15. options: {
  16. showAddToCart: true,
  17. submitUrl: '',
  18. cartButtonId: '',
  19. singleOpenDropDown: true,
  20. dialog: {}, // Options for mage/dropdown
  21. dialogDelay: 500, // Delay in ms after resize dropdown shown again
  22. origin: '', //Required, type of popup: 'msrp', 'tier' or 'info' popup
  23. // Selectors
  24. cartForm: '.form.map.checkout',
  25. msrpLabelId: '#map-popup-msrp',
  26. msrpPriceElement: '#map-popup-msrp .price-wrapper',
  27. priceLabelId: '#map-popup-price',
  28. priceElement: '#map-popup-price .price',
  29. mapInfoLinks: '.map-show-info',
  30. displayPriceElement: '.old-price.map-old-price .price-wrapper',
  31. fallbackPriceElement: '.normal-price.map-fallback-price .price-wrapper',
  32. displayPriceContainer: '.old-price.map-old-price',
  33. fallbackPriceContainer: '.normal-price.map-fallback-price',
  34. popUpAttr: '[data-role=msrp-popup-template]',
  35. popupCartButtonId: '#map-popup-button',
  36. paypalCheckoutButons: '[data-action=checkout-form-submit]',
  37. popupId: '',
  38. realPrice: '',
  39. isSaleable: '',
  40. msrpPrice: '',
  41. helpLinkId: '',
  42. addToCartButton: '',
  43. // Text options
  44. productName: '',
  45. addToCartUrl: ''
  46. },
  47. openDropDown: null,
  48. triggerClass: 'dropdown-active',
  49. popUpOptions: {
  50. appendTo: 'body',
  51. dialogContentClass: 'active',
  52. closeOnMouseLeave: false,
  53. autoPosition: true,
  54. closeOnClickOutside: false,
  55. 'dialogClass': 'popup map-popup-wrapper',
  56. position: {
  57. my: 'left top',
  58. collision: 'fit none',
  59. at: 'left bottom',
  60. within: 'body'
  61. },
  62. shadowHinter: 'popup popup-pointer'
  63. },
  64. popupOpened: false,
  65. wasOpened: false,
  66. /**
  67. * Creates widget instance
  68. *
  69. * @private
  70. */
  71. _create: function () {
  72. if (this.options.origin === 'msrp') {
  73. this.initMsrpPopup();
  74. } else if (this.options.origin === 'info') {
  75. this.initInfoPopup();
  76. } else if (this.options.origin === 'tier') {
  77. this.initTierPopup();
  78. }
  79. $(this.options.cartButtonId).on('click', this._addToCartSubmit.bind(this));
  80. $(document).on('updateMsrpPriceBlock', this.onUpdateMsrpPrice.bind(this));
  81. $(this.options.cartForm).on('submit', this._onSubmitForm.bind(this));
  82. },
  83. /**
  84. * Init msrp popup
  85. *
  86. * @private
  87. */
  88. initMsrpPopup: function () {
  89. var popupDOM = $(this.options.popUpAttr)[0],
  90. $msrpPopup = $(popupDOM.innerHTML.trim());
  91. $msrpPopup.find(this.options.productIdInput).val(this.options.productId);
  92. $('body').append($msrpPopup);
  93. $msrpPopup.trigger('contentUpdated');
  94. $msrpPopup.find('button')
  95. .on('click',
  96. this.handleMsrpAddToCart.bind(this))
  97. .filter(this.options.popupCartButtonId)
  98. .text($(this.options.addToCartButton).text());
  99. $msrpPopup.find(this.options.paypalCheckoutButons).on('click',
  100. this.handleMsrpPaypalCheckout.bind(this));
  101. $(this.options.popupId).on('click',
  102. this.openPopup.bind(this));
  103. this.$popup = $msrpPopup;
  104. },
  105. /**
  106. * Init info popup
  107. *
  108. * @private
  109. */
  110. initInfoPopup: function () {
  111. var infoPopupDOM = $('[data-role=msrp-info-template]')[0],
  112. $infoPopup = $(infoPopupDOM.innerHTML.trim());
  113. $('body').append($infoPopup);
  114. $(this.options.helpLinkId).on('click', function (e) {
  115. this.popUpOptions.position.of = $(e.target);
  116. $infoPopup.dropdownDialog(this.popUpOptions).dropdownDialog('open');
  117. this._toggle($infoPopup);
  118. }.bind(this));
  119. this.$popup = $infoPopup;
  120. },
  121. /**
  122. * Init tier price popup
  123. * @private
  124. */
  125. initTierPopup: function () {
  126. var popupDOM = $(this.options.popUpAttr)[0],
  127. $tierPopup = $(popupDOM.innerHTML.trim());
  128. $('body').append($tierPopup);
  129. $tierPopup.find(this.options.productIdInput).val(this.options.productId);
  130. this.popUpOptions.position.of = $(this.options.helpLinkId);
  131. $tierPopup.find('button').on('click',
  132. this.handleTierAddToCart.bind(this))
  133. .filter(this.options.popupCartButtonId)
  134. .text($(this.options.addToCartButton).text());
  135. $tierPopup.find(this.options.paypalCheckoutButons).on('click',
  136. this.handleTierPaypalCheckout.bind(this));
  137. $(this.options.attr).on('click', function (e) {
  138. this.$popup = $tierPopup;
  139. this.tierOptions = $(e.target).data('tier-price');
  140. this.openPopup(e);
  141. }.bind(this));
  142. },
  143. /**
  144. * handle 'AddToCart' click on Msrp popup
  145. * @param {Object} ev
  146. *
  147. * @private
  148. */
  149. handleMsrpAddToCart: function (ev) {
  150. ev.preventDefault();
  151. if (this.options.addToCartButton) {
  152. $(this.options.addToCartButton).trigger('click');
  153. this.closePopup(this.$popup);
  154. }
  155. },
  156. /**
  157. * handle 'paypal checkout buttons' click on Msrp popup
  158. *
  159. * @private
  160. */
  161. handleMsrpPaypalCheckout: function () {
  162. this.closePopup(this.$popup);
  163. },
  164. /**
  165. * handle 'AddToCart' click on Tier popup
  166. *
  167. * @param {Object} ev
  168. * @private
  169. */
  170. handleTierAddToCart: function (ev) {
  171. ev.preventDefault();
  172. if (this.options.addToCartButton &&
  173. this.options.inputQty && !isNaN(this.tierOptions.qty)
  174. ) {
  175. $(this.options.inputQty).val(this.tierOptions.qty);
  176. $(this.options.addToCartButton).trigger('click');
  177. this.closePopup(this.$popup);
  178. }
  179. },
  180. /**
  181. * handle 'paypal checkout buttons' click on Tier popup
  182. *
  183. * @private
  184. */
  185. handleTierPaypalCheckout: function () {
  186. if (this.options.inputQty && !isNaN(this.tierOptions.qty)
  187. ) {
  188. $(this.options.inputQty).val(this.tierOptions.qty);
  189. this.closePopup(this.$popup);
  190. }
  191. },
  192. /**
  193. * Open and set up popup
  194. *
  195. * @param {Object} event
  196. */
  197. openPopup: function (event) {
  198. var options = this.tierOptions || this.options;
  199. this.popUpOptions.position.of = $(event.target);
  200. if (!this.wasOpened) {
  201. this.$popup.find(this.options.msrpLabelId).html(options.msrpPrice);
  202. this.$popup.find(this.options.priceLabelId).html(options.realPrice);
  203. this.wasOpened = true;
  204. }
  205. this.$popup.dropdownDialog(this.popUpOptions).dropdownDialog('open');
  206. this._toggle(this.$popup);
  207. if (!this.options.isSaleable) {
  208. this.$popup.find('form').hide();
  209. }
  210. },
  211. /**
  212. * Toggle MAP popup visibility
  213. *
  214. * @param {HTMLElement} $elem
  215. * @private
  216. */
  217. _toggle: function ($elem) {
  218. $(document).on('mouseup.msrp touchend.msrp', function (e) {
  219. if (!$elem.is(e.target) && $elem.has(e.target).length === 0) {
  220. this.closePopup($elem);
  221. }
  222. }.bind(this));
  223. $(window).on('resize', function () {
  224. this.closePopup($elem);
  225. }.bind(this));
  226. },
  227. /**
  228. * Close MAP information popup
  229. *
  230. * @param {HTMLElement} $elem
  231. */
  232. closePopup: function ($elem) {
  233. $elem.dropdownDialog('close');
  234. $(document).off('mouseup.msrp touchend.msrp');
  235. },
  236. /**
  237. * Handler for addToCart action
  238. *
  239. * @param {Object} e
  240. */
  241. _addToCartSubmit: function (e) {
  242. this.element.trigger('addToCart', this.element);
  243. if (this.element.data('stop-processing')) {
  244. return false;
  245. }
  246. if (this.options.addToCartButton) {
  247. $(this.options.addToCartButton).trigger('click');
  248. return false;
  249. }
  250. if (this.options.addToCartUrl) {
  251. $('.mage-dropdown-dialog > .ui-dialog-content').dropdownDialog('close');
  252. }
  253. e.preventDefault();
  254. $(this.options.cartForm).trigger('submit');
  255. },
  256. /**
  257. * Call on event updatePrice. Proxy to updateMsrpPrice method.
  258. *
  259. * @param {Event} event
  260. * @param {mixed} priceIndex
  261. * @param {Object} prices
  262. * @param {Object|undefined} $priceBox
  263. */
  264. onUpdateMsrpPrice: function onUpdateMsrpPrice(event, priceIndex, prices, $priceBox) {
  265. var defaultMsrp,
  266. defaultPrice,
  267. msrpPrice,
  268. finalPrice;
  269. defaultMsrp = _.chain(prices).map(function (price) {
  270. return price.msrpPrice.amount;
  271. }).reject(function (p) {
  272. return p === null;
  273. }).max().value();
  274. defaultPrice = _.chain(prices).map(function (p) {
  275. return p.finalPrice.amount;
  276. }).min().value();
  277. if (typeof priceIndex !== 'undefined') {
  278. msrpPrice = prices[priceIndex].msrpPrice.amount;
  279. finalPrice = prices[priceIndex].finalPrice.amount;
  280. if (msrpPrice === null || msrpPrice <= finalPrice) {
  281. this.updateNonMsrpPrice(priceUtils.formatPriceLocale(finalPrice), $priceBox);
  282. } else {
  283. this.updateMsrpPrice(
  284. priceUtils.formatPriceLocale(finalPrice),
  285. priceUtils.formatPriceLocale(msrpPrice),
  286. false,
  287. $priceBox);
  288. }
  289. } else {
  290. this.updateMsrpPrice(
  291. priceUtils.formatPriceLocale(defaultPrice),
  292. priceUtils.formatPriceLocale(defaultMsrp),
  293. true,
  294. $priceBox);
  295. }
  296. },
  297. /**
  298. * Update prices for configurable product with MSRP enabled
  299. *
  300. * @param {String} finalPrice
  301. * @param {String} msrpPrice
  302. * @param {Boolean} useDefaultPrice
  303. * @param {Object|undefined} $priceBox
  304. */
  305. updateMsrpPrice: function (finalPrice, msrpPrice, useDefaultPrice, $priceBox) {
  306. var options = this.tierOptions || this.options;
  307. $(this.options.fallbackPriceContainer, $priceBox).hide();
  308. $(this.options.displayPriceContainer, $priceBox).show();
  309. $(this.options.mapInfoLinks, $priceBox).show();
  310. if (useDefaultPrice || !this.wasOpened) {
  311. if (this.$popup) {
  312. this.$popup.find(this.options.msrpLabelId).html(options.msrpPrice);
  313. this.$popup.find(this.options.priceLabelId).html(options.realPrice);
  314. }
  315. $(this.options.displayPriceElement, $priceBox).html(msrpPrice);
  316. this.wasOpened = true;
  317. }
  318. if (!useDefaultPrice) {
  319. this.$popup.find(this.options.msrpPriceElement).html(msrpPrice);
  320. this.$popup.find(this.options.priceElement).html(finalPrice);
  321. $(this.options.displayPriceElement, $priceBox).html(msrpPrice);
  322. }
  323. },
  324. /**
  325. * Display non MAP price for irrelevant products
  326. *
  327. * @param {String} price
  328. * @param {Object|undefined} $priceBox
  329. */
  330. updateNonMsrpPrice: function (price, $priceBox) {
  331. $(this.options.fallbackPriceElement, $priceBox).html(price);
  332. $(this.options.displayPriceContainer, $priceBox).hide();
  333. $(this.options.mapInfoLinks, $priceBox).hide();
  334. $(this.options.fallbackPriceContainer, $priceBox).show();
  335. },
  336. /**
  337. * Handler for submit form
  338. *
  339. * @private
  340. */
  341. _onSubmitForm: function () {
  342. if ($(this.options.cartForm).valid()) {
  343. $(this.options.cartButtonId).prop('disabled', true);
  344. }
  345. }
  346. });
  347. return $.mage.addToCart;
  348. });