In Odoo application development, the <form>
element is an integral part of the user interface used for managing data. Forms in Odoo are designed to display, edit, and validate model data. This article will discuss the anatomy of a form, provide code examples, and explain how to customize it.
Anatomy of <form>
in Odoo
Odoo uses XML to define the structure and layout of forms. Below are the main elements of a form in Odoo:
1. Tag
- The primary tag that defines a form.
- Must have a
string
attribute to name the form.
2. Field
- Uses the
<field>
tag to display model data. - Can have attributes such as
name
,widget
, andreadonly
.
3. Groups and Pages
<group>
: Used to group fields in a row.<page>
: Used to create tabs within a form.
4. Header
- The top section of the form, often used for action controls, status, or concise information.
5. Notebook
- Divides the form into multiple tabs.
6. Footer
- The bottom section of the form for action buttons or additional information.
General structure example:
<record id="view_form_example" model="ir.ui.view">
<field name="name">example.form</field>
<field name="model">example.model</field>
<field name="arch" type="xml">
<form string="Example Form">
<header>
<button string="Approve" type="object" name="action_approve" class="btn-primary"/>
<field name="state" widget="statusbar" statusbar_visible="draft,approved"/>
</header>
<sheet>
<group>
<field name="name"/>
<field name="description"/>
</group>
<notebook>
<page string="Details">
<field name="details"/>
</page>
<page string="History">
<field name="history" widget="one2many_list"/>
</page>
</notebook>
</sheet>
<footer>
<button string="Cancel" class="btn-secondary" type="object" name="action_cancel"/>
</footer>
</form>
</field>
</record>
Simple Form Example
Model (Python)
from odoo import models, fields
class ExampleModel(models.Model):
_name = 'example.model'
_description = 'Example Model'
name = fields.Char(string="Name", required=True)
description = fields.Text(string="Description")
details = fields.Text(string="Details")
history = fields.One2many('example.history', 'example_id', string="History")
state = fields.Selection([
('draft', 'Draft'),
('approved', 'Approved'),
], default='draft', string="Status")
View (XML)
<odoo>
<record id="example_form_view" model="ir.ui.view">
<field name="name">example.form.view</field>
<field name="model">example.model</field>
<field name="arch" type="xml">
<form string="Example Form">
<header>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<field name="name"/>
<field name="description"/>
</group>
</sheet>
</form>
</field>
</record>
</odoo>
Customizing Forms
- Adding Widgets\ Odoo provides various widgets to enrich the field display. Example usage:
<field name="date" widget="date"/>
<field name="state" widget="statusbar" statusbar_visible="draft,approved"/>
- Dynamic Fields\
Use attributes like
attrs
to make fields conditional:
<field name="description" attrs="{'readonly': [('state', '=', 'approved')]}"/>
- **Inheritance (Using **``)\ Modify an existing form:
<odoo>
<record id="example_form_view" model="ir.ui.view">
<field name="inherit_id" ref="module_name.example_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group" position="inside">
<field name="new_field"/>
</xpath>
</field>
</record>
</odoo>
- Adding Custom Actions\ Add action buttons that call model methods:
<button string="Approve" type="object" name="action_approve"/>
In the model:
def action_approve(self):
for record in self:
record.state = 'approved'