Hi guys,
In this tutorial I will learn you how to re-color agenda views and kanban views. This gives you the ability to modify any color of any item by using a Javascript color picker and saving the color on a record. In this tutorial you will learn how to create a color picker and how to modify agenda and kanban views through Javascript. In this tutorial I will go through this step by step and I will learn you how to modify the agenda view and kanban view for project tasks as an example.
Now let us start!
1. Installing the colorpicker
The first step is to install a module that is already built by another person, named Adil Houmadi. Download the module (you can find it here) and install it in your Odoo. From here on we can start developing on top of it.
2. Creating the models
Now that you have the widget installed it is time to set up your models. If you would directly create the color field on this view you would always have to choose a color which can get annoying. So lets first create a new model with a new view where we can define custom colors. By doing so you can then create a many2one on your project view and simply choose a status from a dropdown! So lets create a new model:
1 2 3 4 5 6 7 8 9 10 11 |
class AgendaStatus(models.Model): _name = 'agenda.status' name = fields.Char( String='Description' ) color = fields.Char( string="Color", help="Choose your color", size=7 ) |
This model will simply create two fields. One where we can fill in the name of the status and a second field which will call a color picker where we can choose a color from. Lets create the view to show this and everything will become much clearer!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<!--Add a new menuitem under project --> <menuitem action="open_view_agenda_coloring" id="menu_projects_agenda" name="Agenda statuses" parent="project.menu_project_management" sequence="10"/> <!-- Create an action for the menuitem --> <record model="ir.actions.act_window" id="open_view_agenda_coloring"> <field name="name">Agenda Statuses</field> <field name="res_model">agenda.status</field> <field name="view_type">form</field> <field name='view_mode'>tree,form</field> <field name='view_id' ref='agenda_status_tree_view'/> </record> <!-- Create the tree view --> <record id="agenda_status_tree_view" model="ir.ui.view"> <field name="name">agenda.status.tree.view</field> <field name="model">agenda.status</field> <field name="type">tree</field> <field name="priority" eval="1"/> <field name="arch" type="xml"> <tree string="Status"> <field name="name"/> <field name="color" widget="color"/> </tree> </field> </record> <!-- Create the form view --> <record id="agenda_status_form_view" model="ir.ui.view"> <field name="name">agenda.status.form.view</field> <field name="model">agenda.status</field> <field name="type">form</field> <field name="priority" eval="1"/> <field name="arch" type="xml"> <form string="Status"> <group col="2"> <field name="name"/> <field name="color" widget="color"/> </group> </form> </field> </record> |
So did you notice anything you haven’t seen before? It is probably this line:
1 |
<field name="color" widget="color"/> |
This line uses a widget that is created with the module web_widget_color which we first installed and that is exactly the reason why we needed it.
When you would now install the module you would get a view like this:
The moment that you click on the widget=”color” field you will get a color picker from where you can choose any color! When you give the record a name, choose a color and save the record the hexidecimal value will be saved in the database and from there on we will re-color the project task view later on.
But first, have a look at the tree view:
We now have the custom views, we can save colors and view them both in tree and form view. Let us move on!
3. Create a many2one to the status model
Alright so we can now make statuses and save colors but they now need to be attached to the project task its view. Lets create a many2one from the model ‘project.task’ to the model ‘agenda.status’ and create a related field.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class ProjectTask(models.Model): _inherit = 'project.task' agenda_status = fields.Many2one( 'agenda.status', 'Agenda status' ) hex_value = fields.Char( string="Hex Value", related="agenda_status.color", store=False, size=7 ) |
The related field will be used to have the color value available in the agenda view, so lets start creating those views. In order to add a new field to the project task view we will need to inherit it and add our related field:
1 2 3 4 5 6 7 8 9 10 |
<record id="project_task_inherit_view" model="ir.ui.view"> <field name="name">project.task.inherit.view</field> <field name="model">project.task</field> <field name="inherit_id" ref="project.view_task_form2"/> <field name="arch" type="xml"> <xpath expr="//field[@name='categ_ids']" position="after"> <field name="agenda_status"/> </xpath> </field> </record> |
Now that ‘project.task’ has a many2one to ‘agenda.status’ we will get a dropdown from where we can choose statuses (which have colors attached to it):
4. Adding a custom JavaScript file
Alright, so we’re almost there! We can create statuses with colors and choose a status on a project. We can now acces the values from the ‘agenda.status’ model so all we need to do now is to acces the view and inject the colors with JavaScript.
Create a new XML file from where you will call the JavaScript file. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8"?> <openerp> <data> <template id="web_task_color_assets_backend" name="web_task_color_assets_backend" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <!--Be sure to call your module name in place of project_task_agenda_coloring. This is the name of my module! --> <script src="/project_task_agenda_colouring/static/src/js/web_task_color.js" type="text/javascript"></script> </xpath> </template> </data> </openerp> |
Tip: Be sure to add this new XML file in your __openerp__.py file!
So, what exactly will this XML do? It will inherit the backend from where all JavaScript is loaded and it will add our custom JavaScript file in it. Now create a new JavaScript file under yourAddonName/static/src/js/ and give it the same name as in your XML. In my example I have created a new JavaScript file named web_task_color.js:
5. Applying your colors to the agenda view
Now that everything is in place there is only one more thing to do. We need to tell Odoo what view we want to inherit and what we want to change. This is done by creating a function (instance) and calling the correct view. Let me show you the code first and I’ll explain it in more depth afterwards:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
openerp.project_task_agenda_colouring = function (instance) { instance.web_calendar.CalendarView = instance.web_calendar.CalendarView.extend({ event_data_transform: function (event) { var res = this._super.apply(this, arguments); //This would go off when there is no color set for hex_value. You could control this too. if (res && res.hasOwnProperty('className')) { //If you would uncomment the next line it would use the default color that is set for the user. (default behaviour from Odoo calendars) //res.className = res.className.substring(0, res.className.indexOf(' calendar_color_')); res.backgroundColor = '#DBDBDB'; if(res.title.indexOf('false') > -1) { res.title = res.title.substring(0, res.title.indexOf(',')); } } if (event.hex_value && res.title) { res.backgroundColor = event.hex_value; res.title = res.title.substring(0, res.title.indexOf(', ' + event.hex_value)); } return res; } }); }; |
The idea is to first create an instance which refers to your module:
1 |
openerp.project_task_agenda_colouring = function (instance) { |
This function will now know where we are (in the module project_task_agenda_colouring). The next step is to tell it what view we want to modify:
1 |
instance.web_calendar.CalendarView = instance.web_calendar.CalendarView.extend({ |
With this line Odoo knows that we want to do something with the CalendarView and that we want to extend this view.
From there on you will tell the JavaScript that we want to transform the data and that you want to have access to the data for the record(s):
1 2 |
event_data_transform: function (event) { var res = this._super.apply(this, arguments); |
Then the last part is to call the correct value (the hexidecimal color) and to apply the color to the correct item:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
if (res && res.hasOwnProperty('className')) { //If you would uncomment the next line it would use the default color that is set for the user. (default behaviour from Odoo calendars) //res.className = res.className.substring(0, res.className.indexOf(' calendar_color_')); //When no color is set on the project.task view it will show this color by default res.backgroundColor = '#DBDBDB'; if(res.title.indexOf('false') > -1) { res.title = res.title.substring(0, res.title.indexOf(',')); } } if (event.hex_value && res.title) { //Setting the hexidecimal color to the item res.backgroundColor = event.hex_value; res.title = res.title.substring(0, res.title.indexOf(', ' + event.hex_value)); } return res; } }); }; |
When you now reload or install your module you will see that after you ask some tasks and statuses you’ll get re-colored agenda items:
6. Re-coloring Kanban views
Want to do the same for the Kanban view? You can, read on! If you don’t you can skip this part and jump to chapter 7.
Alright so you want to re-colour project items in the Kanban view?
Go back to your XML file (the one that creates the views, not the one that adds our JavaScript) and inherit the Kanban view. We will need to make the color values available in this view too or we can’t access them:
1 2 3 4 5 6 7 8 9 10 |
<record id="project_task_kanban_view" model="ir.ui.view"> <field name="name">project.task.kanban.view</field> <field name="model">project.task</field> <field name="inherit_id" ref="project.view_task_kanban"/> <field name="arch" type="xml"> <xpath expr="//field[@name='categ_ids']" position="after"> <field name="hex_value" widget="color"/> </xpath> </field> </record> |
Now that we can access the hex value we will need to add a new JavaScript instance. This time you will need to tell it that you want to modify the KanBanRecord and that you want to add your custom colors to these items:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
instance.web_kanban.KanbanRecord.include({ kanban_getcolor: function (variable) { if (this.view.fields_view.model == 'project.task') { return (0 % this.view.number_of_color_schemes); } else { return this._super(variable); } }, renderElement: function () { this._super(); if (this.values.hex_value) { //Apply the color to the record, if there is one. this.$el.find('.oe_kanban_card').css("background-color", this.values.hex_value.value || 'white'); } } }); |
It is as simple as that. In this JavaScript instance we will check that we are on the view ‘project.task’ and we will then apply the color with CSS to the record. The result:
7. Conclusion
You can do about anything in Odoo and re-coloring items is easier then you’d think!
Do you want to see the source code or try this module for yourself?
Example module to inherit and modify a calendar view can be found here
Example module to inherit and modify a kanban view can be found here
Has this tutorial helped you, do you have any feedback or questions? Post away!