X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fweb%2Fstatic%2Fsrc%2Fjs%2Fview_form.js;h=db75e1ef352792eea74f9f88d33963531a6b6d75;hb=8c4a7cb37143285da0a1a25d0d5e720c45e4346a;hp=599664d14def613aecc3f06d22cded67c4618633;hpb=bb89e548668b88a231a364d106a2cd6e57442ae6;p=odoo%2Fodoo.git diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 599664d..db75e1e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -119,6 +119,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM 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; @@ -631,6 +632,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM }); } return $.when(); + }).fail(function() { + self.save_list.pop(); + return $.when(); }); } return iterate(); @@ -694,6 +698,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } else if (mode === "create") { mode = "edit"; } + this.render_value_defs = []; this.set({actual_mode: mode}); }, check_actual_mode: function(source, options) { @@ -727,8 +732,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } } }, - on_button_save: function() { + on_button_save: function(e) { var self = this; + $(e.target).attr("disabled", true); return this.save().done(function(result) { self.trigger("save", result); self.reload().then(function() { @@ -738,15 +744,20 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM parent.menu.do_reload_needaction(); } }); + }).always(function(){ + $(e.target).attr("disabled", false); }); }, 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'); @@ -967,9 +978,12 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM context: { 'bin_size': true, 'future_display_name': true - } + }, + check_access_rule: true }).then(function(r) { self.trigger('load_record', r); + }).fail(function (){ + self.do_action('history_back'); }); } }); @@ -1979,8 +1993,10 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({ return this.view.do_execute_action( _.extend({}, this.node.attrs, {context: context}), - this.view.dataset, this.view.datarecord.id, function () { - self.view.recursive_reload(); + this.view.dataset, this.view.datarecord.id, function (reason) { + if (!_.isObject(reason)) { + self.view.recursive_reload(); + } }); }, check_disable: function() { @@ -2246,14 +2262,17 @@ instance.web.form.ReinitializeWidgetMixin = { 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); + } }, }); /** Some hack to make placeholders work in ie9. */ -if ($.browser.msie && $.browser.version === "9.0") { +if (!('placeholder' in document.createElement('input'))) { document.addEventListener("DOMNodeInserted",function(event){ var nodename = event.target.nodeName.toLowerCase(); if ( nodename === "input" || nodename == "textarea" ) { @@ -2429,6 +2448,7 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ type_of_date: "datetime", events: { 'change .oe_datepicker_master': 'change_datetime', + 'keypress .oe_datepicker_master': 'change_datetime', }, init: function(parent) { this._super(parent); @@ -2547,8 +2567,8 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ 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"); } @@ -2606,7 +2626,9 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(instanc }, 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); + } } }); @@ -2719,7 +2741,7 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc 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 @@ -2835,9 +2857,7 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan var def; if (this.field.type === "many2one") { var model = new openerp.Model(openerp.session, this.field.relation); - def = model.call("search", [this.get("domain")], {"context": this.build_context()}).then(function(record_ids) { - return model.call("name_get", [record_ids] , {"context": self.build_context()}); - }); + def = model.call("name_search", ['', this.get("domain")], {"context": this.build_context()}); } else { var values = _.reject(this.field.selection, function (v) { return v[0] === false && v[1] === ''; }); def = $.when(values); @@ -3092,7 +3112,7 @@ instance.web.form.CompletionFieldMixin = { // quick create var raw_result = _(data.result).map(function(x) {return x[1];}); if (search_val.length > 0 && !_.include(raw_result, search_val) && - ! (self.options && self.options.no_quick_create)) { + ! (self.options && (self.options.no_create || self.options.no_quick_create))) { values.push({ label: _.str.sprintf(_t('Create "%s"'), $('').text(search_val).html()), @@ -3103,13 +3123,15 @@ instance.web.form.CompletionFieldMixin = { }); } // create... - values.push({ - label: _t("Create and Edit..."), - action: function() { - self._search_create_popup("form", undefined, self._create_context(search_val)); - }, - classname: 'oe_m2o_dropdown_option' - }); + if (!(self.options && self.options.no_create)){ + values.push({ + label: _t("Create and Edit..."), + action: function() { + self._search_create_popup("form", undefined, self._create_context(search_val)); + }, + classname: 'oe_m2o_dropdown_option' + }); + } return values; }); @@ -3125,7 +3147,8 @@ instance.web.form.CompletionFieldMixin = { if (self.options.quick_create === undefined || self.options.quick_create) { new instance.web.DataSet(this, this.field.relation, self.build_context()) .name_create(name).done(function(data) { - self.add_id(data[0]); + if (!self.get('effective_readonly')) + self.add_id(data[0]); }).fail(function(error, event) { event.preventDefault(); slow_create(); @@ -3215,6 +3238,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc this.floating = false; this.current_display = null; this.is_started = false; + this.ignore_focusout = false; }, reinit_value: function(val) { this.internal_set_value(val); @@ -3297,7 +3321,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc self.display_value_backup = {}; self.render_value(); self.focus(); - self.view.do_onchange(self); + self.trigger('changed_value'); }); }); @@ -3341,6 +3365,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc 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) { @@ -3359,7 +3384,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc } 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(); @@ -3545,11 +3570,17 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc _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); } }); @@ -4074,28 +4105,23 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ 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()) { @@ -4165,7 +4191,11 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ 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(){ @@ -4302,7 +4332,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in if (data.id) { self.add_id(data.id); } else { - ignore_blur = true; + self.ignore_blur = true; data.action(); } this.trigger('setSuggestions', {result : []}); @@ -4342,7 +4372,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in if (this.get("effective_readonly")) return; var self = this; - var ignore_blur = false; + self.ignore_blur = false; self.$text = this.$("textarea"); self.$text.textext(self.initialize_texttext()).bind('getSuggestions', function(e, data) { var _this = this; @@ -4362,11 +4392,11 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in self.$text .focusin(function () { self.trigger('focused'); - ignore_blur = false; + self.ignore_blur = false; }) .focusout(function() { self.$text.trigger("setInputData", ""); - if (!ignore_blur) { + if (!self.ignore_blur) { self.trigger('blurred'); } }).keydown(function(e) { @@ -4425,9 +4455,8 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in 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([]); } }, @@ -4444,6 +4473,10 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in width: width, minHeight: height }); + }, + _search_create_popup: function() { + self.ignore_blur = true; + return instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments); }, }); @@ -4552,7 +4585,8 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in 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() @@ -5005,7 +5039,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend this.searchview.on('search_data', self, function(domains, contexts, groupbys) { if (self.initial_ids) { self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]), - contexts, groupbys); + contexts.concat(self.context), groupbys); self.initial_ids = undefined; } else { self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys); @@ -5383,6 +5417,20 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ 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_ + }); + } } }); @@ -5392,7 +5440,7 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ * 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); @@ -5410,6 +5458,9 @@ instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractFie 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_ || []; @@ -5446,6 +5497,7 @@ instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractFie }, 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));