diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab816169f9..640ae5d239 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Release Notes for Craft Commerce
+## Unreleased
+
+### Changed
+- Related sales are now populated on demand when the variant is visible on the Edit Product page. ([#1883](https://github.com/craftcms/commerce/issues/1883))
+
### Fixed
- Fixed a bug where sending an email and downloading a pdf that's using twig template doesn't get the correct order locale. ([#1876](https://github.com/craftcms/commerce/issues/1876))
diff --git a/src/templates/products/_fields.html b/src/templates/products/_fields.html
index c1d71b9e93..4ee2c4fe40 100644
--- a/src/templates/products/_fields.html
+++ b/src/templates/products/_fields.html
@@ -242,6 +242,7 @@
{%- import "_includes/forms" as forms -%}
{% set output %}
{% if not showAddAll %}
+
{# Add to existing sale #}
diff --git a/src/web/assets/editproduct/dist/js/CommerceProductEdit.js b/src/web/assets/editproduct/dist/js/CommerceProductEdit.js
index 4b645ec218..e6d9491a87 100644
--- a/src/web/assets/editproduct/dist/js/CommerceProductEdit.js
+++ b/src/web/assets/editproduct/dist/js/CommerceProductEdit.js
@@ -14,20 +14,28 @@ Craft.Commerce.ProductEdit = Garnish.Base.extend({
$salesList: null,
$discountsList: null,
salesListSelector: '.product-sales.commerce-sales',
+ spinnerSelector: '.product-sales.commerce-sales-spinner',
discountListSelector: '.product-discounts.commerce-discounts',
saleIdsByVariantId: {},
discountIdsByVariantId: {},
$container: null,
+ $window: null,
init: function(settings) {
+ var _this = this;
this.setSettings(settings, this.defaults);
this.$container = $(this.settings.container);
+ this.$window = $(window);
if (this.$container && this.$container.length) {
// List sales
this.$salesList = this.$container.find(this.salesListSelector);
if (this.$salesList && this.$salesList.length) {
- this.populateSalesList();
+ this.$window.scroll(function(ev) {
+ _this.checkSalesInView();
+ });
+
+ _this.checkSalesInView();
}
this.$discountsList = this.$container.find(this.discountListSelector);
@@ -43,6 +51,25 @@ Craft.Commerce.ProductEdit = Garnish.Base.extend({
}
},
+ checkSalesInView: function() {
+ if (this.$salesList && this.$salesList.length) {
+ var _this = this;
+ this.$salesList.each(function(el) {
+ var $spinner = _this.$container.find(_this.spinnerSelector + '[data-id="' + $(this).data('id') + '"]');
+ if (!$spinner.hasClass('hidden') && !$spinner.data('loading')) {
+ var top_of_element = $(this).offset().top;
+ var bottom_of_element = $(this).offset().top + $(this).outerHeight();
+ var bottom_of_screen = _this.$window.scrollTop() + _this.$window.innerHeight();
+ var top_of_screen = _this.$window.scrollTop();
+
+ if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
+ _this.populateSaleList($(this));
+ }
+ }
+ });
+ }
+ },
+
handleAddToSale: function(ev) {
ev.preventDefault();
var el = $(ev.target);
@@ -56,10 +83,27 @@ Craft.Commerce.ProductEdit = Garnish.Base.extend({
});
},
+ resetSales: function() {
+ var $spinners = this.$container.find(this.spinnerSelector);
+
+ if (this.$salesList && this.$salesList.length) {
+ this.$salesList.each(function() {
+ $(this).empty();
+ });
+ }
+
+ if ($spinners && $spinners.length) {
+ $spinners.each(function() {
+ $(this).removeClass('hidden');
+ });
+ }
+ this.checkSalesInView();
+ },
+
createSalesModal: function(id, sales) {
var data = {
existingSaleIds: [],
- onHide: $.proxy(this, 'populateSalesList')
+ onHide: $.proxy(this, 'resetSales')
};
if (id === 'all') {
@@ -71,36 +115,39 @@ Craft.Commerce.ProductEdit = Garnish.Base.extend({
var salesModal = new Craft.Commerce.ProductSalesModal(sales, data);
},
- populateSalesList: function() {
- if (this.$salesList && this.$salesList.length) {
- var _this = this;
- this.$salesList.each(function(el) {
- var element = $(this);
- var id = element.data('id');
- var data = {
- id: id
- };
- element.empty();
+ populateSaleList: function(element) {
+ var _this = this;
+ var id = element.data('id');
+ var $spinner = _this.$container.find(_this.spinnerSelector + '[data-id="' + id + '"]');
+ var data = {
+ id: id
+ };
- Craft.postActionRequest('commerce/sales/get-sales-by-purchasable-id', data, function(response) {
- if (response && response.success && response.sales.length) {
- for (var i = 0; i < response.sales.length; i++) {
- var sale = response.sales[i];
- if (_this.saleIdsByVariantId[id] === undefined) {
- _this.saleIdsByVariantId[id] = [];
- }
- _this.saleIdsByVariantId[id].push(sale.id);
+ $spinner.removeClass('hidden');
+ $spinner.data('loading', true);
- $('
\n' +
- ''+sale.name+'\n' +
- '').appendTo(element);
- }
+ element.empty();
+
+ Craft.postActionRequest('commerce/sales/get-sales-by-purchasable-id', data, function(response) {
+ $spinner.addClass('hidden');
+ $spinner.data('loading', false);
+ if (response && response.success && response.sales.length) {
+ for (var i = 0; i < response.sales.length; i++) {
+ var sale = response.sales[i];
+ if (_this.saleIdsByVariantId[id] === undefined) {
+ _this.saleIdsByVariantId[id] = [];
}
- });
- });
- }
+ _this.saleIdsByVariantId[id].push(sale.id);
+
+ $('
\n' +
+ ''+sale.name+'\n' +
+ '').appendTo(element);
+ }
+ }
+ });
},
+
populateDiscountList: function() {
if (this.$discountsList && this.$discountsList.length) {
var _this = this;