0% found this document useful (0 votes)
11 views

Odoo JavaScript Programming Tutorial (Part Three) – Use of Jquery – Ngasturi Notes

Uploaded by

syb
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

Odoo JavaScript Programming Tutorial (Part Three) – Use of Jquery – Ngasturi Notes

Uploaded by

syb
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Odoo JavaScript Programming Tutorial (Part Three) –

Use of Jquery – Ngasturi Notes

Ngasturi bin Saidi

This article is the third part of my odoo javascript programming tutorial series. If you haven’t read the
first or the second part, I suggest you to read those articles first. You should find the link of those articles
at the bottom of this page.

In the second part, we have discussed how to add the click event to a widget, as well as how to change
the value of the field. In this part, we will discuss how to write jquery events, get value from other
fields/widgets, and how to change the value of other fields/widgets that are still on the same page.

First, let’s add a new button to the widget that we have created in the second part.
1 <?xml version="1.0" encoding="UTF-8"?>

2 <template>

3 <t t-name="WidgetOneTemplate">

4 <div>

<t t-if="widget.mode == 'edit' ">


5
<div class="input-group">
6
<div class="input-group-prepend">
7
<button class="btn btn-danger btn-minus"> - </button>
8
</div>
9
<input type="text" class="form-control" t-att-value="formated_value"
10
disabled="disabled" />
11
<div class="input-group-append">
12
<button class="btn btn-success btn-plus"> + </button>
13
<button class="btn btn-primary btn-copy"><i class="fa fa-copy">
14 </i></button>
</div>
15
</div>
16
</t>
17
<t t-if="widget.mode == 'readonly' ">
18
<span t-esc="formated_value" />
19
</t>
20
</div>
21 </t>
22 </template>
23
24
25

It will look like this.

We can write jquery code in any method, even outside the widget, but if we want to access the elements
of our widget, make sure the template is already rendered, for example, we can write the jquery code at
the bottom of the _render method.

When write a jquery event, for example the click event on a button with the btn-copy class like in the
code above, I don’t recommend using the $(‘.btn-copy’).click() code like in the code below.

1 _render: function () {
2 var formated_value = field_utils.format[this.formatType](this.value);

3 this.$el.html($(qweb.render(this.template, {'widget': this, 'formated_value':


formated_value})));
4
$('.btn-copy').click(function(){
5 alert('click copy button');
6 });

7 },
8
9

Why ? Because based on my experience, we can not add events with the code above to all elements. This
does not mean that the code $(element).click() cannot be used, because the code below will be
executed smoothly.

1 _render: function () {
2 var formated_value = field_utils.format[this.formatType](this.value);

3 this.$el.html($(qweb.render(this.template, {'widget': this, 'formated_value':


formated_value})));
4
$('.o_form_button_save').click(function(){
5 alert('click save button');
6 });

7 },
8
9

With the code above, when you click on the Save button, the click save button message will be
displayed.

The best way to add a jquery event to a widget is to use the this.$el.find(element).click(), as shown
in the code below.

1 _render: function () {
2 var formated_value = field_utils.format[this.formatType](this.value);

3 this.$el.html($(qweb.render(this.template, {'widget': this, 'formated_value':


formated_value})));
4
this.$el.find('.btn-copy').click(function(){
5
6 alert('click on copy button');

7 });

},
8
9

With the this.$el.find(element) code, odoo will ensure that the click event above will only be
executed in one view/field only. I recommend you to always use the this.$el.find(element) code if
you want to write events with jquery, or to get the values of the elements in the widget. As a precaution,
if the widget that we make is used more than one field in one form, or there are other widgets that use
the same class. Of course, it’s not funny if the event that we write executes the action from another
widget.

Then what if we want to access values from other fields ?

As an example, let’s add 2 more integer fields in the form that we have created so that the form view will
be like the image below.

Then in the jquery click event that we have created, add the console.log command as shown in the
code below.

