In this blog, we will look at how we can define header, Statusbar with buttons in Odoo v12. We have already created a form view. If you want to read about how to create models and new views, refer the blog: how to create a module in odoo v12.
In the above image, you can see the header of the sale order form. It encompasses different buttons and a status bar which represents the record status in the right end.
So we will look at how one can add a similar one in our students form view that we have already created.
Here we will continue with the editing of the original file that we have already created, also I will explain how to inherit and do the same in the later part of this blog.
So let us have a look at the existing form view code first,
Above image is the code of the form view that we have, So first let us add the status bar on the right side of the header.
In the python file and in the corresponding model, ie, student.student we have to add a new field which has to be shown.
In the above image, you can see in the model student.student, a new field name state is added, which is a selection field with values draft, done and cancel. Set the default value as draft, so that the newly created records will come in draft state.
state = fields.Selection([('draft', 'Draft'), ('done', 'Done'),
('cancel', 'Cancelled'), ], required=True, default='draft')
So we have defined the field, now we have to add the field in the XML.
In the above image, inside the form tag and before the sheet tag, you can see a new tag named header is added, and the field we have added in the python.
<field name="state" widget="statusbar" statusbar_visible="draft,done,cancel"/>
widget=”statusbar” has to be given for this field, if you remove this widget you can see the difference in the view, so have a try without giving the widget. In the statusbar_visible we can specify which all field has to be displayed in the statusbar, if cancel don't want to see in the status bar initially unless a record goes into the state, we can specify the statusbar_visible as below,
<field name="state" widget="statusbar" statusbar_visible="draft,done"/>
Make sure that python file is called in init and the XML file is called in the manifest.Restart the service as we have made changes in python and install/upgrade the module.
After upgrading the module, you can see the status bar getting added in the header. And the status bar only showing the Draft, Done state, hope you get the reason why canceled is not shown over there? am I? Because in the statusbar_visible we haven't given cancel. If statusbar_visible is empty we can see all the states there.
Adding Button in the header:
Let us add three buttons to the form, for moving the student records to different states.
1. Done- for moving the record to done state.
2. Cancel- For moving the record to cancel state.
3. Reset to draft- For resetting the record to draft state.
So let us make changes in the XML file to add the buttons,
As shown in the above image three buttons are added into the form, button is defined using the button tag, we have to specify a name for the button, as well as a string for the button which will the end user see, class=”oe_highlight” is given to add CSS to the button, so that the button will come with a blue color.
<button name="button_done" string="Done" class="oe_highlight" type="object"/>
<button name="button_reset" string="Reset to Draft" class="oe_highlight"
<button name="button_cancel" string="Cancel" type="object"/>
Types of Button:
Using a button we can call an XML action or a python function if we are going to call a python function on button click, the type has to be given as an object. If the type is given an action, the code will look for the action in the name of the given button.
Here in our case, we have given the type as Object so that on clicking the button python function with the given name of the button in the corresponding model get executed.
So let us upgrade the module and see the changes,
After upgrading the module, you can see that buttons given in the code have appeared in the form.
Have a click at those buttons and see what you get. You are getting an error message right? This is because the system is looking for a function in the name of the button in the student.student model, yet we haven't defined it, that is the reason for getting the error message.
The error message says that student.student model has no attribute/function named button_done. So let us define those function in the model.
In the above image, you can see we have defined three functions in the name of the buttons we have added in the XML.
for rec in self:
So let us look what the button_done do, on clicking the Done button in the XML file, the function button_done will get called inside the function, what we are doing is that changing the field value of the state to do.
Similarly, you can see what the Cancel button and Reset to Draft button does. You can write the values to field either by using the write method or by calling the operator. You can check the difference between button_done function and button_reset function. In these two functions - two different ways are used to write the values to the field.
The self is iterated over the for loop is to avoid the singleton error, which you will understand later.
As api.multi decorator is used above the function we have to update the import line like this to import the API.
from odoo import models, fields, API
So now, we have defined the three functions, now let us restart the service and see the working.
Changes in the python don’t need the module upgrade, now just click those buttons and see the changes. On each button click, you can see the state in the statusbar getting changed.
So we are done with the functions,
Here in the form, Done and Rest to Draft buttons are in Blue and Cancel Button is not colored, this is because we haven't given the class=”oe_hightlight” for the cancel button.
If you look at the form you can see all the buttons are appearing at the same time. Why we to show the Reset to Draft button when the record is already in the draft state, this button has to show only when the record is in the other two states. Similarly, the Done button has to show in the Draft state only. Let us look at how to achieve it.
As shown in the above image, along with the button, we can specify states in which the button has to be visible, this can be done by specifying the states inside the state's attributes.
<button name="button_reset" string="Reset to Draft" states="done, cancel" class="oe_highlight"
Now the Reset to Draft button will be visible only in done and cancel state. Upgrade the module and see the changes.
So this is all about defining the buttons, Statusbar, and header.