this.mutating_mutex = new $.Mutex();
this.on_change_list = [];
this.save_list = [];
+ this.render_value_defs = [];
this.reload_mutex = new $.Mutex();
this.__clicked_inside = false;
this.__blur_timeout = null;
} else if (mode === "create") {
mode = "edit";
}
+ this.render_value_defs = [];
this.set({actual_mode: mode});
},
check_actual_mode: function(source, options) {
});
},
on_button_cancel: function(event) {
+ var self = this;
if (this.can_be_discarded()) {
if (this.get('actual_mode') === 'create') {
this.trigger('history_back');
} else {
this.to_view_mode();
- this.trigger('load_record', this.datarecord);
+ $.when.apply(null, this.render_value_defs).then(function(){
+ self.trigger('load_record', self.datarecord);
+ });
}
}
this.trigger('on_button_cancel');
instance.web.form.ReinitializeFieldMixin = _.extend({}, instance.web.form.ReinitializeWidgetMixin, {
reinitialize: function() {
instance.web.form.ReinitializeWidgetMixin.reinitialize.call(this);
- this.render_value();
+ var res = this.render_value();
+ if (this.view && this.view.render_value_defs){
+ this.view.render_value_defs.push(res);
+ }
},
});
type_of_date: "datetime",
events: {
'change .oe_datepicker_master': 'change_datetime',
+ 'keypress .oe_datepicker_master': 'change_datetime',
},
init: function(parent) {
this._super(parent);
format_client: function(v) {
return instance.web.format_value(v, {"widget": this.type_of_date});
},
- change_datetime: function() {
- if (this.is_valid_()) {
+ change_datetime: function(e) {
+ if ((e.type !== "keypress" || e.which === 13) && this.is_valid_()) {
this.set_value_from_ui_();
this.trigger("datetime_changed");
}
},
set_dimensions: function (height, width) {
this._super(height, width);
- this.datewidget.$input.css('height', height);
+ if (!this.get("effective_readonly")) {
+ this.datewidget.$input.css('height', height);
+ }
}
});
if (! this.get("effective_readonly")) {
self._updating_editor = false;
this.$textarea = this.$el.find('textarea');
- var width = ((this.node.attrs || {}).editor_width || '100%');
+ var width = ((this.node.attrs || {}).editor_width || 'calc(100% - 4px)');
var height = ((this.node.attrs || {}).editor_height || 250);
this.$textarea.cleditor({
width: width, // width not including margins, borders or padding
this.floating = false;
this.current_display = null;
this.is_started = false;
+ this.ignore_focusout = false;
},
reinit_value: function(val) {
this.internal_set_value(val);
var ed_delay = 200;
var ed_duration = 15000;
var anyoneLoosesFocus = function (e) {
+ if (self.ignore_focusout) { return; }
var used = false;
if (self.floating) {
if (self.last_search.length > 0) {
}
self.floating = false;
}
- if (used && self.get("value") === false && ! self.no_ed) {
+ if (used && self.get("value") === false && ! self.no_ed && ! (self.options && (self.options.no_create || self.options.no_quick_create))) {
self.ed_def.reject();
self.uned_def.reject();
self.ed_def = $.Deferred();
_search_create_popup: function() {
this.no_ed = true;
this.ed_def.reject();
- return instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments);
+ this.ignore_focusout = true;
+ this.reinit_value(false);
+ var res = instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments);
+ this.ignore_focusout = false;
+ this.no_ed = false;
+ return res;
},
set_dimensions: function (height, width) {
this._super(height, width);
- this.$input.css('height', height);
+ if (!this.get("effective_readonly") && this.$input)
+ this.$input.css('height', height);
}
});
this.o2m.trigger_on_change();
},
is_valid: function () {
- var editor = this.editor;
- var form = editor.form;
- // If no edition is pending, the listview can not be invalid (?)
- if (!editor.record) {
- return true;
- }
- // If the form has not been modified, the view can only be valid
- // NB: is_dirty will also be set on defaults/onchanges/whatever?
- // oe_form_dirty seems to only be set on actual user actions
- if (!form.$el.is('.oe_form_dirty')) {
+ var self = this;
+ if (!this.editable()){
return true;
}
this.o2m._dirty_flag = true;
-
- // Otherwise validate internal form
- return _(form.fields).chain()
- .invoke(function () {
- this._check_css_flags();
- return this.is_valid();
- })
- .all(_.identity)
- .value();
+ var r;
+ return _.every(this.records.records, function(record){
+ r = record;
+ _.each(self.editor.form.fields, function(field){
+ field.set_value(r.attributes[field.name]);
+ });
+ return _.every(self.editor.form.fields, function(field){
+ field.process_modifiers();
+ field._check_css_flags();
+ return field.is_valid();
+ });
+ });
},
do_add_record: function () {
if (this.editable()) {
else
return $.when();
}).done(function () {
- if (!self.o2m.options.reload_on_button) {
+ var ds = self.o2m.dataset;
+ var cached_records = _.any([ds.to_create, ds.to_delete, ds.to_write], function(value) {
+ return value.length;
+ });
+ if (!self.o2m.options.reload_on_button && !cached_records) {
self.handle_button(name, id, callback);
}else {
self.handle_button(name, id, function(){
self.render_tag(data);
}
if (! values || values.length > 0) {
- this._display_orderer.add(self.get_render_data(values)).done(handle_names);
- }
- else{
+ return this._display_orderer.add(self.get_render_data(values)).done(handle_names);
+ } else {
handle_names([]);
}
},
pop.select_element(
this.model,
{
- title: _t("Add: ") + this.m2m_field.string
+ title: _t("Add: ") + this.m2m_field.string,
+ no_create: this.m2m_field.options.no_create,
},
new instance.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]),
this.m2m_field.build_context()
this._super.apply(this, arguments);
this.render_value();
this.set_filename('');
+ },
+ set_value: function(value_){
+ var changed = value_ !== this.get_value();
+ this._super.apply(this, arguments);
+ // By default, on binary images read, the server returns the binary size
+ // This is possible that two images have the exact same size
+ // Therefore we trigger the change in case the image value hasn't changed
+ // So the image is re-rendered correctly
+ if (!changed){
+ this.trigger("change:value", this, {
+ oldValue: value_,
+ newValue: value_
+ });
+ }
}
});
* Options on attribute ; "blockui" {Boolean} block the UI or not
* during the file is uploading
*/
-instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractField.extend({
+instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
template: "FieldBinaryFileUploader",
init: function(field_manager, node) {
this._super(field_manager, node);
start: function() {
this._super(this);
this.$el.on('change', 'input.oe_form_binary_file', this.on_file_change );
+ this.on("change:effective_readonly", this, function () {
+ this.render_value();
+ });
},
set_value: function(value_) {
value_ = value_ || [];
},
render_value: function () {
var self = this;
+ this.$('.oe_add').css('visibility', this.get('effective_readonly') ? 'hidden': '');
this.read_name_values().then(function (ids) {
var render = $(instance.web.qweb.render('FieldBinaryFileUploader.files', {'widget': self, 'values': ids}));
render.on('click', '.oe_delete', _.bind(self.on_file_delete, self));