Hi guys,
In this tutorial I will learn you how to create an on_change event that automatically updates a field when another field changes. In this sample I will create two new fields under sales > products in the tab ‘Procurements’. When a value changes on one of the two fields a third field will be updated with the total of the other two fields.
1. Creating new fields
The first step is to create new fields in the Python file. For example:
1 2 3 4 5 6 7 8 9 10 |
# -*- coding: utf-8 -*- from openerp import models, fields, api class on_change_function(models.Model): #Inhertis the model product.template _inherit = 'product.template' #Creates two new fields (CostPrice and ShippingCost) in the model product.template CostPrice = fields.Float('Buy price') ShippingCost = fields.Float('Shipping Cost') |
This adds two fields (CostPrice and ShippingCost) to the model product.template, which I first inherited. Both these fields are for numbers. After adding your new fields you need to add them to the view.
2. Add fields to view
In case you’re coding in the current module you can simply add the fields like this:
1 2 |
<field name="CostPrice" on_change="on_change_price(CostPrice,ShippingCost)"/> <field name="ShippingCost" on_change="on_change_price(CostPrice,ShippingCost)"/> |
In case you have a new view you can simply add them but if you want to add them to an existing view you will need to inherit the record from the other module, just like in my sample. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<openerp> <data> <record id="view_product_form_inherit" model="ir.ui.view"> <field name="name">product.template.common.form.inherit</field> <field name="model">product.template</field> <field name="inherit_id" ref="product.product_template_form_view"/> <field name="arch" type="xml"> <xpath expr="//field[@name='standard_price']" position="before"> <field name="CostPrice" on_change="on_change_price(CostPrice,ShippingCost)"/> <field name="ShippingCost" on_change="on_change_price(CostPrice,ShippingCost)"/> </xpath> </field> </record> </data> </openerp> |
3. On_change function
Noticing anything in this code? I’ve already added the on_change event in the view like this:
1 |
on_change="on_change_price(CostPrice,ShippingCost)" |
This will search for the function on_change_price in your module and sends two values to the function, CostPrice and ShippingCost. This are the two fields that will contain the values and in these variables are now the values from the two fields. We’re almost there now, the only thing you need to do now is create the function on_change_price in your Python file. Return to your Python file and add the following code:
1 2 3 4 5 6 7 8 9 10 11 12 |
#This method will be called when either the field CostPrice or the field ShippingCost changes. def on_change_price(self,cr,user,ids,CostPrice,ShippingCost,context=None): #Calculate the total total = CostPrice + ShippingCost res = { 'value': { #This sets the total price on the field standard_price. 'standard_price': total } } #Return the values to update it in the view. return res |
In the variables CostPrice and ShippingCost are the values that the user has entered. The variable total simply contains the sum of CostPrice and ShippingCost and this should now be filled in to our third field, which is named standard_price. After the value is calculated and added to the new field it should be returned so that the user can see it.
The result:
As you can see in this image the third field will be automatically calculated with the values from the field CostPrice and the field ShippingCost. The only thing you need to do for the on_change event to go off is to enter, tab or click anywhere else.
Want to see this module in action? You can download / view it on my Github.
If you want to you can also work with @api.onchange, which is specifically for Odoo 8.