[REF] website_sale, *: organize JS to use new system

* website_sale_comparison, website_sale_wishlist, website_sale_options
This commit is contained in:
qsm-odoo
2018-08-16 16:59:25 +02:00
parent 10f43955d8
commit 8a85cb9ea4
8 changed files with 1286 additions and 880 deletions
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,15 @@
odoo.define('website_sale.payment', function (require) {
"use strict";
'use strict';
$(document).ready(function () {
// If option is enable
if ($("#checkbox_cgv").length) {
$("#checkbox_cgv").change(function() {
$("button#o_payment_form_pay").prop("disabled", !this.checked);
});
$('#checkbox_cgv').trigger('change');
}
});
require('web.dom_ready');
var $checkbox = $("#checkbox_cgv");
if (!$checkbox.length) {
return;
}
$checkbox.on('change', function (ev) {
$('button#o_payment_form_pay').prop('disabled', !ev.target.checked);
});
$checkbox.change();
});
@@ -1,73 +1,118 @@
odoo.define('website_sale.tracking', function(require) {
odoo.define('website_sale.tracking', function (require) {
var ajax = require('web.ajax');
var sAnimations = require('website.content.snippets.animation');
$(document).ready(function () {
sAnimations.registry.websiteSaleTracking = sAnimations.Class.extend({
selector: '.oe_website_sale',
read_events: {
'click form[action="/shop/cart/update"] a.a-submit': '_onAddProductIntoCart',
'click a[href="/shop/checkout"]': '_onCheckoutStart',
'click div.oe_cart a[href^="/web?redirect"][href$="/shop/checkout"]': '_onCustomerSignin',
'click form[action="/shop/confirm_order"] a.a-submit': '_onOrder',
'click form[target="_self"] button[type=submit]': '_onOrderPayment',
},
// Watching a product
if ($("#product_detail.oe_website_sale").length) {
var prod_id = $("input[name='product_id']").attr('value');
vpv("/stats/ecom/product_view/" + prod_id);
}
// Add a product into the cart
$(".oe_website_sale form[action='/shop/cart/update'] a.a-submit").on('click', function(o) {
var prod_id = $("input[name='product_id']").attr('value');
vpv("/stats/ecom/product_add_to_cart/" + prod_id);
});
// Start checkout
$(".oe_website_sale a[href='/shop/checkout']").on('click', function(o) {
vpv("/stats/ecom/customer_checkout");
});
$(".oe_website_sale div.oe_cart a[href^='/web?redirect'][href$='/shop/checkout']").on('click', function(o) {
vpv("/stats/ecom/customer_signin");
});
$(".oe_website_sale form[action='/shop/confirm_order'] a.a-submit").on('click', function(o) {
if ($("#top_menu [href='/web/login']").length){
vpv("/stats/ecom/customer_signup");
/**
* @override
*/
start: function () {
var self = this;
var def = this._super.apply(this, arguments);
if (this.editableMode) {
return def;
}
vpv("/stats/ecom/order_checkout");
});
$(".oe_website_sale form[target='_self'] button[type=submit]").on('click', function(o) {
var method = $("#payment_method input[name=acquirer]:checked").nextAll("span:first").text();
vpv("/stats/ecom/order_payment/" + method);
});
// Watching a product
if (this.$el.is('#product_detail')) {
var productID = this.$('input[name="product_id"]').attr('value');
this._vpv('/stats/ecom/product_view/' + productID);
}
if ($(".oe_website_sale div.oe_website_sale_tx_status").length) {
track_ga('require', 'ecommerce');
// ...
if (this.$('div.oe_website_sale_tx_status').length) {
this._trackGA('require', 'ecommerce');
var order_id = $(".oe_website_sale div.oe_website_sale_tx_status").data("order-id");
vpv("/stats/ecom/order_confirmed/" + order_id);
var orderID = this.$('div.oe_website_sale_tx_status').data('order-id');
this._vpv('/stats/ecom/order_confirmed/' + orderID);
ajax.jsonRpc("/shop/tracking_last_order/").then(function(o) {
track_ga('ecommerce:clear');
this._rpc({
route: '/shop/tracking_last_order/',
}).then(function (o) {
self._trackGA('ecommerce:clear');
if (o.transaction && o.lines) {
track_ga('ecommerce:addTransaction', o.transaction);
_.forEach(o.lines, function(line) {
track_ga('ecommerce:addItem', line);
});
}
track_ga('ecommerce:send');
});
}
if (o.transaction && o.lines) {
self._trackGA('ecommerce:addTransaction', o.transaction);
_.forEach(o.lines, function (line) {
self._trackGA('ecommerce:addItem', line);
});
}
self._trackGA('ecommerce:send');
});
}
function vpv(page){ //virtual page view
track_ga('send', 'pageview', {
return def;
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
*/
_trackGA: function () {
websiteGA = window.ga || function () {};
websiteGA.apply(this, arguments);
},
/**
* @private
*/
_vpv: function (page) { //virtual page view
this._trackGA('send', 'pageview', {
'page': page,
'title': document.title,
});
}
},
function track_ga() {
website_ga = this.ga || function(){};
website_ga.apply(this, arguments);
}
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
*/
_onAddProductIntoCart: function () {
var productID = this.$('input[name="product_id"]').attr('value');
this._vpv('/stats/ecom/product_add_to_cart/' + productID);
},
/**
* @private
*/
_onCheckoutStart: function () {
this._vpv('/stats/ecom/customer_checkout');
},
/**
* @private
*/
_onCustomerSignin: function () {
this._vpv('/stats/ecom/customer_signin');
},
/**
* @private
*/
_onOrder: function () {
if ($('#top_menu [href="/web/login"]').length) {
this._vpv('/stats/ecom/customer_signup');
}
this._vpv('/stats/ecom/order_checkout');
},
/**
* @private
*/
_onOrderPayment: function () {
var method = $('#payment_method input[name=acquirer]:checked').nextAll('span:first').text();
this._vpv('/stats/ecom/order_payment/' + method);
},
});
});
@@ -1,39 +1,38 @@
odoo.define('website_sale.utils', function (require) {
"use strict";
'use strict';
var animate_clone = function(cart, $elem, offset_top, offset_left) {
cart.find('.o_animate_blink').addClass('o_red_highlight o_shadow_animation').delay(500).queue(function(){
$(this).removeClass("o_shadow_animation").dequeue();
}).delay(2000).queue(function(){
$(this).removeClass("o_red_highlight").dequeue();
});
var imgtodrag = $elem.find('img').eq(0);
if (imgtodrag.length) {
var imgclone = imgtodrag.clone()
function animateClone($cart, $elem, offsetTop, offsetLeft) {
$cart.find('.o_animate_blink').addClass('o_red_highlight o_shadow_animation').delay(500).queue(function(){
$(this).removeClass("o_shadow_animation").dequeue();
}).delay(2000).queue(function(){
$(this).removeClass("o_red_highlight").dequeue();
});
var $imgtodrag = $elem.find('img').eq(0);
if ($imgtodrag.length) {
var $imgclone = $imgtodrag.clone()
.offset({
top: imgtodrag.offset().top,
left: imgtodrag.offset().left
top: $imgtodrag.offset().top,
left: $imgtodrag.offset().left
})
.addClass('o_website_sale_animate')
.appendTo($('body'))
.appendTo(document.body)
.animate({
'top': cart.offset().top + offset_top,
'left': cart.offset().left + offset_left,
'width': 75,
'height': 75
top: $cart.offset().top + offsetTop,
left: $cart.offset().left + offsetLeft,
width: 75,
height: 75,
}, 1000, 'easeInOutExpo');
imgclone.animate({
'width': 0,
'height': 0
}, function () {
$(this).detach();
});
}
};
return {
animate_clone: animate_clone,
};
$imgclone.animate({
width: 0,
height: 0,
}, function () {
$(this).detach();
});
}
}
return {
animateClone: animateClone,
};
});
@@ -1,37 +1,54 @@
odoo.define('website_sale.validate', function(require) {
"use strict";
'use strict';
var ajax = require('web.ajax');
var sAnimations = require('website.content.snippets.animation');
$(document).ready(function () {
sAnimations.registry.websiteSaleValidate = sAnimations.Class.extend({
selector: 'div.oe_website_sale_tx_status[data-order-id]',
var _poll_nbr = 0;
function payment_transaction_poll_status() {
var order_node = $('div.oe_website_sale_tx_status');
if (! order_node || order_node.data('order-id') === undefined) {
return;
/**
* @override
*/
start: function () {
var def = this._super.apply(this, arguments);
if (this.editableMode) {
return def;
}
var order_id = parseInt(order_node.data('order-id'));
return ajax.jsonRpc('/shop/payment/get_status/' + order_id, 'call', {
this._poll_nbr = 0;
this._paymentTransationPollStatus();
return def;
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
*/
_paymentTransationPollStatus: function () {
var self = this;
this._rpc({
route: '/shop/payment/get_status/' + parseInt(this.$el.data('order-id')),
}).then(function (result) {
_poll_nbr += 1;
if(result.recall) {
if (_poll_nbr < 20){
setTimeout(function () { payment_transaction_poll_status(); }, Math.ceil(_poll_nbr / 3) * 1000);
}
else {
self._poll_nbr += 1;
if (result.recall) {
if (self._poll_nbr < 20) {
setTimeout(function () {
self._paymentTransationPollStatus();
}, Math.ceil(self._poll_nbr / 3) * 1000);
} else {
var $message = $(result.message);
$message.find('span:first').prepend($(
"<i title='We are waiting the confirmation of the bank or payment provider' class='fa fa-warning' style='margin-right:10px;'>"));
$message.find('span:first').prepend(
$("<i title='We are waiting the confirmation of the bank or payment provider' class='fa fa-warning' style='margin-right:10px;'>")
);
result.message = $message.html();
}
}
$('div.oe_website_sale_tx_status').html(result.message);
self.$el.html(result.message);
});
}
payment_transaction_poll_status();
},
});
});
@@ -1,43 +1,46 @@
odoo.define('website_sale_comparison.comparison', function (require) {
"use strict";
'use strict';
require('web.dom_ready');
var ajax = require('web.ajax');
var core = require('web.core');
var _t = core._t;
var utils = require('web.utils');
var Widget = require('web.Widget');
var website = require('web_editor.base');
var sAnimations = require('website.content.snippets.animation');
var website_sale_utils = require('website_sale.utils');
if(!$('.oe_website_sale').length) {
return $.Deferred().reject("DOM doesn't contain '.oe_website_sale'");
}
var qweb = core.qweb;
ajax.loadXML('/website_sale_comparison/static/src/xml/comparison.xml', qweb);
var _t = core._t;
var ProductComparison = Widget.extend({
template:"product_comparison_template",
xmlDependencies: ['/website_sale_comparison/static/src/xml/comparison.xml'],
template: 'product_comparison_template',
events: {
'click .o_product_panel_header': 'toggle_panel',
'click .o_product_panel_header': '_onClickPanelHeader',
},
product_data: {},
init: function(){
/**
* @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;
},
start:function(){
/**
* @override
*/
start: function () {
var self = this;
self.load_products(this.comparelist_product_ids).then(function() {
self.update_content(self.comparelist_product_ids, true);
self._loadProducts(this.comparelist_product_ids).then(function () {
self._updateContent(self.comparelist_product_ids, true);
if (self.comparelist_product_ids.length) {
$('.o_product_feature_panel').show();
self.update_comparelist_view();
self._updateComparelistView();
}
});
self.popover = $('#comparelist .o_product_panel_header').popover({
$('#comparelist .o_product_panel_header').popover({
trigger: 'manual',
animation: true,
html: true,
@@ -47,115 +50,148 @@ var ProductComparison = Widget.extend({
container: '.o_product_feature_panel',
placement: 'top',
template: '<div style="width:600px;" class="popover comparator-popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',
content: function() {
content: function () {
return $('#comparelist .o_product_panel_content').html();
}
});
$('.oe_website_sale .o_add_compare, .oe_website_sale .o_add_compare_dyn').click(function (e){
if (self.comparelist_product_ids.length < self.product_compare_limit) {
var prod = $(this).data('product-product-id');
if (e.currentTarget.classList.contains('o_add_compare_dyn')) {
prod = $(this).parent().find('.product_id').val();
if (!prod) { // case List View Variants
prod = $(this).parent().find('input:checked').first().val();
}
prod = parseInt(prod, 10);
}
if (!prod) {
return;
}
self.add_new_products(prod);
website_sale_utils.animate_clone($('#comparelist .o_product_panel_header'), $(this).closest('form'), -50, 10);
} else {
self.$('.o_comparelist_limit_warning').show();
self.show_panel(true);
}
});
$('body').on('click', '.comparator-popover .o_comparelist_products .o_remove', function (e){
self.rm_from_comparelist(e);
$(document.body).on('click.product_comparaison_widget', '.comparator-popover .o_comparelist_products .o_remove', function (ev) {
self._removeFromComparelist(ev);
});
$('body').on('click', '.o_comparelist_remove', function (e){
self.rm_from_comparelist(e);
$(document.body).on('click.product_comparaison_widget', '.o_comparelist_remove', function (ev) {
self._removeFromComparelist(ev);
var new_link = '/shop/compare/?products=' + self.comparelist_product_ids.toString();
window.location = _.isEmpty(self.comparelist_product_ids) ? '/shop' : new_link;
window.location.href = _.isEmpty(self.comparelist_product_ids) ? '/shop' : new_link;
});
$("#o_comparelist_table tr").click(function(){
$($(this).data('target')).children().slideToggle(100);
$(this).find('.fa-chevron-circle-down, .fa-chevron-circle-right').toggleClass('fa-chevron-circle-down fa-chevron-circle-right');
});
return this._super.apply(this, arguments);
},
load_products:function(product_ids) {
/**
* @override
*/
destroy: function () {
this._super.apply(this, arguments);
$(document.body).off('.product_comparaison_widget');
},
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @param {jQuery} $elem
*/
handleCompareAddition: function ($elem) {
if (this.comparelist_product_ids.length < this.product_compare_limit) {
var prod = $elem.data('product-product-id');
if ($elem.hasClass('o_add_compare_dyn')) {
prod = $elem.parent().find('.product_id').val();
if (!prod) { // case List View Variants
prod = $elem.parent().find('input:checked').first().val();
}
prod = parseInt(prod, 10);
}
if (!prod) {
return;
}
this._addNewProducts(prod);
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 ajax.jsonRpc('/shop/get_product_data', 'call', {
'product_ids': product_ids,
'cookies': JSON.parse(utils.get_cookie('comparelist_product_ids') || '[]'),
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) {
_.each(data, function (product) {
self.product_data[product.product.id] = product;
});
});
},
toggle_panel: function() {
/**
* @private
*/
_togglePanel: function () {
$('#comparelist .o_product_panel_header').popover('toggle');
},
show_panel: function(force) {
if ((!$('.comparator-popover').length) || force) {
$('#comparelist .o_product_panel_header').popover('show');
}
},
refresh_panel: function() {
if ($('.comparator-popover').length) {
$('#comparelist .o_product_panel_header').popover('show');
}
},
add_new_products:function(product_id){
/**
* @private
*/
_addNewProducts: function (product_id) {
var self = this;
$('.o_product_feature_panel').show();
if (!_.contains(self.comparelist_product_ids, product_id)) {
self.comparelist_product_ids.push(product_id);
if(_.has(self.product_data, product_id)){
self.update_content([product_id], false);
if (_.has(self.product_data, product_id)){
self._updateContent([product_id], false);
} else {
self.load_products([product_id]).then(function(){
self.update_content([product_id], false);
self._loadProducts([product_id]).then(function () {
self._updateContent([product_id], false);
});
}
}
self.update_cookie();
self._updateCookie();
},
update_content:function(product_ids, reset) {
/**
* @private
*/
_updateContent: function (product_ids, reset) {
var self = this;
if (reset) {
self.$('.o_comparelist_products .o_product_row').remove();
}
_.each(product_ids, function(res) {
_.each(product_ids, function (res) {
var $template = self.product_data[res].render;
self.$('.o_comparelist_products').append($template);
});
this.refresh_panel();
if ($('.comparator-popover').length) {
$('#comparelist .o_product_panel_header').popover('show');
}
},
rm_from_comparelist: function(e){
/**
* @private
*/
_removeFromComparelist: function (e) {
this.comparelist_product_ids = _.without(this.comparelist_product_ids, $(e.currentTarget).data('product_product_id'));
$(e.currentTarget).parents('.o_product_row').remove();
this.update_cookie();
this._updateCookie();
$('.o_comparelist_limit_warning').hide();
// force refresh to reposition popover
this.update_content(this.comparelist_product_ids, true);
this._updateContent(this.comparelist_product_ids, true);
},
update_cookie: function(){
/**
* @private
*/
_updateCookie: function () {
document.cookie = 'comparelist_product_ids=' + JSON.stringify(this.comparelist_product_ids) + '; path=/';
this.update_comparelist_view();
this._updateComparelistView();
},
update_comparelist_view: function() {
/**
* @private
*/
_updateComparelistView: function () {
this.$('.o_product_circle').text(this.comparelist_product_ids.length);
this.$('.o_comparelist_button').hide();
if (_.isEmpty(this.comparelist_product_ids)) {
$('.o_product_feature_panel').hide();
this.toggle_panel();
this._togglePanel();
} else {
this.$('.o_comparelist_products').show();
if (this.comparelist_product_ids.length >=2) {
@@ -163,11 +199,59 @@ var ProductComparison = Widget.extend({
this.$('.o_comparelist_button a').attr('href', '/shop/compare/?products='+this.comparelist_product_ids.toString());
}
}
}
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
*/
_onClickPanelHeader: function () {
this._togglePanel();
},
});
website.ready().done(function() {
new ProductComparison().appendTo('.oe_website_sale');
});
sAnimations.registry.ProductComparison = sAnimations.Class.extend({
selector: '.oe_website_sale',
read_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);
if (this.editableMode) {
return def;
}
this.productComparison = new ProductComparison(this);
return $.when(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');
},
});
});
@@ -1,101 +1,141 @@
odoo.define('website_sale_options.website_sale', function(require) {
"use strict";
odoo.define('website_sale_options.website_sale', function (require) {
'use strict';
var ajax = require('web.ajax');
require('web.dom_ready');
var weContext = require("web_editor.context");
var weContext = require('web_editor.context');
var sAnimations = require('website.content.snippets.animation');
require('website_sale.website_sale');
$('.oe_website_sale #add_to_cart, .oe_website_sale #products_grid .a-submit')
.off('click')
.removeClass('a-submit')
.click(_.debounce(function (event) {
var $form = $(this).closest('form');
sAnimations.registry.WebsiteSale.include({
/**
* @override
*/
_onClickSubmit: function (ev) {
if ($(ev.currentTarget).is('#add_to_cart, #products_grid .a-submit')) {
return;
}
this._super.apply(this, arguments);
},
});
sAnimations.registry.WebsiteSaleOptions = sAnimations.Class.extend({
selector: '.oe_website_sale',
read_events: {
'click #add_to_cart, #products_grid .a-submit': '_onClickAdd',
},
/**
* @constructor
*/
init: function () {
this._super.apply(this, arguments);
this._handleAdd = _.debounce(this._handleAdd.bind(this), 200, true);
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
*/
_handleAdd: function ($form) {
var quantity = parseFloat($form.find('input[name="add_qty"]').val() || 1);
var product_id = parseInt($form.find('input[type="hidden"][name="product_id"], input[type="radio"][name="product_id"]:checked').first().val(),10);
event.preventDefault();
ajax.jsonRpc("/shop/modal", 'call', {
'product_id': product_id,
'kwargs': {
'context': _.extend({'quantity': quantity}, weContext.get())
this._rpc({
route: '/shop/modal',
params: {
product_id: product_id,
kwargs: {
context: _.extend({'quantity': quantity}, weContext.get()),
},
}).then(function (modal) {
var $modal = $(modal);
},
}).then(function (modal) {
var $modal = $(modal);
$modal.find('img:first').attr("src", "/web/image/product.product/" + product_id + "/image_medium");
$modal.find('img:first').attr("src", "/web/image/product.product/" + product_id + "/image_medium");
// disable opacity on the <form> if currently active (in case the product is
// not published), as it interferes with bs modals
$form.addClass('css_options');
// disable opacity on the <form> if currently active (in case the product is
// not published), as it interferes with bs modals
$form.addClass('css_options');
$modal.appendTo($form)
.modal()
.on('hidden.bs.modal', function () {
$form.removeClass('css_options'); // possibly reactivate opacity (see above)
$(this).remove();
});
$modal.appendTo($form)
.modal()
.on('hidden.bs.modal', function () {
$form.removeClass('css_options'); // possibly reactivate opacity (see above)
$(this).remove();
});
$modal.on('click', '.a-submit', function (ev) {
var $a = $(this);
$form.ajaxSubmit({
url: '/shop/cart/update_option',
data: {lang: weContext.get().lang},
success: function (quantity) {
if (!$a.hasClass('js_goto_shop')) {
window.location.pathname = window.location.pathname.replace(/shop([\/?].*)?$/, "shop/cart");
}
var $q = $(".my_cart_quantity");
$q.parent().parent().removeClass("d-none", !quantity);
$q.html(quantity).hide().fadeIn(600);
$modal.on('click', '.a-submit', function (ev) {
var $a = $(this);
$form.ajaxSubmit({
url: '/shop/cart/update_option',
data: {lang: weContext.get().lang},
success: function (quantity) {
if (!$a.hasClass('js_goto_shop')) {
window.location.pathname = window.location.pathname.replace(/shop([\/?].*)?$/, "shop/cart");
}
});
$modal.modal('hide');
ev.preventDefault();
});
$modal.on('click', '.css_attribute_color input', function (event) {
$modal.find('.css_attribute_color').removeClass("active");
$modal.find('.css_attribute_color:has(input:checked)').addClass("active");
});
$modal.on("click", "a.js_add, a.js_remove", function (event) {
event.preventDefault();
var $parent = $(this).parents('.js_product:first');
$parent.find("a.js_add, span.js_remove").toggleClass('d-none');
$parent.find("input.js_optional_same_quantity").val( $(this).hasClass("js_add") ? 1 : 0 );
$parent.find(".js_remove");
});
$modal.on("change", "input.js_quantity", function () {
var qty = parseFloat($(this).val());
if (qty === 1) {
$(".js_remove .js_items").addClass('d-none');
$(".js_remove .js_item").removeClass('d-none');
} else {
$(".js_remove .js_items").removeClass('d-none').text($(".js_remove .js_items:first").text().replace(/[0-9.,]+/, qty));
$(".js_remove .js_item").addClass('d-none');
var $q = $(".my_cart_quantity");
$q.parent().parent().removeClass("d-none", !quantity);
$q.html(quantity).hide().fadeIn(600);
}
});
$modal.find('input[name="add_qty"]').val(quantity).change();
$('.js_add_cart_variants').each(function () {
$('input.js_variant_change, select.js_variant_change', this).first().trigger('change');
});
$modal.on("change", 'input[name="add_qty"]', function (event) {
var product_id = $($modal.find('span.oe_price[data-product-id]')).first().data('product-id');
var product_ids = [product_id];
var $products_dom = [];
$("ul.js_add_cart_variants[data-attribute_value_ids]").each(function(){
var $el = $(this);
$products_dom.push($el);
_.each($el.data("attribute_value_ids"), function (values) {
product_ids.push(values[0]);
});
});
});
$modal.modal('hide');
ev.preventDefault();
});
return false;
}, 200, true));
$modal.on('click', '.css_attribute_color input', function (ev) {
$modal.find('.css_attribute_color').removeClass("active");
$modal.find('.css_attribute_color:has(input:checked)').addClass("active");
});
$modal.on("click", "a.js_add, a.js_remove", function (ev) {
ev.preventDefault();
var $parent = $(this).parents('.js_product:first');
$parent.find("a.js_add, span.js_remove").toggleClass('d-none');
$parent.find("input.js_optional_same_quantity").val( $(this).hasClass("js_add") ? 1 : 0 );
$parent.find(".js_remove");
});
$modal.on("change", "input.js_quantity", function () {
var qty = parseFloat($(this).val());
if (qty === 1) {
$(".js_remove .js_items").addClass('d-none');
$(".js_remove .js_item").removeClass('d-none');
} else {
$(".js_remove .js_items").removeClass('d-none').text($(".js_remove .js_items:first").text().replace(/[0-9.,]+/, qty));
$(".js_remove .js_item").addClass('d-none');
}
});
$modal.find('input[name="add_qty"]').val(quantity).change();
$('.js_add_cart_variants').each(function () {
$('input.js_variant_change, select.js_variant_change', this).first().trigger('change');
});
$modal.on("change", 'input[name="add_qty"]', function (ev) {
var product_id = $($modal.find('span.oe_price[data-product-id]')).first().data('product-id');
var product_ids = [product_id];
var $products_dom = [];
$("ul.js_add_cart_variants[data-attribute_value_ids]").each(function () {
var $el = $(this);
$products_dom.push($el);
_.each($el.data("attribute_value_ids"), function (values) {
product_ids.push(values[0]);
});
});
});
});
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
_onClickAdd: function (ev) {
ev.preventDefault();
var $form = $(ev.currentTarget).closest('form');
this._handleAdd($form);
},
});
});
@@ -1,163 +1,135 @@
odoo.define('website_sale_wishlist.wishlist', function (require) {
"use strict";
require('web.dom_ready');
var ajax = require('web.ajax');
var Widget = require('web.Widget');
var base = require('web_editor.base');
var website_sale_utils = require('website_sale.utils');
var sAnimations = require('website.content.snippets.animation');
var wSaleUtils = require('website_sale.utils');
if(!$('.oe_website_sale').length) {
return $.Deferred().reject("DOM doesn't contain '.oe_website_sale'");
}
var ProductWishlist = Widget.extend({
events: {
'click #my_wish': 'display_wishlist',
sAnimations.registry.ProductWishlist = sAnimations.Class.extend({
selector: '.oe_website_sale',
read_events: {
'click #my_wish': '_onClickMyWish',
'click .o_add_wishlist, .o_add_wishlist_dyn': '_onClickAddWish',
'change input.js_variant_change, select.js_variant_change, ul[data-attribute_value_ids]': '_onChangeVariant',
'change input.js_product_change': '_onChangeProduct',
'click .wishlist-section .o_wish_rm': '_onClickWishRemove',
'click .wishlist-section .o_wish_add': '_onClickWishAdd',
},
init: function(){
var self = this;
this.wishlist_product_ids = [];
var wish_loading = $.get('/shop/wishlist', {'count': 1}).then(function(res) {
self.wishlist_product_ids = JSON.parse(res);
self.update_wishlist_view();
});
$('.oe_website_sale .o_add_wishlist, .oe_website_sale .o_add_wishlist_dyn').click(function (e){
self.add_new_products($(this), e);
});
if ($('.wishlist-section').length) {
$('.wishlist-section .o_wish_rm').on('click', function (e){ self.wishlist_rm(e, false); });
$('.wishlist-section .o_wish_add').on('click', function (e){
$('.wishlist-section .o_wish_add').addClass('disabled');
self.wishlist_add_or_mv(e).then(function(o) {
$('.wishlist-section .o_wish_add').removeClass('disabled');
});
});
start: function () {
var self = this;
var def = this._super.apply(this, arguments);
if (this.editableMode) {
return def;
}
$('.oe_website_sale').on('change', 'input.js_variant_change, select.js_variant_change, ul[data-attribute_value_ids]', function(ev) {
var $ul = $(ev.target).closest('.js_add_cart_variants');
var $parent = $ul.closest('.js_product');
var $product_id = $parent.find('.product_id').first();
var $el = $parent.find("[data-action='o_wishlist']");
if (!_.contains(self.wishlist_product_ids, parseInt($product_id.val(), 10))) {
$el.prop("disabled", false).removeClass('disabled').removeAttr('disabled');
}
else {
$el.prop("disabled", true).addClass('disabled').attr('disabled', 'disabled');
}
$el.data('product-product-id', parseInt($product_id.val(), 10));
this.wishlistProductIDs = [];
});
// manage "List View of variants"
$('.oe_website_sale').on('change', 'input.js_product_change', function(ev) {
var product_id = ev.currentTarget.value;
var $el = $(ev.target).closest('.js_add_cart_variants').find("[data-action='o_wishlist']");
if (!_.contains(self.wishlist_product_ids, parseInt(product_id, 10))) {
$el.prop("disabled", false).removeClass('disabled').removeAttr('disabled');
}
else {
$el.prop("disabled", true).addClass('disabled').attr('disabled', 'disabled');
}
$el.data('product-product-id', product_id);
});
wish_loading.then(function() {
var wishDef = $.get('/shop/wishlist', {
count: 1,
}).then(function (res) {
self.wishlistProductIDs = JSON.parse(res);
self._updateWishlistView();
if ($('input.js_product_change').length) { // manage "List View of variants"
$('input.js_product_change:checked').first().trigger('change');
}
else {
} else {
$('input.js_variant_change').trigger('change');
}
});
return $.when(def, wishDef);
},
add_new_products: function($el, e){
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
*/
_addNewProducts: function ($el) {
var self = this;
var product_id = parseInt($el.data('product-product-id'), 10);
if (!product_id && e.currentTarget.classList.contains('o_add_wishlist_dyn')) {
product_id = parseInt($el.parent().find('.product_id').val());
var productID = parseInt($el.data('product-product-id'), 10);
if (!productID && $el.hasClass('o_add_wishlist_dyn')) {
productID = parseInt($el.parent().find('.product_id').val());
}
if (product_id && !_.contains(self.wishlist_product_ids, product_id)) {
return ajax.jsonRpc('/shop/wishlist/add', 'call', {
'product_id': product_id
if (productID && !_.contains(self.wishlistProductIDs, productID)) {
return this._rpc({
route: '/shop/wishlist/add',
params: {
product_id: productID,
},
}).then(function () {
self.wishlist_product_ids.push(product_id);
self.update_wishlist_view();
website_sale_utils.animate_clone($('#my_wish'), $el.closest('form'), 25, 40);
self.wishlistProductIDs.push(productID);
self._updateWishlistView();
wSaleUtils.animateClone($('#my_wish'), $el.closest('form'), 25, 40);
$el.prop("disabled", true).addClass('disabled');
});
}
},
display_wishlist: function() {
if (this.wishlist_product_ids.length === 0) {
this.update_wishlist_view();
this.redirect_no_wish();
}
else {
window.location = '/shop/wishlist';
}
},
update_wishlist_view: function() {
if (this.wishlist_product_ids.length > 0) {
/**
* @private
*/
_updateWishlistView: function () {
if (this.wishlistProductIDs.length > 0) {
$('#my_wish').show();
$('.my_wish_quantity').text(this.wishlist_product_ids.length);
}
else {
$('.my_wish_quantity').text(this.wishlistProductIDs.length);
} else {
$('#my_wish').hide();
}
},
wishlist_rm: function(e, deferred_redirect){
/**
* @private
*/
_removeWish: function (e, deferred_redirect){
var tr = $(e.currentTarget).parents('tr');
var wish = tr.data('wish-id');
var product = tr.data('product-id');
var self = this;
ajax.jsonRpc('/shop/wishlist/remove/' + wish).done(function () {
this._rpc({
route: '/shop/wishlist/remove/' + wish,
}).done(function () {
$(tr).hide();
});
this.wishlist_product_ids = _.without(this.wishlist_product_ids, product);
if (this.wishlist_product_ids.length === 0) {
this.wishlistProductIDs = _.without(this.wishlistProductIDs, product);
if (this.wishlistProductIDs.length === 0) {
deferred_redirect = deferred_redirect ? deferred_redirect : $.Deferred();
deferred_redirect.then(function() {
self.redirect_no_wish();
deferred_redirect.then(function () {
self._redirectNoWish();
});
}
this.update_wishlist_view();
this._updateWishlistView();
},
wishlist_add_or_mv: function(e){
return $('#b2b_wish').is(':checked') ? this.wishlist_add(e) : this.wishlist_mv(e);
},
wishlist_add: function(e){
/**
* @private
*/
_addOrMoveWish: function (e) {
var tr = $(e.currentTarget).parents('tr');
var product = tr.data('product-id');
// can be hidden if empty
$('#my_cart').removeClass('d-none');
website_sale_utils.animate_clone($('#my_cart'), tr, 25, 40);
return this.add_to_cart(product, tr.find('qty').val() || 1);
},
wishlist_mv: function(e){
var tr = $(e.currentTarget).parents('tr');
var product = tr.data('product-id');
wSaleUtils.animateClone($('#my_cart'), tr, 25, 40);
$('#my_cart').removeClass('d-none');
website_sale_utils.animate_clone($('#my_cart'), tr, 25, 40);
var adding_deffered = this.add_to_cart(product, tr.find('qty').val() || 1);
this.wishlist_rm(e, adding_deffered);
return adding_deffered;
if ($('#b2b_wish').is(':checked')) {
return this._addToCart(product, tr.find('qty').val() || 1);
} else {
var adding_deffered = this._addToCart(product, tr.find('qty').val() || 1);
this._removeWish(e, adding_deffered);
return adding_deffered;
}
},
add_to_cart: function(product_id, qty_id) {
var add_to_cart = ajax.jsonRpc("/shop/cart/update_json", 'call', {
'product_id': parseInt(product_id, 10),
'add_qty': parseInt(qty_id, 10),
'display': false,
});
add_to_cart.then(function(resp) {
/**
* @private
*/
_addToCart: function (productID, qty_id) {
return this._rpc({
route: "/shop/cart/update_json",
params: {
product_id: parseInt(productID, 10),
add_qty: parseInt(qty_id, 10),
display: false,
},
}).then(function (resp) {
if (resp.warning) {
if (! $('#data_warning').length) {
$('.wishlist-section').prepend('<div class="mt16 alert alert-danger alert-dismissable" role="alert" id="data_warning"></div>');
@@ -167,13 +139,85 @@ var ProductWishlist = Widget.extend({
}
$('.my_cart_quantity').html(resp.cart_quantity || '<i class="fa fa-warning" /> ');
});
return add_to_cart;
},
redirect_no_wish: function() {
window.location = '/shop/cart';
}
});
/**
* @private
*/
_redirectNoWish: function () {
window.location.href = '/shop/cart';
},
new ProductWishlist();
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
*/
_onClickMyWish: function () {
if (this.wishlistProductIDs.length === 0) {
this._updateWishlistView();
this._redirectNoWish();
return;
}
window.location = '/shop/wishlist';
},
/**
* @private
* @param {Event} ev
*/
_onClickAddWish: function (ev) {
this._addNewProducts($(ev.currentTarget));
},
/**
* @private
* @param {Event} ev
*/
_onChangeVariant: function (ev) {
var $ul = $(ev.target).closest('.js_add_cart_variants');
var $parent = $ul.closest('.js_product');
var $productID = $parent.find('.product_id').first();
var $el = $parent.find("[data-action='o_wishlist']");
if (!_.contains(this.wishlistProductIDs, parseInt($productID.val(), 10))) {
$el.prop("disabled", false).removeClass('disabled').removeAttr('disabled');
} else {
$el.prop("disabled", true).addClass('disabled').attr('disabled', 'disabled');
}
$el.data('product-product-id', parseInt($productID.val(), 10));
},
/**
* @private
* @param {Event} ev
*/
_onChangeProduct: function (ev) {
var productID = ev.currentTarget.value;
var $el = $(ev.target).closest('.js_add_cart_variants').find("[data-action='o_wishlist']");
if (!_.contains(this.wishlistProductIDs, parseInt(productID, 10))) {
$el.prop("disabled", false).removeClass('disabled').removeAttr('disabled');
} else {
$el.prop("disabled", true).addClass('disabled').attr('disabled', 'disabled');
}
$el.data('product-product-id', productID);
},
/**
* @private
* @param {Event} ev
*/
_onClickWishRemove: function (ev) {
this._removeWish(ev, false);
},
/**
* @private
* @param {Event} ev
*/
_onClickWishAdd: function (ev) {
var self = this;
this.$('.wishlist-section .o_wish_add').addClass('disabled');
this._addOrMoveWish(ev).then(function () {
self.$('.wishlist-section .o_wish_add').removeClass('disabled');
});
},
});
});