Một bảng danh sách dài mà mọi dòng đen sì như nhau thì mắt phải căng ra tìm cái quan trọng. Odoo có một cách để bảng tự làm nổi bật thứ cần chú ý: decoration-* — tô màu và đổi kiểu chữ từng dòng theo một biểu thức điều kiện. Ta đã gặp thoáng qua ở bài list view; bài này đi sâu vào cả bảng màu, cách ghép nhiều decoration, và cạm bẫy hay quên. Dựng thật một list với thẻ khoá đỏ, thẻ hết hạn cam, thẻ VIP xanh đậm.

Cú pháp: decoration-MÀU="biểu thức"

Mỗi thuộc tính decoration-<màu> nhận một biểu thức Python; dòng nào làm biểu thức đúng thì được tô màu/kiểu đó:

<list string="Thẻ thành viên" default_order="diem desc"
      decoration-success="diem >= 100"          <!-- XANH lá -->
      decoration-bf="diem >= 150"               <!-- IN ĐẬM -->
      decoration-warning="trang_thai == 'het_han'" <!-- CAM -->
      decoration-danger="trang_thai == 'khoa'"    <!-- ĐỎ -->
      decoration-muted="diem == 0">             <!-- XÁM mờ -->
  <field name="name"/>
  <field name="diem" sum="Tổng điểm"/>
  <field name="trang_thai"/>   <!-- field dùng trong biểu thức PHẢI có trong list -->
</list>

Ảnh chụp mã XML nền tối định nghĩa list với nhiều decoration, thẻ list có default_order diem desc, decoration-success cho diem lớn hơn hoặc bằng 100 tô xanh lá, decoration-bf cho diem lớn hơn hoặc bằng 150 in đậm, decoration-warning cho trang_thai bằng het_han tô cam, decoration-danger cho trang_thai bằng khoa tô đỏ, decoration-muted cho diem bằng 0 tô xám mờ, bên trong field name field diem có sum Tổng điểm và field trang_thai với chú thích field dùng trong biểu thức phải có trong list, phần cuối liệt kê bảng màu success xanh info lam warning cam danger đỏ muted xám bf đậm it nghiêng và ghi chú nhiều decoration cùng áp được

Hình 1: Năm decoration cùng khai trên một list. Mỗi cái là một cặp màu/kiểu + biểu thức. Biểu thức đọc field của dòng đang xét. Chú ý dòng cuối: trang_thai phải là một field trong list thì biểu thức mới đọc được nó — đây là cạm bẫy hay quên.

Xem thật: bốn dòng, bốn màu

Đặt bốn thẻ ở bốn trạng thái khác nhau và mở list:

Ảnh chụp giao diện list Odoo 19 bốn thẻ thành viên với màu khác nhau theo điều kiện, dòng VIP-0003 Vàng 150 điểm Đang dùng hiển thị màu xanh lá và in đậm vì đạt từ 150 điểm, dòng VIP-0001 Bạc 120 điểm Mới cấp màu xanh lá vì đạt từ 100 điểm, dòng VIP-0002 Bạc 85 điểm Hết hạn màu cam, dòng VIP-0004 Bạc 0 điểm Đã khoá màu đỏ, chân bảng cộng tổng điểm 355

Hình 2: Cùng list ở Hình 1, render thật. Mỗi dòng một màu theo đúng điều kiện: VIP-0003 (150đ) xanh đậm (success + bf cùng áp vì 150 ≥ 100 và ≥ 150); VIP-0001 (120đ) xanh; VIP-0002 (hết hạn) cam; VIP-0004 (đã khoá) đỏ. Nhìn màu là biết ngay dòng nào cần xử lý — không cần đọc cột trạng thái.

Điểm hay ở VIP-0003: hai decoration cùng áp (success cho màu xanh, bf cho in đậm) vì cả hai biểu thức đều đúng — cho ra "xanh đậm". Decoration ghép được với nhau.

Bảng màu decoration đầy đủ

decoration Kiểu Thường dùng cho
success Xanh lá Trạng thái tốt, hoàn tất, đạt ngưỡng
info Lam Thông tin, đang xử lý
warning Cam Cảnh báo, sắp hết hạn
danger Đỏ Lỗi, bị khoá, quá hạn
muted Xám mờ Không hoạt động, rỗng, đã lưu trữ
bf In đậm Nhấn mạnh (ghép với màu)
it Nghiêng Ghi chú, tạm

Các màu (success/info/warning/danger/muted) là màu chữ; bf/it là kiểu chữ — nên hay ghép một màu với bf để vừa tô vừa nhấn.

Cạm bẫy và lưu ý

  • Field trong biểu thức phải có trong list. Nếu decoration-danger="trang_thai == 'khoa'" mà cột trang_thai không được khai trong list, biểu thức không đọc được giá trị. Nếu không muốn hiện cột đó, thêm <field name="trang_thai" column_invisible="1"/> — ẩn cột nhưng vẫn nạp.
  • Nhiều decoration cùng đúng thì cùng áp, nhưng nếu hai màu chữ cùng đúng, cái sau (theo thứ tự ưu tiên CSS) thắng — nên tránh cho hai màu chồng nhau trên cùng dòng; thiết kế điều kiện loại trừ.
  • Biểu thức là Python trên field của dòng, dùng == != > < >= in not in and or not — giống invisible/readonly ở bài trước.
  • Decoration chỉ đổi hình thức, không lọc. Muốn ẩn dòng thì dùng domain của action/filter, không phải decoration.

Ba ý mang về

  1. decoration-<màu>="biểu thức" tô màu/kiểu từng dòng list theo điều kiện Python trên field của dòng — không cần JavaScript. Đã chứng minh: 4 thẻ ra 4 màu (xanh đậm / xanh / cam / đỏ) đúng điều kiện.
  2. Bảy giá trị: success (xanh), info (lam), warning (cam), danger (đỏ), muted (xám) là màu chữ; bf (đậm), it (nghiêng) là kiểu — ghép được (như success + bf = xanh đậm).
  3. Cạm bẫy: field dùng trong biểu thức decoration phải có trong list (dùng column_invisible="1" nếu không muốn hiện cột); decoration chỉ đổi hình thức, không lọc dòng.

Ta đã tô màu và điều khiển hiển thị field. Lần sau đi vào chính cái ô field: Phần sau mổ xẻ widget trên trường — chọn đúng widget (badge, monetary, progressbar, handle, priority...) để mỗi field vừa đẹp vừa đúng chức năng.