1 _render: function () {

2 var self = this;

3 var formated_value = field_utils.format[this.formatType](this.value);

4 this.$el.html($(qweb.render(this.template, {'widget': this, 'formated_value':


formated_value})));
5
this.$el.find('.btn-copy').click(function(){
6 console.log(self);
7 });

8 },

9
10

IMPORTANT !!! When we write the jquery event followed by an anonymous function, please store the
value of the widget in a temporary variable, in the example code above I save the current widget value
into a variable with the name of self, because in an anonymous function, the this variable no longer
points to the widget that we created, but points to the element that we add an event, it is the button with
btn-copy class.

Restart the odoo service, then refresh your browser. In edit mode, click the copy button then pay
attention to the console tab in the developer tools.

To get the value of a field on a form, we can see it in the recordData or record property as shown
above. In the picture above the values of Field Two and Field Three are still 0, now let’s change the
values of the two fields above then click the copy button again.

In the user interface the values of Field Two and Field Three have changed, but in the console tab the
values are still 0. OK. Now let’s click the + or – button then click the copy button again.
Now the values of Field Two and Field Three in the console are the same as the field values in the
user interface.

Next, let’s test it by moving the console.log code above in another method, for example when the user
clicks the + button as shown in the code below.

1 btn_plus_action: function(){
2 console.log(this);

var new_value = this.value + this.step;


3
this._setValue(new_value.toString());
4
},
5

The values of all fields should match the values displayed in the user interface. Next try removing or
commenting the this._setValue(new_value.toString()); code above. Are the values of all fields in
the console the same as the values in the user interface ? It’s a bit tricky to get the value of a field by
accessing the this/self object. However, depending on the field type, sometimes we can still use jquery.
Please inspect the input element of Field Two then pay attention to the attribute of that element.
From the picture above, the input element of an integer field has a name attribute with the same value
as the field name. So that we can access the value of that field with a jquery code like this.

1 _render: function () {

2 var self = this;

3 var formated_value = field_utils.format[this.formatType](this.value);

4 this.$el.html($(qweb.render(this.template, {'widget': this, 'formated_value':


formated_value})));
5
this.$el.find('.btn-copy').click(function(){
6
var field_two_val = $('[name=field_two]').val();
7 console.log(field_two_val);
8 });

9 },

10
11

Then what if we want to change other value fields with javascript ?

To change other field values, we cannot change the recordData object directly, like in the
self.recordData.field_three = 3000; code, but we must call the
self.trigger_up(‘field_changed’, values) method like in the code below.

1 _render: function () {

2 var self = this;

3 var formated_value = field_utils.format[this.formatType](this.value);

4 this.$el.html($(qweb.render(this.template, {'widget': this, 'formated_value':


formated_value})));
5
this.$el.find('.btn-copy').click(function(){
6
var field_one_val = self.value;
7
var field_two_val = $('[name=field_two]').val();
8
var field_three_val = field_one_val + parseInt(field_two_val);
9 self.trigger_up('field_changed', {
10 dataPointID: self.dataPointID,

11 viewType: self.viewType,

12 changes: {'field_three': field_three_val},

});
13
});
14
},
15
16
17
18
19
20
21

Ignore the dataPointID variable, just write it straight like that, this variable usually contains the model
name and an integer, I don’t know where this integer was obtained and what it is used for. While the
viewType variable is the view type where our widget is used, usually a form or a tree.

What you have to pay attention to is the changes variable which must be an object with a key is the
name of the other field that you want to change its value, while the value depends on the type of the
field. Since in this tutorial the field_three type is an integer, the value must be a number.

This is the end of the third part of my odoo javascript programming tutorial series. If there is no
hindrance, I would advise you to write events like what we did in the second part of the series.
Meanwhile, to change the value of other fields, I would recommend you to use the @api.onchange
decorator with python.

Download the Source Code

Related Article

Odoo JavaScript Programming Tutorial (Part Two) – Widget Logic

Odoo JavaScript Programming Tutorial (Part One) – Create Widget View

How to Prevent Auto Save When User Click on Any Odoo Button

Read Odoo Source Code : Delivery Order Journal Entry

You might also like