fields
forms
many2 Many Tags Avatar Field
Odoo 19 fields — many2 Many Tags Avatar Field (views)
Live preview
Interactive
Source excerpt
web/static/src/views/fields/many2many_tags_avatar/many2many_tags_avatar_field.js
import { _t } from "@web/core/l10n/translation";
import { usePopover } from "@web/core/popover/popover_hook";
import { registry } from "@web/core/registry";
import {
many2ManyTagsField,
Many2ManyTagsField,
} from "@web/views/fields/many2many_tags/many2many_tags_field";
import { TagsList } from "@web/core/tags_list/tags_list";
import { imageUrl } from "@web/core/utils/urls";
export class Many2ManyTagsAvatarField extends Many2ManyTagsField {
static template = "web.Many2ManyTagsAvatarField";
static optionTemplate = "web.Many2ManyTagsAvatarField.option";
static props = {
...Many2ManyTagsField.props,
withCommand: { type: Boolean, optional: true },
};
get specification() {
return {};
}
getTagProps(record) {
return {
...super.getTagProps(record),
img: imageUrl(this.relation, record.resId, "avatar_128"),
};
}
}
export const many2ManyTagsAvatarField = {
...many2ManyTagsField,
component: Many2ManyTagsAvatarField,
extractProps({ viewType }, dynamicInfo) {
const props = many2ManyTagsField.extractProps(...arguments);
props.withCommand = viewType === "form" || viewType === "list";
props.domain = dynamicInfo.domain;
return props;
},
};
registry.category("fields").add("many2many_tags_avatar", many2ManyTagsAvatarField);
export class ListMany2ManyTagsAvatarField extends Many2ManyTagsAvatarField {
visibleItemsLimit = 5;
}
export const listMany2ManyTagsAvatarField = {
...many2ManyTagsAvatarField,
component: ListMany2ManyTagsAvatarField,
};
registry.category("fields").add("list.many2many_tags_avatar", listMany2ManyTagsAvatarField);
export class Many2ManyTagsAvatarFieldPopover extends Many2ManyTagsAvatarField {
static template = "web.Many2ManyTagsAvatarFieldPopover";
static props = {
...Many2ManyTagsAvatarField.props,
close: { type: Function },
};
setup() {
super.setup();
const originalUpdate = this.update;
this.update = async (recordList) => {
await originalUpdate(recordList);
await this._saveUpdate();
};
}
async deleteTag(id) {
await super.deleteTag(id);
await this._saveUpdate();
}
async _saveUpdate() {
await this.props.record.save({ reload: false });
// manual render to dirty record
this.render();
// update dropdown
this.autoCompleteRef.el?.querySelector("input")?.click();
}
get tags() {
return super.tags.reverse();
}
}
export const many2ManyTagsAvatarFieldPopover = {
...many2ManyTagsAvatarField,
component: Many2ManyTagsAvatarFieldPopover,
};
registry.category("fields").add("many2many_tags_avatar_popover", many2ManyTagsAvatarFieldPopover);
export class KanbanMany2ManyTagsAvatarFieldTagsList extends TagsList {
static template = "web.KanbanMany2ManyTagsAvatarFieldTagsList";
static props = {
...TagsList.props,
popoverProps: { type: Object },
readonly: { type: Boolean, optional: true },
};
setup() {
super.setup();
this.popover = usePopover(Many2ManyTagsAvatarFieldPopover, {
popoverClass: "o_m2m_tags_avatar_field_popover",
closeOnClickAway: (target) => !target.closest(".modal"),
});
}
openPopover(ev) {
if (this.props.readonly) {
return;
}
this.popover.open(ev.currentTarget.parentElement, {
...this.props.popoverProps,
readonly: false,
canCreate: false,
canCreateEdit: false,
canQuickCreate: false,
Registry / API
- Registry name
many2ManyTagsAvatarField- Category
fields- Module
web- Slug
many2-many-tags-avatar-field- Nav group
forms