In odoo, if we are editing a document, then click on a button, even though it’s not the Save button, odoo will immediately save the document, then the method of the button that we click will be executed by odoo. The document will change to read-only mode, which means that we can no longer edit the document. If we want to change it, for example, because there is some wrong information we have to click the Edit button.
In some scenarios, this behavior sometimes feels a bit less user-friendly, because sometimes we need a button to help the user to input some data automatically, but not all the automatically generated data that we provide to user may need to be stored by the user. For example, to generate data based on certain conditions, such as creating an order line from a list of products that have been ordered by a customer. When the product list has been added to the sales order, it doesn’t mean that the user always wants the data to be saved right away, right? It could be that the user just wants odoo to provide some kind of recommendation, later the user can choose whether the recommendation that given by odoo is ready to be saved or not.
Of course, when the data has been saved, the user can still change the data by pressing the Edit button, but I think the user experience will be better if the list of product recommendations that the customer has ordered is successfully generated but the document is still in edit mode. So the user can review the document before clicking the Save button to actually save the document.
What’s even more annoying is when the document is opened in a dialog/modal. When we click a button in the dialog/modal, the document will be saved immediately and the dialog/modal will be closed by odoo. Indeed, we can set it via python so that the document will be opened again immediately, but there will be a delay before the document to appear again.
Actually, I’ve been trying to solve this problem since odoo was still version 12 (I started working as an odoo programmer when odoo was still version 10/11). But because there is no urgency, I have not received a client complaint report about this problem, I only do it as part of my blogging activity. Until a few weeks before this article was written, when odoo version reaches 14, I still couldn’t find a good solution.
The result is a module which I named as button_no_save. Please download here. I’ve also created a demo module to demonstrate how the button_no_save module works, both in a normal document and a document that opened in a dialog/modal. Please download here.
How to use the module?
First, you have to download the button_no_save module above, then install it on your odoo server. Then create a field with the type of Char as a trigger when the button that you want doesn’t make odoo to save the document when the user clicks it.
trigger_field = fields.Char()
Then create a method with the @api.onchange() decorator. In edit mode when a button that you marked with a custom attribute recognized by the button_no_save module is clicked, the button_no_save module will triggers the onchange function so this method will be executed.
@api.onchange('trigger_field') def onchange_trigger_field(self): print('This method will be called in edit mode')
Then create a button with type of object and insert the method above as the value of the name attribute.
<button name="onchange_trigger_field" string="Compute Result" type="object" />
When you click the Compute Result button in both edit and read-only mode, odoo will execute the onchange_trigger_field method above.
But, if you want odoo to call the different method in edit and read-only mode, you must create the second method without the @api.onchange decorator and insert that method name as the value of the name attribute of the button that you created. NOTE !!! A method marked with the @api.onchange decorator is mandatory, because if you don’t write it, the button_no_save module will fail to trigger the onchange function in edit mode.
@api.onchange('trigger_field') def onchange_trigger_field(self): print('This method will be called in edit mode') def recompute_total(self): print('This method will be called in readonly mode')
<button name="recompute_total" string="Compute Result" type="object" />
From the code above, if you click the Compute Result button in edit mode odoo will execute the onchange_trigger_field method, whereas if you click the button in read-only mode odoo will execute the recompute_total method. Why did I make the button_no_save module execute different methods in edit and read-only mode? Because in edit mode, when a method marked with a @api.onchange decorator is executed, not all the records of your model are stored in the database, so the record might not have a database id, the id of the record is False. If you click the button in read-only mode, all the records of your model are certainly stored in the database, so all records have a database id. That’s why I made the button_no_save module can execute different methods in both edit or read-only mode, just in case that you want to write different logic in those modes.
Next, insert the trigger field that you created into the odoo form/view, make sure to make it invisible, because that field will store the date and time when the user clicks the button that you created, so it does not confuse the user.
<field name="trigger_field" invisible="1" />
In the final step, add the triggeronchange attribute to the button that you created with the value of your trigger field name.
<button name="recompute_total" string="Compute Result" type="object" triggeronchange="trigger_field" />
This is a screenshot when the user clicks the button marked with the triggeronchange attribute in the normal form.
As you can see in the Network tab of the developer tools, odoo has called the onchange function. The form/document also does not change to read-only mode, so the user can still edit the document and review it again, before being absolutely sure to click the Save button to save the document.
This is a screenshot when the user clicks a button marked with the triggeronchange attribute on a form/document that is opened in a dialog/modal.
As you can see in the Network tab of the developer tools, odoo has called the trigger function. The modal/dialog is also not closed by odoo, so the user can still edit the document.
The two screenshots above are screenshots of the demo module from the button_no_save module. I highly recommend you to download this module to try it on your odoo server, to find out if the button_no_save module is the module you need or not.