Tạo widget trong Odoo

  Sep 6, 2020      2m
   

Tut 11: Widget

Tạo widget trong Odoo

Odoo Tut 11: Widget

Trước khi xem bài viết này, bạn vui lòng hoàn thành hướng dẫn ở Tut 10: Hiện thực wizard trong Odoo.

Bài viết này sẽ hướng dẫn bạn:

  • Widget trong Odoo là gì?
  • Tạo mới một widget trong Odoo

Widget trong Odoo là gì?

Widget trong Odoo nằm ở phần web client. Trên UI, giao diện quản trị (sau khi login) Odoo bạn nhìn thấy chính là cấu thành từ các widget. Các built-in widget của Odoo đang hỗ trợ khá đa dạng:

  • Text
  • HTML
  • Monetary: tiền tệ
  • Image: upload / hiển thị ảnh
  • Selection: option
  • Relation: many2one, many2many
  • Button

Các liệt kê trên mình liệt kê widget phổ biến cho form view mà Odoo đã hiện thực và ta hay dùng nhiều nhất. Ngoài ra, những component sau cũng được hiện thực ở web client trong Odoo (code bằng Javascript):

  • Form view
  • Tree view
  • Kanban
  • Chart
  • Actions: window, server

Một điểm mạnh của Odoo mà mình cực kỳ ưng ý đó là tính module hóa rất cao. Thành phần UI (web client) hiện thực theo các widget, do đó việc tái sử dụng (reuse) và mở rộng (extend) dễ dàng. Các thành phần customization viết riêng thành các module (trong Odoo gọi là addon) khiến việc cài đặt (dùng) và gỡ bỏ (không dùng) linh họat.

Odoo sử dụng framework backbone.js cho web client của mình. Do đó, code js hiện thực, thừa kế sẽ viết theo framework backbone.js này.

odoo code widget

Ảnh. Widget cho form field đã được dùng ở Tut 4: View trong Odoo

odoo form widget ui

Ảnh. Hiển thị widget trên form giao diện

Một tutorial đầy đủ về widget trên trang tài liệu chính thức của Odoo: https://www.odoo.com/documentation/13.0/howtos/web.html

Vậy là mình đã biết được widget nó là gì, tọa lạc ở đâu, mặt mũi trông như nào, xinh xấu quan trọng hay không rồi :D. Tiếp theo, mình sẽ tiến hành tạo một một widget form field nhẹ nhàng thôi.

Tạo mới Odoo widget (form field)

Khai báo widget javascript

Widget ta viết code bằng javascript (*.js), và file js này phải được "include" / "import" (tức khai báo trong view backend) để lúc render frontend script js ta viết mới có tác dụng. Ta tiến hành các bước sau:

  • Khai báo file js trong views/templates.xml
  • Khai báo xml mới tạo ở bước trên vào manifest
  • Tiến hành hiện thực widget trong js

mypet/views/templates.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <template id="assets_backend" inherit_id="web.assets_backend">
        <xpath expr="." position="inside">
            <script type="text/javascript" src="/mypet/static/src/js/bold.js"></script>
        </xpath>
    </template>    
</odoo>

mypet/__manifest__.py

# -*- coding: utf-8 -*-
{
    'name': "My pet - minhng.info",
    # ...
    'data': [
        # ...
        'views/templates.xml',      # <-- DECLARE OUR NEW XML FILE
    ],
}

Hiện thực widget trong Odoo (form field)

File templates.xml trên mình vừa khai báo đường dẫn tương đối đến file bold.js mà ta sắp hiện thực trong phần này. Do đó, ta tiến hành tạo thư mục mới:

mypet/static/src/js/: các file javascript hiện thực widget mình sẽ để trong folder này nha, cấu trúc đường dẫn folder này là "convention" trong Odoo rồi. Nên mình cứ theo đó chính là "best practice", không phải lăn tăn :).

Ta viết một widget nhẹ nhàng thôi đó là sẽ bôi đậm char field, thay vì bình thường Odoo hiển thị normal (không bold hay italic gì cả). Let's viết code thôiiiiiii.

mypet/static/src/js/bold.js

odoo.define('mypet.bold', function (require) {
    "use strict";
    // import packages
    var basic_fields = require('web.basic_fields');
    var registry = require('web.field_registry');
    
    // widget implementation
    var BoldWidget = basic_fields.FieldChar.extend({
        _renderReadonly: function () {
            this._super();
            var old_html_render = this.$el.html();
            var new_html_render = '<b style="color:red;">' + old_html_render + '</b>'
            this.$el.html(new_html_render);
        },
    });
    
    registry.add('bold_red', BoldWidget); // add our "bold" widget to the widget registry
});

Giải thích đoạn code wiget trên:

  • Khai báo gói mypet.bold bằng odoo.define. Tên gói của chúng ta sau có thể kế thừa hay mở rộng bằng cách lệnh require().
  • "Import" basic_fields, nơi hiện thực widget FieldChar, ta sắp sửa thừa kế để hiệu chỉnh nó.
  • Override hàm _renderReadonly() để render text in đậm màu đỏ, bạn có thể thấy thao tác code js, html (nghề của frontend developer) rất rõ ở đây.
  • Cuối cùng ta phải khai báo widget này vào registry.

Lưu ý: trong quá trình dev widget cho Odoo, để có tác dụng mình cần phải Upgrade module. Trong quá trình dev js, Minh còn thường dùng console.log() để in ấn giá trị, cũng như check xem code mới có được áp dụng chưa.

Sử dụng widget trong view của Odoo

Sau khi hiện thực tá lả hột dưa, bug tùm lum lên xuống ở file js rôi. Sắp đến thời điểm hưởng thành quả, ta vào view xml nên mà field trong form view muốn sử dụng và thêm widget="bold_red". Tên bold_red là tên ta dùng đăng ký widget ở registry.

mypet/views/my_pet_views.xml

...
    <field name="basic_price" widget="bold_red"/>
...
    <field name="nickname" widget="bold_red"/>
...

Mình áp dụng widget đậm đỏ cho 2 field trong form pet là giá và nickname. Upgrade addon my_pet và xem kết quả:

custom widget bold text

Download Odoo Widget - Tut 11

Source code download: Tut 11: Widget in Odoo


minhng.info dự định sẽ mở khóa học training lập trình Odoo OFFLINE ở TP. HCM, nếu bạn nào có nhu cầu giúp mình tham gia khảo sát nhé.

https://forms.gle/K9t2kjx5SCQWftkm8

Cài đặt Odoo:

Danh sách bài viết series Odoo:

Tham gia ngay group trên Facebook để cùng thảo luận với đồng bọn nhé: