不多说先上源码。

 1 odoo.define('my_company_users_widget', function (require) {
2 "use strict";
3
4 var AbstractField = require('web.AbstractField');
5 var fieldRegistry = require('web.field_registry');
6
7 var core = require('web.core');
8 var qweb = core.qweb;
9
10 var FieldCompanyUser = AbstractField.extend({
11 className: 'o_kanban_view',//当前控件使用的是哪个scss类。这个类里边包含了你所有使用到的样式。这样的好处是,你编写的小部件可移植变强
12 tagName: 'div',//设置你的根元素
13 supportedFieldTypes: ['many2many'],//设置你的小部件可以用在什么字段上。
14 events: {//这是事件。当点击了这个class元素的时候触发clickCard
15 'click .oe_kanban_global_click': 'clickCard',
16 },
17 init: function () {//初始化
18 this._super.apply(this, arguments);
19 },
20 _getImageURL: function (model, field, id, placeholder) {//这个方法是用生成访问图片的url
21 id = (_.isArray(id) ? id[0] : id) || null;
22 var isCurrentRecord = this.modelName === model && this.recordData.id === id;
23 var url;
24 if (isCurrentRecord && this.record[field] && this.record[field].raw_value && !utils.is_bin_size(this.record[field].raw_value)) {
25 // Use magic-word technique for detecting image type
26 url = 'data:image/' + this.file_type_magic_word[this.record[field].raw_value[0]] + ';base64,' + this.record[field].raw_value;
27 } else if (placeholder && (!model || !field || !id || (isCurrentRecord && this.record[field] && !this.record[field].raw_value))) {
28 url = placeholder;
29 } else {
30 var session = this.getSession();
31 var params = {
32 model: model,
33 field: field,
34 id: id
35 };
36 if (isCurrentRecord) {
37 params.unique = this.record.__last_update && this.record.__last_update.value.replace(/[^0-9]/g, '');
38 }
39 url = session.url('/web/image', params);
40 }
41 return url;
42 },
43 willStart: function () {//这里准备好你的数据
44 var self = this;
45 this.data_users = [];
46
47 var DataPromise = this._rpc({//调用model方法
48 model: 'res.groups',
49 method: 'get_company_users',
50 args: [[self.record.res_id],self.record.res_id]
51 }).then(function (result){
52 var i = 0;
53 for (i=0;i<result.length;i++){
54 result[i].image_url = self._getImageURL('res.users', 'image_128', result[i].id, '');
55 console.log(result[i].image_url);
56 };
57 self.data_users = result
58 console.log('result');
59 console.log(result);
60 });
61
62 return Promise.all([this._super.apply(this, arguments), DataPromise]);
63 },
64
65 _renderEdit: function () {
66 this.$el.empty();//这是编辑的时候显示内容。这里我将它置空了。所以在编辑的时候该控件直接不见了
67 },
68
69 _renderReadonly: function () {
70 this.$el.empty();//先置空控件内容。
71 var CompanyUsers = qweb.render('OWLFieldCompanyUsers', {widget: this});
72 this.$el.append(CompanyUsers);//重新添加控件内容
73
74 },
75 clickCard: function (ev) {//事件
76 var $target = $(ev.currentTarget);
77 var data = $target.data();
78 self = this;
79 this._rpc({
80 model: 'res.users',
81 method: 'get_userform_action',
82 args: [[data.val]]
83 }).then(function (result){
84 self.do_action(result);
85 });
86 }
87
88 });
89
90 fieldRegistry.add('company_users', FieldCompanyUser);//别忘记了注册你的widget
91
92 return {//最后公开你的小部件让其他视图可以使用
93 FieldCompanyUser: FieldCompanyUser,
94 };
95 });
 1 <?xml version="1.0" encoding="UTF-8"?>
2 <templates>
3 <t t-name="OWLFieldCompanyUsers" >
4
5 <div class="o_kanban_view o_kanban_mobile o_kanban_ungrouped">
6 <t t-foreach="widget.data_users" t-as="record">
7 <div t-attf-class="oe_kanban_global_click o_kanban_record" t-att-data-val="record.id">
8 <div class="o_kanban_image">
9 <img alt="Avatar" t-att-src="record.image_url"/>
10 </div>
11 <div class="oe_kanban_details">
12 <ul>
13 <li class="text-success float-right mb4" t-if="record.active"><i class="fa fa-circle" role="img" aria-label="Ok" title="Ok"/></li>
14 <li class="text-danger float-right mb4" t-if="!record.active"><i class="fa fa-circle" role="img" aria-label="Invalid" title="Invalid"/></li>
15 <li class="mb4">
16 <strong><t t-esc="record.name"/></strong>
17 </li>
18 <li class="badge badge-pill float-right mb4" t-if="record.lang"><t t-esc="record.lang"/></li>
19 <li class="mb4" t-if="record.login" title="Login"><i class="fa fa-envelope" role="img" aria-label="Login"/> <t t-esc="record.login"/></li>
20 </ul>
21 </div>
22 </div>
23 </t>
24 </div>
25 </t>
26
27 </templates>
1     <template id="assets_end" inherit_id="web.assets_backend">
2 <xpath expr="." position="inside">
3 <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/kanban_view.scss"/>
4 <script src="/ship_manage/static/src/js/field_widget.js" type="text/javascript" />
5 </xpath>
6 </template>
o_kanban_view样式类在kanban_view.xml文件中

