Reputation: 777
I'm using Odoo v16 and I want to use Odoo Official Frontend Docs for v16 as an example,
In the tutorial, we created the Counter OWL Component.
But in the example, they created a controller and initiated the whole OWL stack from the ground (owl_playground.assets_playground
asset).
I want to use the component inside an existing frontend page.
assume I want to show the counter on my home page of the website (not a custom page initiated with from a controller and custom template and main.js
)
How can I do that?
What should I do?
Alternatively, it will be good if I can create a website snippet for that counter or any other Odoo component.
Upvotes: 1
Views: 2055
Reputation: 1314
CASE 1 : For Backoffice views (model views), you can mount it using js_class in the xml (ex: js_class="project_form" in project_views.xml), and define the corresponding name as class in js. Example: addons/project/project_form_view.js:
/** @odoo-module */
import { registry } from "@web/core/registry";
import { formViewWithHtmlExpander } from '../form_with_html_expander/form_view_with_html_expander';
import { ProjectFormRenderer } from "./project_form_renderer";
export const projectFormView = {
...formViewWithHtmlExpander,
Renderer: ProjectFormRenderer,
};
registry.category("views").add("project_form", projectFormView);
CASE 2 : extending the Controller
Example in module mass_mailing > mailing_contact_view_list.js
/** @odoo-module **/
import { ListController } from "@web/views/list/list_controller";
import { listView } from '@web/views/list/list_view';
import { registry } from '@web/core/registry';
import { useService } from "@web/core/utils/hooks";
/**
* List view for the <mailing.contact> model.
*
* Add an import button to open the wizard <mailing.contact.import>. This wizard
* allows the user to import contacts line by line.
*/
export class MailingContactListController extends ListController {
async setup() {
super.setup();
this.actionService = useService("action");
}
onImport() {
const context = this.props.context;
const actionParams = { additionalContext: context };
if (!context.default_mailing_list_ids && context.active_model === 'mailing.list' && context.active_ids) {
actionParams.additionalContext.default_mailing_list_ids = context.active_ids;
}
this.actionService.doAction('mass_mailing.mailing_contact_import_action', actionParams);
}
};
registry.category('views').add('mailing_contact_list', {
...listView,
Controller: MailingContactListController,
buttonTemplate: 'MailingContactListView.buttons',
});
CASE 3: using a static/xml template
Example Emojis in mail (odoo/addons/mail/static/src/js /emojis_dropdown.js)
/** @odoo-module **/
import emojis from '@mail/js/emojis';
const { Component, useRef, onMounted } = owl;
export class EmojisDropdown extends Component {
setup() {
this.toggleRef = useRef('toggleRef');
this.emojis = emojis;
super.setup();
onMounted(() => {
new Dropdown(this.toggleRef.el, {
popperConfig: { placement: 'bottom-end', strategy: 'fixed' },
});
});
}
};
EmojisDropdown.template = 'mail.EmojisDropdown';
CASE 4: mounting owl-component in any place using a DOM-selector (document.getElementById(...)):
Example: odoo/addons/mass_mailing/static/src/snippets/s_rating /options.js
/**
* Allows to select a font awesome icon with media dialog.
*
* @see this.selectClass for parameters
*/
customIcon: async function (previewMode, widgetValue, params) {
const media = document.createElement('i');
media.className = params.customActiveIcon === 'true' ? this.faClassActiveCustomIcons : this.faClassInactiveCustomIcons;
const dialog = new ComponentWrapper(this, MediaDialogWrapper, {
noImages: true,
noDocuments: true,
noVideos: true,
media,
save: icon => {
const customClass = icon.className;
const $activeIcons = this.$target.find('.s_rating_active_icons > i');
const $inactiveIcons = this.$target.find('.s_rating_inactive_icons > i');
const $icons = params.customActiveIcon === 'true' ? $activeIcons : $inactiveIcons;
$icons.removeClass().addClass(customClass);
this.faClassActiveCustomIcons = $activeIcons.length > 0 ? $activeIcons.attr('class') : customClass;
this.faClassInactiveCustomIcons = $inactiveIcons.length > 0 ? $inactiveIcons.attr('class') : customClass;
this.$target[0].dataset.activeCustomIcon = this.faClassActiveCustomIcons;
this.$target[0].dataset.inactiveCustomIcon = this.faClassInactiveCustomIcons;
this.$target[0].dataset.icon = 'custom';
this.iconType = 'custom';
}
});
dialog.mount(document.body);
},
CASE 5 : Widget to display odoo field (odoo/addons/mrp/static/src/widgets/timer.js)
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { parseFloatTime } from "@web/views/fields/parsers";
import { useInputField } from "@web/views/fields/input_field_hook";
const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl;
export class MrpTimer extends Component {
setup() {
this.orm = useService('orm');
this.state = useState({
// duration is expected to be given in minutes
duration:
this.props.value !== undefined ? this.props.value : this.props.record.data.duration,
});
useInputField({
getValue: () => this.durationFormatted,
refName: "numpadDecimal",
parse: (v) => parseFloatTime(v),
});
onWillStart(async () => {
if(this.props.ongoing === undefined && !this.props.record.model.useSampleModel && this.props.record.data.state == "progress") {
const additionalDuration = await this.orm.call('mrp.workorder', 'get_working_duration', [this.props.record.resId]);
this.state.duration += additionalDuration;
}
if (this.ongoing) {
this._runTimer();
}
});
_runTimer() {
this.timer = setTimeout(() => {
if (this.ongoing) {
this.state.duration += 1 / 60;
this._runTimer();
}
}, 1000);
}
}
MrpTimer.supportedTypes = ["float"];
MrpTimer.template = "mrp.MrpTimer";
registry.category("fields").add("mrp_timer", MrpTimer);
registry.category("formatters").add("mrp_timer", formatMinutes);
Tutorial to create snippets:
https://www.oocademy.com/v15.0/tutorial/introduction-to-owl-115
https://codingdodo.com/realworld-app-with-owl-odoo-web-library-part-1/
https://www.odoo.com/documentation/16.0/fr/developer/howtos/website_themes/building_blocks.html
Upvotes: 4