summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/fields/field_wrapper.js
diff options
context:
space:
mode:
authorMichael Mattiello (mcm) <mcm@odoo.com>2020-02-03 10:40:52 +0000
committeraab-odoo <aab@odoo.com>2020-02-03 11:08:04 +0000
commit3fd7b2009ec1f16c56c6d0ae87004011c90e204c (patch)
tree85f041055d81938c694263fe082f490d0f0e8446 /addons/web/static/src/js/fields/field_wrapper.js
parent6bdcf054fdeef1b02cbb20bdb00fcba648725f36 (diff)
[ADD] web: add owl AbstractField
This commit adds the new AbstractField class written in owl, meant to be extended by specific Field owl implementations. Note that its API is not complete yet, but it is enough for basic usecases. This commit also adapts the BasicRenderer to instantiate the future new fields that will be written in owl. closes odoo/odoo#43759 Related: odoo/enterprise#7872 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/fields/field_wrapper.js')
-rw-r--r--addons/web/static/src/js/fields/field_wrapper.js126
1 files changed, 126 insertions, 0 deletions
diff --git a/addons/web/static/src/js/fields/field_wrapper.js b/addons/web/static/src/js/fields/field_wrapper.js
new file mode 100644
index 00000000000..0b808d0c732
--- /dev/null
+++ b/addons/web/static/src/js/fields/field_wrapper.js
@@ -0,0 +1,126 @@
+odoo.define('web.FieldWrapper', function (require) {
+ "use strict";
+
+ const { ComponentWrapper } = require('web.OwlCompatibility');
+ const field_utils = require('web.field_utils');
+
+ /**
+ * This file defines the FieldWrapper component, an extension of ComponentWrapper,
+ * needed to instanciate Owl fields inside legacy widgets. This component
+ * will be no longer necessary as soon as all legacy widgets using fields will
+ * be rewritten in Owl.
+ */
+ class FieldWrapper extends ComponentWrapper {
+ constructor() {
+ super(...arguments);
+
+ this._data = {};
+
+ const options = this.props.options || {};
+ const record = this.props.record;
+ this._data.name = this.props.fieldName;
+ this._data.record = record;
+ this._data.field = record.fields[this._data.name];
+ this._data.viewType = options.viewType || 'default';
+ const fieldsInfo = record.fieldsInfo[this._data.viewType];
+ this._data.attrs = options.attrs || (fieldsInfo && fieldsInfo[this._data.name]) || {};
+ this._data.additionalContext = options.additionalContext || {};
+ this._data.value = record.data[this._data.name];
+ this._data.recordData = record.data;
+ this._data.string = this._data.attrs.string || this._data.field.string || this._data.name;
+ this._data.nodeOptions = this._data.attrs.options || {};
+ this._data.dataPointID = record.id;
+ this._data.res_id = record.res_id;
+ this._data.model = record.model;
+ this._data.mode = options.mode || "readonly";
+ this._data._isValid = true;
+ this._data.lastSetValue = undefined;
+ this._data.formatType = this._data.attrs.widget in field_utils.format ?
+ this._data.attrs.widget :
+ this._data.field.type;
+ this._data.formatOptions = {};
+ this._data.parseOptions = {};
+ if (this._data.attrs.decorations) {
+ this._data.resetOnAnyFieldChange = true;
+ }
+ for (const key in this._data) {
+ Object.defineProperty(this, key, {
+ get: () => (this.el ? this.componentRef.comp : this._data)[key],
+ });
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Getters
+ //----------------------------------------------------------------------
+
+ get $el() {
+ return $(this.el);
+ }
+ get fieldDependencies() {
+ return this.Component.fieldDependencies;
+ }
+ get resetOnAnyFieldChange() {
+ return this.Component.resetOnAnyFieldChange;
+ }
+ get specialData() {
+ return this.Component.specialData;
+ }
+ get supportedFieldTypes() {
+ return this.Component.supportedFieldTypes;
+ }
+ get description() {
+ return this.Component.description;
+ }
+ get noLabel() {
+ return this.Component.noLabel;
+ }
+
+ //----------------------------------------------------------------------
+ // Public
+ //----------------------------------------------------------------------
+
+ activate(options) {
+ return this.componentRef.comp.activate(options);
+ }
+ commitChanges() {
+ return this.componentRef.comp.commitChanges();
+ }
+ getFocusableElement() {
+ return $(this.componentRef.comp.focusableElement);
+ }
+ isEmpty() {
+ return this.componentRef.comp.isEmpty;
+ }
+ isFocusable() {
+ return this.componentRef.comp.isFocusable;
+ }
+ isSet() {
+ if (this.componentRef.comp) {
+ return this.componentRef.comp.isSet;
+ }
+ // because of the willStart, the real field widget may not be
+ // instantiated yet when the renderer first asks if it is set
+ // (only the wrapper is instantiated), so we instantiate one
+ // with the same props, get its 'isSet' status, and destroy it.
+ const c = new this.Component(null, this.props);
+ const isSet = c.isSet;
+ c.destroy();
+ return isSet;
+ }
+ isValid() {
+ return this.componentRef.comp.isValid;
+ }
+ reset(record, event) {
+ return this.update({record, event});
+ }
+ setIDForLabel(id) {
+ return this.componentRef.comp.setIDForLabel(id);
+ }
+ updateModifiersValue(modifiers) {
+ return this.componentRef.comp.updateModifiersValue(modifiers);
+ }
+ }
+
+ return FieldWrapper;
+});