Odoo14 自定义widget小部件的更多相关文章

  1. Android简易实战教程--第十四话《模仿金山助手创建桌面Widget小部件》

    打开谷歌api,对widget小部件做如下说明: App Widgets are miniature application views that can be embedded in otherap ...

  2. 从Hello World说起(Dart)到“几乎所有东西都是Widget”小部件。

    import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends S ...

  3. Android Widget 小部件(一) 简单实现

    在屏幕上加入Widget:或长按屏幕空白处,或找到WidgetPreview App选择. 原生系统4.0下面使用长按方式,4.0及以上 打开WIDGETS 创建Widget的一般步骤: 在menif ...

  4. Android Widget 小部件(四---完结) 使用ListView、GridView、StackView、ViewFlipper展示Widget

    官方有话这样说: A RemoteViews object (and, consequently, an App Widget) can support the following layout cl ...

  5. django中widget小部件

    1. 处理 input 的部件 TextInput    NumberInput EmailInput URLInput PasswordInput HiddenInput DateInput Dat ...

  6. iOS - Widget 小部件

    1.Widget iOS extension 的出现,方便了用户查看应用的服务,比如用户可以在 Today 的 widgets 中查看应用的简略信息,然后点击进入相关的应用界面. 2.添加 Widge ...

  7. Android Widget 小部件(三) 在Activity中加入Widget

    package com.stone.ui; import static android.util.Log.d; import android.app.Activity; import android. ...

  8. Web UI开发推荐!Kendo UI for jQuery自定义小部件——使用MVVM

    Kendo UI for jQuery最新试用版下载 Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support f ...

  9. Web UI开发推荐!Kendo UI for jQuery自定义小部件——处理事件

    Kendo UI for jQuery最新试用版下载 Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support f ...

随机推荐

  1. 玩转ASP.NET 6.0框架-序言

    ASP.NET Core是微软提供的强大的web框架,它有很多潜在的强大而有用的功能. 本专栏的目标是帮助您把框架的隐藏能力最大限度地发挥出来,让您能够按需定制ASP NET Core框架.本专栏提供 ...

  2. SM3和Blake

    在此给出SM3和Blake的对比 哈希函数 哈希算法 (Hash Algorithm) 是将任意长度的数据映射为固定长度数据的算法,也称为消息摘要.一般情况下,哈希算法有两个特点, 一是原始数据的细微 ...

  3. 学习Java的第十七天——大数字运算

    学习内容:大数字运算 代码实现: package 数字处理类; import java.math.BigInteger; public class BigIntegerDemo { public st ...

  4. 每天一个 HTTP 状态码 102

    102 Processing 102 Processing 是用于 WebDAV协议 请求的状态码. 这个状态码表示服务器已经收到了客户端的请求,正在处理,但暂时还没有可接触的响应.可以用于防止客户端 ...

  5. HMS Core AR Engine 2D图片/3D物体跟踪技术 助力打造更智能AR交互体验

    AR技术已经被广泛应用于营销.教育.游戏.展览等场景.通过2D图像跟踪技术和3D物体跟踪技术,用户只需使用一台手机进行拍摄,即可实现海报.卡牌等平面物体以及文物.手办等立体物体的AR效果.尽管近年来2 ...

  6. 面试官:Dubbo是什么,他有什么特性?

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,今天还是过周末,虽然 ...

  7. SQL年龄计算方法

    第一种方法: 用DATEDIFF函数,DATEDIFF(YEAR,beginDate,endDate). 测试语句: 1 DECLARE @birthdayDate DATE 2 DECLARE @e ...

  8. java基础题(5)

    6.常用API 6.1string类 1.动态字符串 描述 将一个由英文字母组成的字符串转换成从末尾开始每三个字母用逗号分隔的形式. 输入描述: 一个字符串 输出描述: 修改后的字符串 示例1 输入: ...

  9. JAVA - 线程同步和线程调度的相关方法

    JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...

  10. 多路分支、for循环

    多路分支 多路分支也叫做switch语句,它的格式: switch (控制表达式){ case 条件: 输出....} switch 可以看成一种跳转,每当我们满足跳转就会跳转到响应的位置,接下我们写 ...