summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/fields
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js/fields')
-rw-r--r--addons/web/static/src/js/fields/abstract_field.js2
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js105
-rw-r--r--addons/web/static/src/js/fields/field_registry.js2
-rw-r--r--addons/web/static/src/js/fields/field_utils.js19
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js37
5 files changed, 84 insertions, 81 deletions
diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js
index 4948a3e3c31..dd2caaa5dd1 100644
--- a/addons/web/static/src/js/fields/abstract_field.js
+++ b/addons/web/static/src/js/fields/abstract_field.js
@@ -34,7 +34,6 @@ var field_utils = require('web.field_utils');
var Widget = require('web.Widget');
var AbstractField = Widget.extend({
- className: 'o_field_widget',
events: {
'keydown': '_onKeydown',
},
@@ -151,6 +150,7 @@ var AbstractField = Widget.extend({
var self = this;
return this._super.apply(this, arguments).then(function () {
self.$el.attr('name', self.name);
+ self.$el.addClass('o_field_widget');
return self._render();
});
},
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index e600954b967..7b48574fb44 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -184,7 +184,7 @@ var InputField = DebouncedField.extend({
*/
_prepareInput: function ($input) {
this.$input = $input || $("<input/>");
- this.$input.addClass('o_form_input');
+ this.$input.addClass('o_input');
this.$input.attr({
type: 'text',
placeholder: this.attrs.placeholder || "",
@@ -261,12 +261,13 @@ var InputField = DebouncedField.extend({
});
var FieldChar = InputField.extend({
- supportedFieldTypes: ['char'],
+ className: 'o_field_char',
tagName: 'span',
+ supportedFieldTypes: ['char'],
});
var FieldDate = InputField.extend({
- className: "o_form_field_date",
+ className: "o_field_date",
tagName: "span",
supportedFieldTypes: ['date'],
@@ -411,7 +412,8 @@ var FieldDateTime = FieldDate.extend({
});
var FieldMonetary = InputField.extend({
- className: 'o_form_field_monetary o_list_number',
+ className: 'o_field_monetary o_field_number',
+ tagName: 'span',
supportedFieldTypes: ['float', 'monetary'],
resetOnAnyFieldChange: true, // Have to listen to currency changes
@@ -436,6 +438,7 @@ var FieldMonetary = InputField.extend({
if (this.mode === 'edit' && this.currency) {
this.tagName = 'div';
+ this.className += ' o_input';
}
},
@@ -554,28 +557,18 @@ var FieldBoolean = AbstractField.extend({
/**
* The actual checkbox is designed in css to have full control over its
* appearance, as opposed to letting the browser and the os decide how
- * a checkbox should look. The actual input is disabled and hidden.
+ * a checkbox should look. The actual input is disabled and hidden. In
+ * readonly mode, the checkbox is disabled.
*
* @override
* @private
*/
- _renderReadonly: function () {
+ _render: function () {
var $checkbox = this._formatValue(this.value);
this.$input = $checkbox.find('input');
- this.$el.empty().append($checkbox);
- },
-
- /**
- * The actual checkbox is designed in css to have full control over its
- * appearance, as opposed to letting the browser and the os decide how
- * a checkbox should look. The actual input is hidden.
- *
- * @override
- * @private
- */
- _renderEdit: function () {
- this._renderReadonly();
- this.$input.prop('disabled', false);
+ this.$input.prop('disabled', this.mode === 'readonly');
+ this.$el.addClass($checkbox.attr('class'));
+ this.$el.empty().append($checkbox.contents());
},
//--------------------------------------------------------------------------
@@ -591,7 +584,6 @@ var FieldBoolean = AbstractField.extend({
_onChange: function () {
this._setValue(this.$input[0].checked);
},
-
/**
* Implement keyboard movements. Mostly useful for its environment, such
* as a list view.
@@ -624,6 +616,8 @@ var FieldBoolean = AbstractField.extend({
});
var FieldInteger = InputField.extend({
+ className: 'o_field_integer o_field_number',
+ tagName: 'span',
supportedFieldTypes: ['integer'],
//--------------------------------------------------------------------------
@@ -669,6 +663,8 @@ var FieldInteger = InputField.extend({
});
var FieldFloat = InputField.extend({
+ className: 'o_field_float o_field_number',
+ tagName: 'span',
supportedFieldTypes: ['float'],
/**
@@ -696,22 +692,6 @@ var FieldFloat = InputField.extend({
isSet: function () {
return this.value === 0 || this._super.apply(this, arguments);
},
-
- //--------------------------------------------------------------------------
- // Private
- //--------------------------------------------------------------------------
-
- /**
- * Format value according to precision parameter.
- *
- * @override
- * @private
- */
- _renderReadonly: function () {
- var value = this._formatValue(this.value);
- var $span = $('<span>').addClass('o_form_field o_form_field_number').text(value);
- this.$el.html($span);
- },
});
var FieldFloatTime = FieldFloat.extend({
@@ -743,21 +723,28 @@ var FieldFloatTime = FieldFloat.extend({
});
var FieldText = DebouncedField.extend({
+ className: 'o_field_text',
supportedFieldTypes: ['text'],
/**
- * In edit mode, the text widget contains a textarea. We append it in
- * start() instead of _renderEdit() to keep the same textarea even
- * if several _renderEdit are done. This allows to keep the cursor
- * position and to autoresize only once.
+ * @constructor
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+
+ if (this.mode === 'edit') {
+ this.tagName = 'textarea';
+ this.className += ' o_input';
+ }
+ },
+ /**
+ * As it it done in the start function, the autoresize is done only once.
*
* @override
*/
start: function () {
- this.$el.addClass('o_list_text o_form_textarea');
-
if (this.mode === 'edit') {
- this.$textarea = $('<textarea>').appendTo(this.$el);
+ this.$textarea = this.$el;
if (this.attrs.placeholder) {
this.$textarea.attr('placeholder', this.attrs.placeholder);
}
@@ -816,13 +803,14 @@ var FieldText = DebouncedField.extend({
* Displays a handle to modify the sequence.
*/
var HandleWidget = AbstractField.extend({
- tagName: 'span',
className: 'o_row_handle fa fa-arrows ui-sortable-handle',
+ tagName: 'span',
description: "",
supportedFieldTypes: ['integer'],
});
-var EmailWidget = InputField.extend({
+var FieldEmail = InputField.extend({
+ className: 'o_field_email',
prefix: 'mailto',
supportedFieldTypes: ['char'],
@@ -853,7 +841,8 @@ var EmailWidget = InputField.extend({
}
});
-var FieldPhone = EmailWidget.extend({
+var FieldPhone = FieldEmail.extend({
+ className: 'o_field_phone',
prefix: 'tel',
/**
@@ -907,6 +896,7 @@ var FieldPhone = EmailWidget.extend({
});
var UrlWidget = InputField.extend({
+ className: 'o_field_url',
supportedFieldTypes: ['char'],
/**
@@ -939,9 +929,9 @@ var UrlWidget = InputField.extend({
var AbstractFieldBinary = AbstractField.extend({
events: _.extend({}, AbstractField.prototype.events, {
- 'change .o_form_input_file': 'on_file_change',
+ 'change .o_input_file': 'on_file_change',
'click .o_select_file_button': function () {
- this.$('.o_form_input_file').click();
+ this.$('.o_input_file').click();
},
'click .o_clear_file_button': 'on_clear',
}),
@@ -1084,8 +1074,8 @@ var FieldBinaryFile = AbstractFieldBinary.extend({
this.on_save_as(event);
}
},
- 'click .o_form_input': function () { // eq[0]
- this.$('.o_form_input_file').click();
+ 'click .o_input': function () { // eq[0]
+ this.$('.o_input_file').click();
},
}),
supportedFieldTypes: ['binary'],
@@ -1106,7 +1096,7 @@ var FieldBinaryFile = AbstractFieldBinary.extend({
if (this.value) {
this.$el.children().removeClass('o_hidden');
this.$('.o_select_file_button').first().addClass('o_hidden');
- this.$('.o_form_input').eq(0).val(this.filename_value || this.value);
+ this.$('.o_input').eq(0).val(this.filename_value || this.value);
} else {
this.$el.children().addClass('o_hidden');
this.$('.o_select_file_button').first().removeClass('o_hidden');
@@ -1727,8 +1717,8 @@ var FieldToggleBoolean = AbstractField.extend({
* @private
*/
_render: function () {
- var class_name = this.value ? 'o_toggle_button_success' : 'text-muted';
- this.$('i').attr('class', ('fa fa-circle ' + class_name));
+ var className = this.value ? 'o_toggle_button_success' : 'text-muted';
+ this.$('i').addClass('fa fa-circle ' + className);
var title = this.value ? this.attrs.options.active : this.attrs.options.inactive;
this.$el.attr('title', title);
},
@@ -1747,7 +1737,6 @@ var FieldToggleBoolean = AbstractField.extend({
event.stopPropagation();
this._setValue(!this.value);
},
-
});
var JournalDashboardGraph = AbstractField.extend({
@@ -1891,7 +1880,7 @@ var FieldDomain = AbstractField.extend({
events: _.extend({}, AbstractField.prototype.events, {
"click .o_domain_show_selection_button": "_onShowSelectionButtonClick",
- "click .o_form_field_domain_dialog_button": "_onDialogEditButtonClick",
+ "click .o_field_domain_dialog_button": "_onDialogEditButtonClick",
}),
custom_events: {
"domain_changed": "_onDomainSelectorValueChange",
@@ -1907,7 +1896,7 @@ var FieldDomain = AbstractField.extend({
this.inDialog = !!this.nodeOptions.in_dialog;
this.fsFilters = this.nodeOptions.fs_filters || {};
- this.className = "o_form_field_domain";
+ this.className = "o_field_domain";
if (this.mode === "edit") {
this.className += " o_edit_mode";
}
@@ -2190,7 +2179,7 @@ var AceEditor = DebouncedField.extend({
return {
DebouncedField: DebouncedField,
- EmailWidget: EmailWidget,
+ FieldEmail: FieldEmail,
FieldBinaryFile: FieldBinaryFile,
FieldBinaryImage: FieldBinaryImage,
FieldBoolean: FieldBoolean,
diff --git a/addons/web/static/src/js/fields/field_registry.js b/addons/web/static/src/js/fields/field_registry.js
index 41889fcfa85..dcd8f7acd48 100644
--- a/addons/web/static/src/js/fields/field_registry.js
+++ b/addons/web/static/src/js/fields/field_registry.js
@@ -29,7 +29,7 @@ registry
.add('float', basic_fields.FieldFloat)
.add('char', basic_fields.FieldChar)
.add('handle', basic_fields.HandleWidget)
- .add('email', basic_fields.EmailWidget)
+ .add('email', basic_fields.FieldEmail)
.add('phone', basic_fields.FieldPhone)
.add('url', basic_fields.UrlWidget)
.add('image', basic_fields.FieldBinaryImage)
diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js
index afc15b7a882..508d97b131c 100644
--- a/addons/web/static/src/js/fields/field_utils.js
+++ b/addons/web/static/src/js/fields/field_utils.js
@@ -35,13 +35,16 @@ var _t = core._t;
* @returns {jQueryElement}
*/
function formatBoolean(value) {
- var $input = $('<input type="checkbox">')
- .prop('checked', value)
- .prop('disabled', true);
- return $('<div>')
- .addClass('o_checkbox')
- .append($input)
- .append($('<span>'));
+ var $input = $('<input/>', {
+ type: 'checkbox',
+ }).prop({
+ checked: value,
+ disabled: true,
+ });
+ var $div = $('<div/>', {
+ class: 'o_checkbox',
+ });
+ return $div.append($input, '<span/>');
}
/**
@@ -342,7 +345,7 @@ function parseDateTime(value, field, options) {
var pattern2 = datePatternWoZero + ' ' + timePatternWoZero;
var datetime;
if (options && options.isUTC) {
- // phatomjs crash if we don't use this format
+ // phatomjs crash if we don't use this format
datetime = moment.utc(value.replace(' ', 'T') + 'Z');
} else {
datetime = moment.utc(value, [pattern1, pattern2, moment.ISO_8601], true);
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 28d790b16c4..d7e65f5c4bf 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -81,9 +81,9 @@ var FieldMany2One = AbstractField.extend({
'search_create_popup': '_onSearchCreatePopup',
},
events: _.extend({}, AbstractField.prototype.events, {
- 'click .o_form_input': '_onInputClick',
- 'focusout .o_form_input': '_onInputFocusout',
- 'keyup .o_form_input': '_onInputKeyup',
+ 'click input': '_onInputClick',
+ 'focusout input': '_onInputFocusout',
+ 'keyup input': '_onInputKeyup',
'click .o_external_button': '_onExternalButtonClick',
'click': '_onClick',
}),
@@ -106,7 +106,7 @@ var FieldMany2One = AbstractField.extend({
// what is 'this.floating' for? add a comment!
this.floating = false;
- this.$input = this.$('.o_form_input');
+ this.$input = this.$('input');
this.$external_button = this.$('.o_external_button');
return this._super.apply(this, arguments);
},
@@ -713,7 +713,7 @@ var FieldX2Many = AbstractField.extend({
onFailure: def.reject.bind(def),
});
} else {
- self.renderer.setRowMode(recordID, 'readonly', true);
+ self.renderer.setRowMode(recordID, 'readonly');
def.resolve();
}
});
@@ -819,7 +819,7 @@ var FieldX2Many = AbstractField.extend({
});
var FieldOne2Many = FieldX2Many.extend({
- className: 'o_form_field_one2many',
+ className: 'o_field_one2many',
supportedFieldTypes: ['one2many'],
//--------------------------------------------------------------------------
@@ -937,7 +937,7 @@ var FieldOne2Many = FieldX2Many.extend({
});
var FieldMany2Many = FieldX2Many.extend({
- className: 'o_form_field_many2many',
+ className: 'o_field_many2many',
supportedFieldTypes: ['many2many'],
/**
@@ -1019,7 +1019,7 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
events: {
'click .o_attach': '_onAttach',
'click .oe_delete': '_onDelete',
- 'change .o_form_input_file': '_onFileChanged',
+ 'change .o_input_file': '_onFileChanged',
},
/**
* @constructor
@@ -1102,7 +1102,7 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
_onAttach: function () {
// This widget uses a hidden form to upload files. Clicking on 'Attach'
// will simulate a click on the related input.
- this.$('.o_form_input_file').click();
+ this.$('.o_input_file').click();
},
/**
* @private
@@ -1196,7 +1196,7 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
var FieldMany2ManyTags = AbstractField.extend({
tag_template: "FieldMany2ManyTag",
- className: "o_form_field o_form_field_many2manytags",
+ className: "o_field_many2manytags",
supportedFieldTypes: ['many2many'],
custom_events: {
field_changed: '_onFieldChanged',
@@ -1204,13 +1204,24 @@ var FieldMany2ManyTags = AbstractField.extend({
},
events: _.extend({}, AbstractField.prototype.events, {
'click .o_delete': '_onDeleteTag',
- 'keydown .o_form_field_many2one input': '_onKeyDown',
+ 'keydown .o_field_many2one input': '_onKeyDown',
}),
fieldsToFetch: {
color: {type: 'integer'},
display_name: {type: 'char'},
},
+ /**
+ * @constructor
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+
+ if (this.mode === 'edit') {
+ this.className += ' o_input';
+ }
+ },
+
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
@@ -1310,7 +1321,7 @@ var FieldMany2ManyTags = AbstractField.extend({
this.many2one._getSearchBlacklist = function () {
return self.value.res_ids;
};
- this.many2one.appendTo(this.$el);
+ return this.many2one.appendTo(this.$el);
},
/**
* @private
@@ -1445,7 +1456,7 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({
var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({
_render: function () {
var self = this;
- this.$el.addClass('o_form_field_many2manytags o_kanban_tags');
+ this.$el.addClass('o_field_many2manytags o_kanban_tags');
_.each(this.value.data, function (m2m) {
// 10th color is invisible
if ('color' in m2m.data && m2m.data.color !== 10) {