summaryrefslogtreecommitdiff
path: root/addons/website_sale_comparison/static/src
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website_sale_comparison/static/src
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website_sale_comparison/static/src')
-rw-r--r--addons/website_sale_comparison/static/src/js/website_sale_comparison.js294
-rw-r--r--addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss65
-rw-r--r--addons/website_sale_comparison/static/src/xml/comparison.xml35
3 files changed, 394 insertions, 0 deletions
diff --git a/addons/website_sale_comparison/static/src/js/website_sale_comparison.js b/addons/website_sale_comparison/static/src/js/website_sale_comparison.js
new file mode 100644
index 00000000..8e8a4436
--- /dev/null
+++ b/addons/website_sale_comparison/static/src/js/website_sale_comparison.js
@@ -0,0 +1,294 @@
+odoo.define('website_sale_comparison.comparison', function (require) {
+'use strict';
+
+var concurrency = require('web.concurrency');
+var core = require('web.core');
+var publicWidget = require('web.public.widget');
+var utils = require('web.utils');
+var VariantMixin = require('sale.VariantMixin');
+var website_sale_utils = require('website_sale.utils');
+
+var qweb = core.qweb;
+var _t = core._t;
+
+// VariantMixin events are overridden on purpose here
+// to avoid registering them more than once since they are already registered
+// in website_sale.js
+var ProductComparison = publicWidget.Widget.extend(VariantMixin, {
+ xmlDependencies: ['/website_sale_comparison/static/src/xml/comparison.xml'],
+
+ template: 'product_comparison_template',
+ events: {
+ 'click .o_product_panel_header': '_onClickPanelHeader',
+ },
+
+ /**
+ * @constructor
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+
+ this.product_data = {};
+ this.comparelist_product_ids = JSON.parse(utils.get_cookie('comparelist_product_ids') || '[]');
+ this.product_compare_limit = 4;
+ this.guard = new concurrency.Mutex();
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ var self = this;
+
+ self._loadProducts(this.comparelist_product_ids).then(function () {
+ self._updateContent('hide');
+ });
+ self._updateComparelistView();
+
+ $('#comparelist .o_product_panel_header').popover({
+ trigger: 'manual',
+ animation: true,
+ html: true,
+ title: function () {
+ return _t("Compare Products");
+ },
+ container: '.o_product_feature_panel',
+ placement: 'top',
+ template: qweb.render('popover'),
+ content: function () {
+ return $('#comparelist .o_product_panel_content').html();
+ }
+ });
+ // We trigger a resize to launch the event that checks if this element hides
+ // a button when the page is loaded.
+ $(window).trigger('resize');
+
+ $(document.body).on('click.product_comparaison_widget', '.comparator-popover .o_comparelist_products .o_remove', function (ev) {
+ ev.preventDefault();
+ self._removeFromComparelist(ev);
+ });
+ $(document.body).on('click.product_comparaison_widget', '.o_comparelist_remove', function (ev) {
+ self._removeFromComparelist(ev);
+ self.guard.exec(function() {
+ var new_link = '/shop/compare/?products=' + self.comparelist_product_ids.toString();
+ window.location.href = _.isEmpty(self.comparelist_product_ids) ? '/shop' : new_link;
+ });
+ });
+
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ this._super.apply(this, arguments);
+ $(document.body).off('.product_comparaison_widget');
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @param {jQuery} $elem
+ */
+ handleCompareAddition: function ($elem) {
+ var self = this;
+ if (this.comparelist_product_ids.length < this.product_compare_limit) {
+ var productId = $elem.data('product-product-id');
+ if ($elem.hasClass('o_add_compare_dyn')) {
+ productId = $elem.parent().find('.product_id').val();
+ if (!productId) { // case List View Variants
+ productId = $elem.parent().find('input:checked').first().val();
+ }
+ }
+
+ this.selectOrCreateProduct(
+ $elem.closest('form'),
+ productId,
+ $elem.closest('form').find('.product_template_id').val(),
+ false
+ ).then(function (productId) {
+ productId = parseInt(productId, 10) || parseInt($elem.data('product-product-id'), 10);
+ if (!productId) {
+ return;
+ }
+ self._addNewProducts(productId).then(function () {
+ website_sale_utils.animateClone(
+ $('#comparelist .o_product_panel_header'),
+ $elem.closest('form'),
+ -50,
+ 10
+ );
+ });
+ });
+ } else {
+ this.$('.o_comparelist_limit_warning').show();
+ $('#comparelist .o_product_panel_header').popover('show');
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _loadProducts: function (product_ids) {
+ var self = this;
+ return this._rpc({
+ route: '/shop/get_product_data',
+ params: {
+ product_ids: product_ids,
+ cookies: JSON.parse(utils.get_cookie('comparelist_product_ids') || '[]'),
+ },
+ }).then(function (data) {
+ self.comparelist_product_ids = JSON.parse(data.cookies);
+ delete data.cookies;
+ _.each(data, function (product) {
+ self.product_data[product.product.id] = product;
+ });
+ if (product_ids.length > Object.keys(data).length) {
+ /* If some products have been archived
+ they are not displayed but the count & cookie
+ need to be updated.
+ */
+ self._updateCookie();
+ }
+ });
+ },
+ /**
+ * @private
+ */
+ _togglePanel: function () {
+ $('#comparelist .o_product_panel_header').popover('toggle');
+ },
+ /**
+ * @private
+ */
+ _addNewProducts: function (product_id) {
+ return this.guard.exec(this._addNewProductsImpl.bind(this, product_id));
+ },
+ _addNewProductsImpl: function (product_id) {
+ var self = this;
+ $('.o_product_feature_panel').addClass('d-md-block');
+ if (!_.contains(self.comparelist_product_ids, product_id)) {
+ self.comparelist_product_ids.push(product_id);
+ if (_.has(self.product_data, product_id)){
+ self._updateContent();
+ } else {
+ return self._loadProducts([product_id]).then(function () {
+ self._updateContent();
+ self._updateCookie();
+ });
+ }
+ }
+ self._updateCookie();
+ },
+ /**
+ * @private
+ */
+ _updateContent: function (force) {
+ var self = this;
+ this.$('.o_comparelist_products .o_product_row').remove();
+ _.each(this.comparelist_product_ids, function (res) {
+ var $template = self.product_data[res].render;
+ self.$('.o_comparelist_products').append($template);
+ });
+ if (force !== 'hide' && (this.comparelist_product_ids.length > 1 || force === 'show')) {
+ $('#comparelist .o_product_panel_header').popover('show');
+ }
+ else {
+ $('#comparelist .o_product_panel_header').popover('hide');
+ }
+ },
+ /**
+ * @private
+ */
+ _removeFromComparelist: function (e) {
+ this.guard.exec(this._removeFromComparelistImpl.bind(this, e));
+ },
+ _removeFromComparelistImpl: function (e) {
+ var target = $(e.target.closest('.o_comparelist_remove, .o_remove'));
+ this.comparelist_product_ids = _.without(this.comparelist_product_ids, target.data('product_product_id'));
+ target.parents('.o_product_row').remove();
+ this._updateCookie();
+ $('.o_comparelist_limit_warning').hide();
+ this._updateContent('show');
+ },
+ /**
+ * @private
+ */
+ _updateCookie: function () {
+ document.cookie = 'comparelist_product_ids=' + JSON.stringify(this.comparelist_product_ids) + '; path=/';
+ this._updateComparelistView();
+ },
+ /**
+ * @private
+ */
+ _updateComparelistView: function () {
+ this.$('.o_product_circle').text(this.comparelist_product_ids.length);
+ this.$('.o_comparelist_button').removeClass('d-md-block');
+ if (_.isEmpty(this.comparelist_product_ids)) {
+ $('.o_product_feature_panel').removeClass('d-md-block');
+ } else {
+ $('.o_product_feature_panel').addClass('d-md-block');
+ this.$('.o_comparelist_products').addClass('d-md-block');
+ if (this.comparelist_product_ids.length >=2) {
+ this.$('.o_comparelist_button').addClass('d-md-block');
+ this.$('.o_comparelist_button a').attr('href', '/shop/compare/?products='+this.comparelist_product_ids.toString());
+ }
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _onClickPanelHeader: function () {
+ this._togglePanel();
+ },
+});
+
+publicWidget.registry.ProductComparison = publicWidget.Widget.extend({
+ selector: '.oe_website_sale',
+ events: {
+ 'click .o_add_compare, .o_add_compare_dyn': '_onClickAddCompare',
+ 'click #o_comparelist_table tr': '_onClickComparelistTr',
+ },
+
+ /**
+ * @override
+ */
+ start: function () {
+ var def = this._super.apply(this, arguments);
+ this.productComparison = new ProductComparison(this);
+ return Promise.all([def, this.productComparison.appendTo(this.$el)]);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onClickAddCompare: function (ev) {
+ this.productComparison.handleCompareAddition($(ev.currentTarget));
+ },
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onClickComparelistTr: function (ev) {
+ var $target = $(ev.currentTarget);
+ $($target.data('target')).children().slideToggle(100);
+ $target.find('.fa-chevron-circle-down, .fa-chevron-circle-right').toggleClass('fa-chevron-circle-down fa-chevron-circle-right');
+ },
+});
+return ProductComparison;
+});
diff --git a/addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss b/addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss
new file mode 100644
index 00000000..204d9d1b
--- /dev/null
+++ b/addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss
@@ -0,0 +1,65 @@
+.o_product_feature_panel {
+ position: fixed;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index:10;
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ border-bottom: 0px;
+ padding: 10px 20px;
+ text-align: center;
+ border: 2px solid theme-color('primary');
+ border-bottom: 0px;
+ background-color: white;
+ opacity: 0.95;
+
+ .o_product_panel {
+ position: relative;
+ .o_product_panel_header {
+ margin: 0 10px 0 10px;
+ cursor: pointer;
+ .o_product_icon {
+ margin-right: 5px;
+ }
+ .o_product_text {
+ text-transform: uppercase;
+ vertical-align: middle;
+ font-size: 16px;
+ }
+ .o_product_circle {
+ vertical-align: 6px;
+ padding: 0 3px;
+ line-height: 14px;
+ }
+ }
+ .o_product_panel_content {
+ display: none !important;
+ }
+ }
+}
+
+.oe_website_sale {
+ .product_summary > *{
+ display: block;
+ margin: 15px 0 15px 0;
+ }
+ .table-comparator {
+ .o_product_comparison_collpase {
+ margin-right: 8px;
+ }
+ }
+
+ div.css_not_available .o_add_compare_dyn {
+ display: none;
+ }
+
+ .o_comparelist_remove {
+ @include o-position-absolute($top: 0, $right: 0.5rem);
+ }
+
+ .o_ws_compare_image {
+ vertical-align: middle;
+ }
+}
+
diff --git a/addons/website_sale_comparison/static/src/xml/comparison.xml b/addons/website_sale_comparison/static/src/xml/comparison.xml
new file mode 100644
index 00000000..47085955
--- /dev/null
+++ b/addons/website_sale_comparison/static/src/xml/comparison.xml
@@ -0,0 +1,35 @@
+<templates id="compare_products" xml:space="preserve">
+
+ <t t-name="product_comparison_template">
+ <div class="o_product_feature_panel d-none css_editable_mode_hidden o_bottom_fixed_element">
+ <span class="o_product_panel" id="comparelist">
+ <span class="o_product_panel_header">
+ <span class="o_product_icon"><i class="fa fa-exchange" role="img" aria-label="Product" title="Product"></i></span>
+ <span class="o_product_text">Compare</span>
+ <span class="o_product_circle o_animate_blink badge badge-primary">0</span>
+ </span>
+ <span class="o_product_panel_content">
+ <div class="o_comparelist_products">
+ <div class="o_comparelist_limit_warning" style="display:none">
+ <div class="o_shortlog alert alert-warning" role="alert">
+ <span><i class="fa fa-warning text-danger" role="img" aria-label="Warning" title="Warning"></i> You can compare max 4 products.</span>
+ </div>
+ </div>
+ </div>
+ <div class="o_comparelist_button" style='display:none'>
+ <a role="button" class="btn btn-primary btn-block" href="#"><i class="fa fa-exchange mr4"/>Compare</a>
+ </div>
+ </span>
+ </span>
+ </div>
+ </t>
+
+ <t t-name="popover">
+ <div style="width:600px;" class="popover comparator-popover" role="tooltip">
+ <div class="arrow"/>
+ <h3 class="popover-header"/>
+ <div class="popover-body"/>
+ </div>
+ </t>
+
+</templates>