diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/js/fields/field_wrapper.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web/static/src/js/fields/field_wrapper.js')
| -rw-r--r-- | addons/web/static/src/js/fields/field_wrapper.js | 157 |
1 files changed, 157 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 00000000..ad32d046 --- /dev/null +++ b/addons/web/static/src/js/fields/field_wrapper.js @@ -0,0 +1,157 @@ +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.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 (let key in this._data) { + Object.defineProperty(this, key, { + get: () => { + if (this.el) { + if (key === 'dataPointID') { + return this.componentRef.comp.dataPointId; + } else if (key === 'res_id') { + return this.componentRef.comp.resId; + } + } + return (this.el ? this.componentRef.comp : this._data)[key]; + }, + }); + } + } + + /** + * Renderers set the '__node' attribute on fields they instantiate. It + * is used for instance to evaluate modifiers on multi-edition. In this + * case, the controller reads this property on the target of the event. + * However, with Owl field Components, it is set on the FieldWrapper, + * not the real field Component, which triggers the 'field-changed' + * event. This function writes the attribute on that field Component. + */ + mounted() { + super.mounted(...arguments); + this.componentRef.comp.__node = this.__node; + } + + //---------------------------------------------------------------------- + // Getters + //---------------------------------------------------------------------- + + get $el() { + return $(this.el); + } + get fieldDependencies() { + return this.Component.fieldDependencies; + } + 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() { + return this.componentRef.comp.activate(...arguments); + } + commitChanges() { + return this.componentRef.comp.commitChanges(...arguments); + } + 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 component 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; + } + removeInvalidClass() { + return this.componentRef.comp.removeInvalidClass(...arguments); + } + reset(record, event) { + return this.update({record, event}); + } + setIDForLabel() { + return this.componentRef.comp.setIdForLabel(...arguments); + } + setInvalidClass() { + return this.componentRef.comp.setInvalidClass(...arguments); + } + updateModifiersValue(modifiers) { + if (this.props.options.attrs) { + this.props.options.attrs.modifiersValue = modifiers || {}; + } else { + const viewType = this.props.options.viewType || 'default'; + const fieldsInfo = this.props.record.fieldsInfo[viewType]; + fieldsInfo[this.props.fieldName].modifiersValue = modifiers || {}; + } + this.componentRef.comp.props = this.props; + } + } + + return FieldWrapper; +}); |
