如何在Odoo 14 CE中使用image map?现有实现方案失效求助
在Odoo 14 CE中实现图片映射(Image Map)的问题
尝试在Odoo 14 CE中使用图片映射,现有概念验证代码无法正常工作:图片未实现映射,客户端页面的<img>标签也没有usermap="#workmap"属性。
原代码如下:
<field name="image_parts" widget="image" usemap="#workmap"/> <map name="workmap"> <area shape="rect" coords="34,44,270,350" alt="Computer" href="computer.htm"/> <area shape="rect" coords="290,172,333,250" alt="Phone" href="phone.htm"/> <area shape="circle" coords="337,300,44" alt="Coffee" href="coffee.htm"/> </map>
需求是:显示自定义字段image_parts中的图片,支持hover时弹出信息对话框,点击区域触发后续操作。
可行解决方案
方案1:自定义图片Widget扩展原生image widget
Odoo原生的image widget不会处理usermap属性,需要自定义widget来添加该属性:
- 创建自定义Widget
在模块的static/src/js目录下创建image_map_widget.js:
odoo.define('your_module_name.image_map_widget', function (require) { "use strict"; var fieldRegistry = require('web.field_registry'); var ImageWidget = require('web.basic_fields').Image; var ImageMapWidget = ImageWidget.extend({ _render: function () { this._super.apply(this, arguments); var usemap = this.nodeOptions.usemap; if (usemap) { this.$el.find('img').attr('usemap', usemap); } }, }); fieldRegistry.add('image_map', ImageMapWidget); return ImageMapWidget; });
- 注册Widget
在模块的views/assets.xml中添加资源引用:
<odoo> <data> <template id="assets_backend" name="image map assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <script type="text/javascript" src="/your_module_name/static/src/js/image_map_widget.js"/> </xpath> </template> </data> </odoo>
- 在视图中使用自定义Widget
修改原视图代码,使用自定义的image_mapwidget:
<field name="image_parts" widget="image_map" options='{"usemap": "#workmap"}'/> <map name="workmap"> <area shape="rect" coords="34,44,270,350" alt="Computer" title="这是电脑区域" onclick="alert('点击了电脑区域')"/> <area shape="rect" coords="290,172,333,250" alt="Phone" title="这是手机区域" onclick="alert('点击了手机区域')"/> <area shape="circle" coords="337,300,44" alt="Coffee" title="这是咖啡区域" onclick="alert('点击了咖啡区域')"/> </map>
title属性可实现hover时弹出默认提示框onclick可绑定自定义JS逻辑,比如触发Odoo动作、打开表单等
方案2:直接用HTML字段渲染带映射的图片
如果不需要Odoo image字段的特性,可直接用html字段渲染完整的图片映射代码:
- 在模型中添加HTML字段
from odoo import fields, models class YourModel(models.Model): _name = 'your.model.name' _description = 'Your Model' image_parts = fields.Binary(string="图片") image_map_html = fields.Html(string="带映射的图片", compute='_compute_image_map_html') def _compute_image_map_html(self): for record in self: if not record.image_parts: record.image_map_html = "" continue # 生成图片URL image_url = f"/web/image?model={self._name}&field=image_parts&id={record.id}" # 拼接图片映射HTML html_content = f''' <img src="{image_url}" usemap="#workmap_{record.id}" style="max-width:100%;"/> <map name="workmap_{record.id}"> <area shape="rect" coords="34,44,270,350" alt="Computer" title="电脑区域" onclick="odoo.do_action('your_module_name.your_action_id')"/> <area shape="rect" coords="290,172,333,250" alt="Phone" title="手机区域" onclick="odoo.do_action('your_module_name.another_action_id')"/> <area shape="circle" coords="337,300,44" alt="Coffee" title="咖啡区域" onclick="alert('咖啡区域被点击')"/> </map> ''' record.image_map_html = html_content
注意:workmap名称要加上记录ID,避免多条记录时映射冲突。
- 在视图中添加HTML字段
<field name="image_map_html" widget="html"/>
自定义hover对话框(可选)
如果默认title提示不够,可通过JS实现自定义弹窗:
在Widget的JS文件中添加hover事件监听:
// 在ImageMapWidget的_render方法中添加 this.$el.find('area').hover(function(e) { // 自定义弹窗逻辑 var tooltip = $('<div class="custom-tooltip"></div>').text($(this).attr('data-info')); tooltip.css({ position: 'absolute', top: e.pageY + 10, left: e.pageX + 10, background: '#333', color: '#fff', padding: '5px 10px', borderRadius: '4px', zIndex: 9999 }); $('body').append(tooltip); }, function() { $('.custom-tooltip').remove(); });
然后在area标签中添加data-info属性:
<area shape="rect" coords="34,44,270,350" alt="Computer" data-info="这是电脑区域,点击可查看详情" onclick="..."/>
内容的提问来源于stack exchange,提问作者holydragon
相关产品推荐
相关产品推荐

