Sometime we might have come across a situation where we need to conditionally apply attributes to the fields. In Odoo we can conditionally apply some of the attributes to a view component which is based on other fields. There are three attributes that we can apply like this that are invisible, read-only, and required. With this, we can hide a field (invisible), make it required, or read-only based on another field’s value. In this blog, I will show you how to use attrs in Odoo 13.
For this, I am taking my student.student model. I already created the model with some fields.
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")age = fields.Integer(string = "Age")gender = fields.Selection([('m', 'Male'), ('f', 'Female'), ('o', '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')
<record id="student_studen_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"/>
<field name="gender"/>
</group>
<group>
<field name="last_name"/>
<field name="age"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
Now I am going to hide the Last Name field based on the boolean field Include the Last name. We only need to show the last name field if we check the Include Last name field. For that, we need to give attrs inside the Last Name field and need to give condition.
So the field will be,
<field name="last_name" attrs="{'invisible': [('include_last_name','=',False)] }"/>
Here in this code I have specified the attrs as invisible and given the condition when to invisible. The condition will be like when the include_last_name = False makes it invisible.
Here you can see what happens when you check the boolean button and when not.
We can also apply this for the other two attributes that are required and read-only. Let me replace invisible from the code above with required and then read-only and let see what happens.
<field name="last_name" attrs="{‘required’: [('include_last_name','=',True)] }"/>
As you can see with this code the field last_name will be required only if check the checkbox.
The result of the above code is
We can do the same for read-only too.
We can also add multiple conditions. Let’s see how we can add multiple conditions.
<field name="last_name" attrs="{'invisible': ['|',('include_last_name','=',False),('name','=',False)] }"/>
Here, I have added to conditions and also I have mentioned the operator as a logical OR. Here it says perform logical or between the two conditions and if you have 3 conditions we need to specify the operator to tell which logical operation should perform with the third condition. So if any of the conditions are true then it will return True so in the above condition, the last_name becomes invisible if ‘include_last_name’ is false or ‘name’ is false.
Let’s say if you have three conditions and all condition should perform the logical OR then you need to write like this,
<field name="last_name" attrs="{'invisible': ['|','|',('include_last_name','=',False),('name','=',False), ('dob', '=',False)] }"/>
If we don’t supply any operators there it will default taken as a Logical AND operator.
That is ,
<field name="last_name" attrs="{'invisible':[('include_last_name','=',False),('name','=',False)] }"/>
Here the invisible becomes true only if both the conditions are true.
Most of the time we need a combination of attributes such as invisible and required.
we can also add multiple attributes inside an attrs.
That is,
<field name="last_name" attrs="{'invisible': [('include_last_name','=',False)], 'required' :[(('include_last_name','=',True))] }"/>
Also inside the attrs we also have one more option that is column invisible. It is used for One2many fields when we need to dynamically hide a column in the One2many based on the parent object.
<field name="total" attrs="{'column_invisible' : [('parent.is_total','=',False)]}"/>
This works the same as the invisible but here to get the field value of the parent object we need to call it with a parent.field_name. In this example, the total is an One2many field and is_total is a field of the parent.
The attrs not only works with the field, but You can also use the attrs for groups, pages, button, div, etc.