[REF] website_sale: move the product input files
This commit changes the file structure of the product input snippet. Related to #42067 Part of #45176 task-2189645
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
'views/crm_team_views.xml',
|
||||
'views/templates.xml',
|
||||
'views/snippets.xml',
|
||||
'views/snippets/s_products_searchbar.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/digest_views.xml',
|
||||
'views/website_sale_visitor_views.xml',
|
||||
|
||||
@@ -52,14 +52,9 @@ WebsiteNewMenu.include({
|
||||
odoo.define('website_sale.editor', function (require) {
|
||||
'use strict';
|
||||
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var options = require('web_editor.snippets.options');
|
||||
var publicWidget = require('web.public.widget');
|
||||
|
||||
var _t = core._t;
|
||||
var qweb = core.qweb;
|
||||
|
||||
publicWidget.registry.websiteSaleCurrency = publicWidget.Widget.extend({
|
||||
selector: '.oe_website_sale',
|
||||
disabledInEditableMode: false,
|
||||
@@ -88,7 +83,6 @@ function reload() {
|
||||
}
|
||||
|
||||
options.registry.WebsiteSaleGridLayout = options.Class.extend({
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale.editor.xml'],
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -322,64 +316,4 @@ options.registry.WebsiteSaleProductsItem = options.Class.extend({
|
||||
}).then(reload);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles the edition of products search bar snippet.
|
||||
*/
|
||||
options.registry.ProductsSearchBar = options.Class.extend({
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale.editor.xml'],
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$searchProductsInput = this.$('.search-query');
|
||||
this.$searchOrderField = this.$('.o_wsale_search_order_by');
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Options
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @see this.selectClass for parameters
|
||||
*/
|
||||
openSearchbarSettings: function (previewMode, widgetValue, params) {
|
||||
var self = this;
|
||||
new Dialog(this, {
|
||||
title: _t("Products Search Bar"),
|
||||
$content: $(qweb.render('website_sale.dialog.productsSearchBar', {
|
||||
currentOrderBy: this.$searchOrderField.val(),
|
||||
currentLimit: parseInt(this.$searchProductsInput.attr('data-limit')),
|
||||
currentDisplayDescription: this.$searchProductsInput.attr('data-display-description') === 'true',
|
||||
currentDisplayPrice: this.$searchProductsInput.attr('data-display-price') === 'true',
|
||||
currentDisplayImage: this.$searchProductsInput.attr('data-display-image') === 'true',
|
||||
})),
|
||||
buttons: [
|
||||
{
|
||||
text: _t("Save"),
|
||||
classes: 'btn-primary',
|
||||
click: function () {
|
||||
self.$searchOrderField.attr({
|
||||
'value': this.$('#order_by').val(),
|
||||
});
|
||||
self.$searchProductsInput.attr({
|
||||
'data-limit': this.$('#use_autocomplete').is(':checked') ? this.$('#limit').val() : 0,
|
||||
'data-display-description': this.$('#display_description').is(':checked'),
|
||||
'data-display-price': this.$('#display_price').is(':checked'),
|
||||
'data-display-image': this.$('#display_image').is(':checked'),
|
||||
});
|
||||
self.$target.trigger('content_changed');
|
||||
this.close();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: _t("Discard"),
|
||||
close: true,
|
||||
},
|
||||
],
|
||||
}).open();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -147,13 +147,11 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
|
||||
var core = require('web.core');
|
||||
var config = require('web.config');
|
||||
var concurrency = require('web.concurrency');
|
||||
var publicWidget = require('web.public.widget');
|
||||
var VariantMixin = require('sale.VariantMixin');
|
||||
var wSaleUtils = require('website_sale.utils');
|
||||
require("web.zoomodoo");
|
||||
|
||||
var qweb = core.qweb;
|
||||
|
||||
publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, {
|
||||
selector: '.oe_website_sale',
|
||||
@@ -807,132 +805,4 @@ publicWidget.registry.websiteSaleCart = publicWidget.Widget.extend({
|
||||
$(ev.currentTarget).closest('tr').find('.js_quantity').val(0).trigger('change');
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @todo maybe the custom autocomplete logic could be extract to be reusable
|
||||
*/
|
||||
publicWidget.registry.productsSearchBar = publicWidget.Widget.extend({
|
||||
selector: '.o_wsale_products_searchbar_form',
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale_utils.xml'],
|
||||
events: {
|
||||
'input .search-query': '_onInput',
|
||||
'focusout': '_onFocusOut',
|
||||
'keydown .search-query': '_onKeydown',
|
||||
},
|
||||
autocompleteMinWidth: 300,
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this._dp = new concurrency.DropPrevious();
|
||||
|
||||
this._onInput = _.debounce(this._onInput, 400);
|
||||
this._onFocusOut = _.debounce(this._onFocusOut, 100);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$input = this.$('.search-query');
|
||||
|
||||
this.order = this.$('.o_wsale_search_order_by').val();
|
||||
this.limit = parseInt(this.$input.data('limit'));
|
||||
this.displayDescription = !!this.$input.data('displayDescription');
|
||||
this.displayPrice = !!this.$input.data('displayPrice');
|
||||
this.displayImage = !!this.$input.data('displayImage');
|
||||
|
||||
if (this.limit) {
|
||||
this.$input.attr('autocomplete', 'off');
|
||||
}
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_fetch: function () {
|
||||
return this._rpc({
|
||||
route: '/shop/products/autocomplete',
|
||||
params: {
|
||||
'term': this.$input.val(),
|
||||
'options': {
|
||||
'order': this.order,
|
||||
'limit': this.limit,
|
||||
'display_description': this.displayDescription,
|
||||
'display_price': this.displayPrice,
|
||||
'max_nb_chars': Math.round(Math.max(this.autocompleteMinWidth, parseInt(this.$el.width())) * 0.22),
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_render: function (res) {
|
||||
var $prevMenu = this.$menu;
|
||||
this.$el.toggleClass('dropdown show', !!res);
|
||||
if (res) {
|
||||
var products = res['products'];
|
||||
this.$menu = $(qweb.render('website_sale.productsSearchBar.autocomplete', {
|
||||
products: products,
|
||||
hasMoreProducts: products.length < res['products_count'],
|
||||
currency: res['currency'],
|
||||
widget: this,
|
||||
}));
|
||||
this.$menu.css('min-width', this.autocompleteMinWidth);
|
||||
this.$el.append(this.$menu);
|
||||
}
|
||||
if ($prevMenu) {
|
||||
$prevMenu.remove();
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onInput: function () {
|
||||
if (!this.limit) {
|
||||
return;
|
||||
}
|
||||
this._dp.add(this._fetch()).then(this._render.bind(this));
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onFocusOut: function () {
|
||||
if (!this.$el.has(document.activeElement).length) {
|
||||
this._render();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onKeydown: function (ev) {
|
||||
switch (ev.which) {
|
||||
case $.ui.keyCode.ESCAPE:
|
||||
this._render();
|
||||
break;
|
||||
case $.ui.keyCode.UP:
|
||||
ev.preventDefault();
|
||||
this.$menu.children().last().focus();
|
||||
break;
|
||||
case $.ui.keyCode.DOWN:
|
||||
ev.preventDefault();
|
||||
this.$menu.children().first().focus();
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
odoo.define('website_sale.s_products_searchbar', function (require) {
|
||||
'use strict';
|
||||
|
||||
const concurrency = require('web.concurrency');
|
||||
const publicWidget = require('web.public.widget');
|
||||
|
||||
const { qweb } = require('web.core');
|
||||
|
||||
/**
|
||||
* @todo maybe the custom autocomplete logic could be extract to be reusable
|
||||
*/
|
||||
publicWidget.registry.productsSearchBar = publicWidget.Widget.extend({
|
||||
selector: '.o_wsale_products_searchbar_form',
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale_utils.xml'],
|
||||
events: {
|
||||
'input .search-query': '_onInput',
|
||||
'focusout': '_onFocusOut',
|
||||
'keydown .search-query': '_onKeydown',
|
||||
},
|
||||
autocompleteMinWidth: 300,
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this._dp = new concurrency.DropPrevious();
|
||||
|
||||
this._onInput = _.debounce(this._onInput, 400);
|
||||
this._onFocusOut = _.debounce(this._onFocusOut, 100);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$input = this.$('.search-query');
|
||||
|
||||
this.order = this.$('.o_wsale_search_order_by').val();
|
||||
this.limit = parseInt(this.$input.data('limit'));
|
||||
this.displayDescription = !!this.$input.data('displayDescription');
|
||||
this.displayPrice = !!this.$input.data('displayPrice');
|
||||
this.displayImage = !!this.$input.data('displayImage');
|
||||
|
||||
if (this.limit) {
|
||||
this.$input.attr('autocomplete', 'off');
|
||||
}
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_fetch: function () {
|
||||
return this._rpc({
|
||||
route: '/shop/products/autocomplete',
|
||||
params: {
|
||||
'term': this.$input.val(),
|
||||
'options': {
|
||||
'order': this.order,
|
||||
'limit': this.limit,
|
||||
'display_description': this.displayDescription,
|
||||
'display_price': this.displayPrice,
|
||||
'max_nb_chars': Math.round(Math.max(this.autocompleteMinWidth, parseInt(this.$el.width())) * 0.22),
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_render: function (res) {
|
||||
var $prevMenu = this.$menu;
|
||||
this.$el.toggleClass('dropdown show', !!res);
|
||||
if (res) {
|
||||
var products = res['products'];
|
||||
this.$menu = $(qweb.render('website_sale.productsSearchBar.autocomplete', {
|
||||
products: products,
|
||||
hasMoreProducts: products.length < res['products_count'],
|
||||
currency: res['currency'],
|
||||
widget: this,
|
||||
}));
|
||||
this.$menu.css('min-width', this.autocompleteMinWidth);
|
||||
this.$el.append(this.$menu);
|
||||
}
|
||||
if ($prevMenu) {
|
||||
$prevMenu.remove();
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onInput: function () {
|
||||
if (!this.limit) {
|
||||
return;
|
||||
}
|
||||
this._dp.add(this._fetch()).then(this._render.bind(this));
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onFocusOut: function () {
|
||||
if (!this.$el.has(document.activeElement).length) {
|
||||
this._render();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onKeydown: function (ev) {
|
||||
switch (ev.which) {
|
||||
case $.ui.keyCode.ESCAPE:
|
||||
this._render();
|
||||
break;
|
||||
case $.ui.keyCode.UP:
|
||||
ev.preventDefault();
|
||||
this.$menu.children().last().focus();
|
||||
break;
|
||||
case $.ui.keyCode.DOWN:
|
||||
ev.preventDefault();
|
||||
this.$menu.children().first().focus();
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
odoo.define('website_sale.s_products_searchbar_options', function (require) {
|
||||
'use strict';
|
||||
|
||||
const Dialog = require('web.Dialog');
|
||||
const options = require('web_editor.snippets.options');
|
||||
|
||||
const { qweb, _t } = require('web.core');
|
||||
|
||||
options.registry.ProductsSearchBar = options.Class.extend({
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale.editor.xml'],
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$searchProductsInput = this.$('.search-query');
|
||||
this.$searchOrderField = this.$('.o_wsale_search_order_by');
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Options
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @see this.selectClass for parameters
|
||||
*/
|
||||
openSearchbarSettings: function (previewMode, widgetValue, params) {
|
||||
var self = this;
|
||||
new Dialog(this, {
|
||||
title: _t("Products Search Bar"),
|
||||
$content: $(qweb.render('website_sale.dialog.productsSearchBar', {
|
||||
currentOrderBy: this.$searchOrderField.val(),
|
||||
currentLimit: parseInt(this.$searchProductsInput.attr('data-limit')),
|
||||
currentDisplayDescription: this.$searchProductsInput.attr('data-display-description') === 'true',
|
||||
currentDisplayPrice: this.$searchProductsInput.attr('data-display-price') === 'true',
|
||||
currentDisplayImage: this.$searchProductsInput.attr('data-display-image') === 'true',
|
||||
})),
|
||||
buttons: [
|
||||
{
|
||||
text: _t("Save"),
|
||||
classes: 'btn-primary',
|
||||
click: function () {
|
||||
self.$searchOrderField.attr({
|
||||
'value': this.$('#order_by').val(),
|
||||
});
|
||||
self.$searchProductsInput.attr({
|
||||
'data-limit': this.$('#use_autocomplete').is(':checked') ? this.$('#limit').val() : 0,
|
||||
'data-display-description': this.$('#display_description').is(':checked'),
|
||||
'data-display-price': this.$('#display_price').is(':checked'),
|
||||
'data-display-image': this.$('#display_image').is(':checked'),
|
||||
});
|
||||
self.$target.trigger('content_changed');
|
||||
this.close();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: _t("Discard"),
|
||||
close: true,
|
||||
},
|
||||
],
|
||||
}).open();
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -1,29 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="s_products_searchbar_input" name="Products Search Input">
|
||||
<t t-call="website_sale.website_sale_products_search_box">
|
||||
<t t-set="_classes" t-value="'s_wsale_products_searchbar_input mb-3'"/>
|
||||
</t>
|
||||
</template>
|
||||
<template id="s_products_searchbar" name="Products Search">
|
||||
<section class="s_wsale_products_searchbar bg-200 pt24 pb24">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 offset-lg-2">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h2>Search for a product</h2>
|
||||
<p>We have amazing products in our shop, check them now !</p>
|
||||
<t t-call="website_sale.s_products_searchbar_input"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<template id="s_products_recently_viewed" name="Products Recently Viewed">
|
||||
<section class="s_wsale_products_recently_viewed d-none pt24 pb24" style="min-height: 400px;">
|
||||
<div class="container">
|
||||
@@ -96,13 +73,7 @@
|
||||
<we-button data-change-sequence="bottom">Push to bottom</we-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-js="ProductsSearchBar"
|
||||
data-selector=".s_wsale_products_searchbar_input">
|
||||
<we-button data-no-preview="true" data-open-searchbar-settings="">Products Search Bar</we-button>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//*[@t-set='so_content_addition_selector']" position="inside">, .s_wsale_products_searchbar_input</xpath>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="s_products_searchbar_input" name="Products Search Input">
|
||||
<t t-call="website_sale.website_sale_products_search_box">
|
||||
<t t-set="_classes" t-value="'s_wsale_products_searchbar_input mb-3'"/>
|
||||
</t>
|
||||
</template>
|
||||
<template id="s_products_searchbar" name="Products Search">
|
||||
<section class="s_wsale_products_searchbar bg-200 pt24 pb24">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 offset-lg-2">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h2>Search for a product</h2>
|
||||
<p>We have amazing products in our shop, check them now !</p>
|
||||
<t t-call="website_sale.s_products_searchbar_input"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<template id="searchbar_input_snippet_options" inherit_id="website_sale.snippet_options" name="search bar snippet options">
|
||||
<xpath expr="." position="inside">
|
||||
<div data-js="ProductsSearchBar"
|
||||
data-selector=".s_wsale_products_searchbar_input">
|
||||
<we-button data-no-preview="true" data-open-searchbar-settings="">Products Search Bar</we-button>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//*[@t-set='so_content_addition_selector']" position="inside">, .s_wsale_products_searchbar_input</xpath>
|
||||
</template>
|
||||
|
||||
<template id="assets_snippet_s_products_searchbar_js_000" inherit_id="website_sale.assets_frontend">
|
||||
<xpath expr="//script[last()]" position="after">
|
||||
<script type="text/javascript" src="/website_sale/static/src/snippets/s_products_searchbar/000.js"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
@@ -47,6 +47,7 @@
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.editor.js"></script>
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_form_editor.js"></script>
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/tours/website_sale_shop_frontend.js"></script>
|
||||
<script type="text/javascript" src="/website_sale/static/src/snippets/s_products_searchbar/options.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user