Utilizing JS Class in Form Views within Odoo 17

In Odoo 17, a notable feature is the ability to craft bespoke views, enabling users to interact with data uniquely. This article explores the development of a personalized view using a JavaScript class for form view rendering. By following this guide, users can gain valuable insights into customizing their Odoo 17 experience, leveraging the platform's capabilities for tailored solutions and improved usability.

This blog post will delve into customizing form views in Odoo by leveraging the JavaScript class feature. Starting with adding a custom button to an XML view, we'll explore how clicking this button triggers a JavaScript function. Step by step, we'll dissect the JavaScript code to understand its workings. By the conclusion of this post, you'll have a deeper grasp of utilizing JavaScript to augment Odoo's functionality.

The JavaScript class function functions by associating a class with a particular view. When we integrate this class into the form view, it embeds the customized view into the form. To accomplish this, we need to generate the custom view as a template, enroll it as a component, and subsequently connect it to the form controller. Consequently, the form controller will activate the view upon detecting the designated class during the view loading process.

In the image, you'll observe the "Info" button that we incorporated into the form views utilizing the JavaScript class named "model_info".

In this case, we've extended the Sale order form and introduced the attribute "js_class", setting its value to "model_info".

<?xml version="1.0"?>
<odoo>
   <record id="view_sale_order_form_inherit" model="ir.ui.view">
       <field name="name">sale.order</field>
       <field name="model">sale.order</field>
       <field name="inherit_id" ref="sale.view_order_form"/>
       <field name="arch" type="xml">
           <xpath expr="//form" position="attributes">
               <attribute name="js_class">model_info</attribute>
           </xpath>
       </field>
   </record>
</odoo>

Initially, the Form controller checks whether the JS class is stored in the registry. To accomplish this, we register the class along with the custom view in the core registry.

In this instance, we inherit the base form view by incorporating the button as a template.

<templates>
   <t t-name="blog_js_class.modelInfoBtn" t-inherit="web.FormView">
       <xpath expr="//t[@t-set-slot='layout-actions']" position="inside">
           <button class="btn btn-primary" t-on-click="actionInfoForm">Info
           </button>
       </xpath>
   </t>
</templates>


In this scenario, there's a button tag containing a click function named "actionInfoForm()". Now, we proceed to modularize the template into components to display the view and execute the function triggered by the button click.

/** @odoo-module **/
import { FormController } from "@web/views/form/form_controller";
import { formView } from '@web/views/form/form_view';
import { registry } from "@web/core/registry";
import { jsClassDialog } from "@blog_js_class/js/js_blog_dialog";
class jsClassModelInfo extends FormController {
   actionInfoForm(){
       this.env.services.dialog.add(jsClassDialog, {
           resModel: this.props.resModel,
           resDesc: "This is a demo pop-up; feel free to customize the functionality to meet your requirements."
       });
   }
}
jsClassModelInfo.template = "blog_js_class.modelInfoBtn";
export const modelInfoView = {
   ...formView,
   Controller: jsClassModelInfo,
};registry.category("views").add("model_info", modelInfoView);

In this segment of code, we import the necessary classes to register the template. We then generate a new class by extending formController and embed the template within it. Subsequently, we export this class to the controller using a constant. Lastly, we enroll it in the core registry under the view category, labeled with the JavaScript class "model_info".

With the template successfully registered, within this extension class, you'll encounter the actionInfoForm() function, responsible for displaying a dialog box. In Odoo 17, to invoke this dialog box, a new component must be created. Here, you'll observe the dialog box template and its associated values enlisted within the Owl component class.

/** @odoo-module **/
import { Component } from "@odoo/owl";
import { Dialog } from "@web/core/dialog/dialog";
import { _t } from "@web/core/l10n/translation";
export class jsClassDialog extends Component{
    clickClose() {
        this.props.close()
    }
}
jsClassDialog.template = "blog_js_class.infoDialog";
jsClassDialog.components = { Dialog };
jsClassDialog.title = _t("Model Info"),
jsClassDialog.props = {
    confirmLabel: { type: String, optional: true },
    confirmClass: { type: String, optional: true },
    resModel: { type: String, optional: true },
    tools: Object,
    close: { type: Function, optional: true },
    };
jsClassDialog.defaultProps = {
    confirmLabel: _t("Close"),
    confirmClass: "btn-primary",
};


<templates>
   <t t-name="blog_js_class.infoDialog">
       <Dialog size="'md'" title="'Model Info'" modalRef="modalRef">
           <div class="">
               <h6>Model:</h6>
               <span>
                   <t t-esc="props.resModel"/>
               </span><br/>
               <h6>Description:</h6>
               <span>
                   <t t-esc="props.resDesc"/>
               </span>
           </div>
           <t t-set-slot="footer">
               <button class="btn" t-att-class="props.confirmClass"
                       t-on-click="clickClose" t-esc="props.confirmLabel"/>
           </t>
       </Dialog>
   </t>
</templates>

By importing the "jsClassDialog" class and integrating it with the environment dialog service, we enable the display of the dialog box.

import { jsClassDialog } from "@blog_js_class/js/js_blog_dialog";


actionInfoForm(){
   this.env.services.dialog.add(jsClassDialog, {
       resModel: this.props.resModel,
       resDesc: "This is a demo pop-up; feel free to customize the functionality to meet your requirements."
   });
}

Now, when we click the "Info" button, let's observe the appearance of the dialog box.


To sum up, the JS Class feature within Odoo serves as a crucial asset for developers, offering the versatility needed to tailor workflows to specific needs. It opens up a plethora of opportunities for integrating JavaScript functionalities, thereby enriching the Odoo form view with advanced capabilities and optimizing its effectiveness. Ultimately, this results in a more adaptable and streamlined system, benefitting users in various ways.

Creating a Chatter Button in Odoo 16: A Step-by-Step Guide