Sometimes we may go through situations where we have to make some fields read only, invisible, or required based on another field. In Odoo, these types of situations can be handled by using attrs (Attributes). In this blog, we can discuss how to use attrs in Odoo 16.
For that, we can consider the model student.student with as an example, which is given below.
class StudentRecord(models.Model):
_name = 'student.student'
include_last_name = fields.Boolean('Include Last name')
name = fields.Char(string="Name", required=True)
last_name = fields.Char(string="Last Name")
dob = fields.Date(string="Date of birth")
gender = fields.Selection([
('male', 'Male'),
('female', 'Female'),
('others', 'others')],
string="Gender", required=True)
student_blood_group = fields.Selection([
('A+', 'A+ve'),
('B+', 'B+ve'),
('O+', 'O+ve'),
('AB+', 'AB+ve')],
string="Blood Group")
nationality = fields.Many2one('res.country', string='Nationality')
The form view for the model is shown below.
<record id="student_student_form" model="ir.ui.view">
<field name="name">student.student.form</field>
<field name="model">student.student</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name"/>
<field name="include_last_name"/>
<field name="dob"/>
</group>
<group>
<field name="last_name"/>
<field name="gender"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
Now, we can check how to make a field invisible based on another field. In our example, we can make the field last_name invisible based on the field include_last_name. For that, add attrs to the last_name field in the XML code as shown below.
attrs="{'invisible': [(condition)] }
<field name="last_name" attrs="{'invisible': [('include_last_name','=',False)] }"/>
This code will give the result that last_name will be visible only if the field include_last_name is True. Otherwise, it will be invisible.
Similar to invisible attributes, there exists one more attribute called “column_invisible.” It is used to hide a field based on the value of a field in another object connected through an On2Many connection.
<field name="total" attrs="{'column_invisible': [('parent.is_total','=',False)]}"/>
According to the code above, the field total will be invisible if the value of the field is_total is None, which belongs to the One2Many field parent.
For making a field mandatory based on another field, we can use the attribute “required.” It can be used as given below.
attrs="{required: [(condition)] }
<field name="last_name" attrs="{'required':[('include_last_name','=',True)]}"/>
In the above case, if the field include_last_name is True, then the field last_name will be a mandatory field; else, it will not be mandatory.
Using attrs, we can make a field read-only with respect to the value of another field.
attrs="{required: [(condition)] }
<field name="last_name" attrs="{'readonly': [('include_last_name', '=', False)]}"/>
According to the above code, the field “last_name” will be read only if the value of the boolean field ‘include_last_name’ is False. Otherwise, the field will be writable.
Multiple Conditions
It is possible to apply multiple conditions to a single attribute and multiple attributes to a single field.
1) Multiple conditions for a single attribute
<field name="last_name" attrs="{'invisible':
['|', ('include_last_name','=',False), ('name','=',False)] }"/>
In this case, the field “last_name” will be invisible either if the value of the field “include_last_name” is False or the value of the name is False. The ‘|’ operator is used for OR conditions. If we didn’t use any operators, then by default Odoo will consider it as an AND condition.
2) Multiple attributes for a singlefield
<field name="last_name" attrs="{'readonly': [('include_last_name', '!=', True)], 'required': [('dob', '=', True)], 'invisible': [('name', '=', False)]}"/>
3) Multiple attributes with multiple conditions
<field name="last_name" attrs="{'readonly': [('include_last_name','=',False), ('name','=',False)], 'invisible': [('include_last_name','=',False), (name, '!=', True)], 'required': ['|', ('include_last_name','=',False), ('name','=',False)]}"/>
Attrs can be also applied for buttons, groups, div, buttons, pages, etc.,
So in Odoo, we can make a field hidden, mandatory, or read-only based on the value of another field simply by using attr.