X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fweb%2Fstatic%2Fsrc%2Fjs%2Fview_form.js;h=d0698cc13b87e62842581ff3700969c35513b7c1;hb=59d0d15b03125bd0d0cff0729326c9e35c6e6212;hp=6bc708527af83cb633d3f8332d4a284a784f7465;hpb=4d80adac5b029e1a71e823fb21fe4994a452131d;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 6bc7085..d0698cc 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -208,8 +208,9 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form. } } }, - do_show: function () { + do_show: function (options) { var self = this; + options = options || {}; if (this.sidebar) { this.sidebar.$element.show(); } @@ -233,6 +234,9 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form. }).pipe(self.on_record_loaded); } result.pipe(function() { + if (options.editable) { + self.set({mode: "edit"}); + } self.$element.css('visibility', 'visible'); }); return result; @@ -468,7 +472,7 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form. return self.on_processed_onchange(response, processed); } catch(e) { - console.error(e); + instance.webclient.crashmanager.on_javascript_exception(e); return $.Deferred().reject(); } }); @@ -495,7 +499,8 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form. this.on_form_changed(); } if (!_.isEmpty(result.warning)) { - instance.web.dialog($(QWeb.render("CrashManagerWarning", result.warning)), { + instance.web.dialog($(QWeb.render("CrashManager.warning", result.warning)), { + title:result.warning.title, modal: true, buttons: [ {text: _t("Ok"), click: function() { $(this).dialog("close"); }} @@ -642,6 +647,9 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form. } if (form_invalid) { self.set({'display_invalid_fields': true}); + for (var f in self.fields) { + self.fields[f]._check_css_flags(); + } first_invalid_field.focus(); self.on_invalid(); return $.Deferred().reject(); @@ -720,7 +728,6 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form. if (this.sidebar) { this.sidebar.do_attachement_update(this.dataset, this.datarecord.id); } - //instance.log("The record has been created with id #" + this.datarecord.id); this.reload(); return $.when(_.extend(r, {created: true})).then(success); } @@ -906,6 +913,10 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt }, set_fields_view: function(fvg) { this.fvg = fvg; + this.version = parseFloat(this.fvg.arch.attrs.version); + if (isNaN(this.version)) { + this.version = 6.1; + } }, set_tags_registry: function(tags_registry) { this.tags_registry = tags_registry; @@ -913,6 +924,18 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt set_fields_registry: function(fields_registry) { this.fields_registry = fields_registry; }, + // Backward compatibility tools, current default version: v6.1 + process_version: function() { + if (this.version < 7.0) { + this.$form.find('form:first').wrapInner(''); + this.$form.find('page').each(function() { + if (!$(this).parents('field').length) { + $(this).wrapInner(''); + } + }); + } + selector = 'form[version!="7.0"] page,form[version!="7.0"]'; + }, render_to: function($target) { var self = this; this.$target = $target; @@ -922,6 +945,8 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt var xml = instance.web.json_node_to_xml(this.fvg.arch); this.$form = $('
' + xml + '
'); + this.process_version(); + this.fields_to_init = []; this.tags_to_init = []; this.labels = {}; @@ -1004,7 +1029,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt this.process($new_sheet); }, process_form: function($form) { - if ($form.find('> sheet').length == 0) { + if ($form.find('> sheet').length === 0) { $form.addClass('oe_form_nosheet'); } var $new_form = this.render_element('FormRenderingForm', $form.getAttributes()); @@ -1048,6 +1073,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt "modifiers": JSON.stringify({invisible: field_modifiers.invisible}), "string": $field.attr('string'), "help": $field.attr('help'), + "class": $field.attr('class'), }); $label.insertBefore($field); if (field_colspan > 1) { @@ -1135,13 +1161,14 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt if ($child.attr('orientation') === 'vertical') { $td.addClass('oe_vertical_separator').attr('width', '1'); $td.empty(); - row_cols--; + row_cols-= $td.attr('colspan') || 1; + total--; } break; case 'label': if ($child.attr('for')) { $td.attr('width', '1%').addClass('oe_form_group_cell_label'); - row_cols--; + row_cols-= $td.attr('colspan') || 1; total--; } break; @@ -1158,20 +1185,22 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt } $td.attr('width', width); $child.removeAttr('width'); - row_cols--; + row_cols-= $td.attr('colspan') || 1; } else { to_compute.push($td); } } }); - var unit = Math.floor(total / row_cols); - if (!$(this).is('.oe_form_group_row_incomplete')) { - _.each(to_compute, function($td, i) { - var width = parseInt($td.attr('colspan'), 10) * unit; - $td.attr('width', ((i == to_compute.length - 1) ? total : width) + '%'); - total -= width; - }); + if (row_cols) { + var unit = Math.floor(total / row_cols); + if (!$(this).is('.oe_form_group_row_incomplete')) { + _.each(to_compute, function($td, i) { + var width = parseInt($td.attr('colspan'), 10) * unit; + $td.attr('width', width + '%'); + total -= width; + }); + } } }); _.each(children, function(el) { @@ -1187,19 +1216,40 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt var $page = $(this); var page_attrs = $page.getAttributes(); page_attrs.id = _.uniqueId('notebook_page_'); - pages.push(page_attrs); var $new_page = self.render_element('FormRenderingNotebookPage', page_attrs); $page.contents().appendTo($new_page); $page.before($new_page).remove(); - self.handle_common_properties($new_page, $page); + var ic = self.handle_common_properties($new_page, $page).invisibility_changer; + page_attrs.__page = $new_page; + page_attrs.__ic = ic; + pages.push(page_attrs); + + $new_page.children().each(function() { + self.process($(this)); + }); }); var $new_notebook = this.render_element('FormRenderingNotebook', { pages : pages }); $notebook.contents().appendTo($new_notebook); $notebook.before($new_notebook).remove(); - $new_notebook.children().each(function() { - self.process($(this)); - }); + self.process($($new_notebook.children()[0])); + //tabs and invisibility handling $new_notebook.tabs(); + _.each(pages, function(page, i) { + if (! page.__ic) + return; + page.__ic.on("change:effective_invisible", null, function() { + var current = $new_notebook.tabs("option", "selected"); + if (! pages[current].__ic || ! pages[current].__ic.get("effective_invisible")) + return; + var first_visible = _.find(_.range(pages.length), function(i2) { + return (! pages[i2].__ic) || (! pages[i2].__ic.get("effective_invisible")); + }); + if (first_visible !== undefined) { + $new_notebook.tabs('select', first_visible); + } + }); + }); + this.handle_common_properties($new_notebook, $notebook); return $new_notebook; }, @@ -1237,10 +1287,12 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt handle_common_properties: function($new_element, $node) { var str_modifiers = $node.attr("modifiers") || "{}" var modifiers = JSON.parse(str_modifiers); + var ic = null; if (modifiers.invisible !== undefined) - new instance.web.form.InvisibilityChanger(this.view, this.view, modifiers.invisible, $new_element); + ic = new instance.web.form.InvisibilityChanger(this.view, this.view, modifiers.invisible, $new_element); $new_element.addClass($node.attr("class") || ""); $new_element.attr('style', $node.attr('style')); + return {invisibility_changer: ic,}; }, }); @@ -1378,15 +1430,11 @@ instance.web.form.InvisibilityChangerMixin = { _.bind(check, this)(); }, start: function() { - var check_visibility = function() { - if (this.get("effective_invisible")) { - this.$element.hide(); - } else { - this.$element.show(); - } - }; - this.on("change:effective_invisible", this, check_visibility); - _.bind(check_visibility, this)(); + this.on("change:effective_invisible", this, this._check_visibility); + this._check_visibility(); + }, + _check_visibility: function() { + this.$element.toggleClass('oe_form_invisible', this.get("effective_invisible")); }, }; @@ -1733,6 +1781,8 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(_.extend({ this.on("change:required", this, this._set_required); this._set_required(); } + this._check_visibility(); + this._check_css_flags(); }, /** * Private. Do not use. @@ -1873,7 +1923,7 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(_.extend({} return true; }, is_false: function() { - return this.get('value') === ''; + return this.get('value') === '' || this._super(); }, focus: function() { this.delay_focus(this.$element.find('input:first')); @@ -2082,7 +2132,7 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(_.exten return true; }, is_false: function() { - return this.get('value') === ''; + return this.get('value') === '' || this._super(); }, focus: function() { if (this.datewidget && this.datewidget.$input) @@ -2132,7 +2182,7 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(_.extend({} return true; }, is_false: function() { - return this.get('value') === ''; + return this.get('value') === '' || this._super(); }, focus: function($element) { this.delay_focus(this.$textarea); @@ -2493,6 +2543,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(_.exten var tip_delay = 200; var tip_duration = 3000; var anyoneLoosesFocus = function() { + var used = false; if (self.floating) { if (self.last_search.length > 0) { if (self.last_search[0][0] != self.get("value")) { @@ -2500,13 +2551,17 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(_.exten self.display_value["" + self.last_search[0][0]] = self.last_search[0][1]; self.set({value: self.last_search[0][0]}); } else { + used = true; self.render_value(); } } else { + used = true; self.set({value: false}); + self.render_value(); } + self.floating = false; } - if (! self.get("value")) { + if (used) { tip_def.reject(); untip_def.reject(); tip_def = $.Deferred(); @@ -2553,7 +2608,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(_.exten e.preventDefault(); }, html: true, - close: anyoneLoosesFocus, + // disabled to solve a bug, but may cause others + //close: anyoneLoosesFocus, minLength: 0, delay: 0 }); @@ -2691,6 +2747,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ }, start: function() { this._super.apply(this, arguments); + this.$element.addClass('oe_form_field_one2many'); var self = this; @@ -2698,7 +2755,6 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ this.dataset.o2m = this; this.dataset.parent_view = this.view; this.dataset.child_name = this.name; - //this.dataset.child_name = this.dataset.on_change.add_last(function() { self.trigger_on_change(); }); @@ -2730,6 +2786,13 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ modes = !!modes ? modes.split(",") : ["tree"]; var views = []; _.each(modes, function(mode) { + if (! _.include(["list", "tree", "graph", "kanban"], mode)) { + try { + throw new Error(_.str.sprintf("View type '%s' is not supported in One2Many.", mode)); + } catch(e) { + instance.webclient.crashmanager.on_javascript_exception(e) + } + } var view = { view_id: false, view_type: mode == "tree" ? "list" : mode, @@ -2750,9 +2813,13 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ } view.options.not_interactible_on_create = true; } else if (view.view_type === "kanban") { + view.options.confirm_on_delete = false; + view.options.sortable = false; if (self.get("effective_readonly")) { view.options.action_buttons = false; view.options.quick_creatable = false; + view.options.creatable = false; + view.options.read_only_mode = true; } } views.push(view); @@ -2760,6 +2827,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ this.views = views; this.viewmanager = new instance.web.form.One2ManyViewManager(this, this.dataset, views, {}); + this.viewmanager.$element.addClass("oe_view_manager_one2many"); this.viewmanager.o2m = self; var once = $.Deferred().then(function() { self.init_form_last_update.resolve(); @@ -3102,7 +3170,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(_. if (this.get("effective_readonly")) return; var self = this; - self. $text = $("textarea", this.$element); + self.$text = $("textarea", this.$element); self.$text.textext({ plugins : 'tags arrow autocomplete', autocomplete: { @@ -3154,19 +3222,6 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(_. return _.extend(el, {index:i}); })}); }); - }).bind('tagClick', function(e, tag, value, callback) { - var pop = new instance.web.form.FormOpenPopup(self.view); - pop.show_element( - self.field.relation, - value.id, - self.build_context(), - { - title: _t("Open: ") + (self.string || self.name) - } - ); - pop.on_write_completed.add_last(function() { - self.render_value(); - }); }).bind('hideDropdown', function() { self._drop_shown = false; }).bind('showDropdown', function() { @@ -3174,7 +3229,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(_. }); self.tags = self.$text.textext()[0].tags(); $("textarea", this.$element).focusout(function() { - $("textarea", this.$element).val(""); + self.$text.trigger("setInputData", ""); }).keydown(function(e) { if (event.keyCode === 9 && self._drop_shown) { self.$text.textext()[0].autocomplete().selectFromDropdown(); @@ -3210,17 +3265,6 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(_. self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};})); } else { self.$element.html(QWeb.render("FieldMany2ManyTags.box", {elements: data})); - $(".oe_form_field_many2manytags_box", self.$element).click(function() { - var index = Number($(this).data("index")); - self.do_action({ - type: 'ir.actions.act_window', - res_model: self.field.relation, - res_id: self.get("value")[index], - context: self.build_context(), - views: [[false, 'form']], - target: 'current' - }); - }); } }; if (! self.get('values') || self.get('values').length > 0) { @@ -3248,6 +3292,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ }, start: function() { this._super.apply(this, arguments); + this.$element.addClass('oe_form_field_many2many'); var self = this; @@ -3256,7 +3301,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ this.dataset.on_unlink.add_last(function(ids) { self.dataset_changed(); }); - + this.is_setted.then(function() { self.load_view(); }); @@ -3269,7 +3314,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ }); }); }); - }) + }); }, set_value: function(value_) { value_ = value_ || []; @@ -3282,12 +3327,16 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ self.reload_content(); this.is_setted.resolve(); }, + get_value: function() { + return [commands.replace_with(this.get('value'))]; + }, load_view: function() { var self = this; this.list_view = new instance.web.form.Many2ManyListView(this, this.dataset, false, { 'addable': self.get("effective_readonly") ? null : _t("Add"), 'deletable': self.get("effective_readonly") ? false : true, 'selectable': self.multi_selection, + 'sortable': false, }); var embedded = (this.field.views || {}).tree; if (embedded) { @@ -3311,7 +3360,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ }); }, dataset_changed: function() { - this.set({'value': [commands.replace_with(this.dataset.ids)]}); + this.set({'value': this.dataset.ids}); }, }); @@ -3413,6 +3462,8 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend( 'create_text': _t("Add"), 'creatable': self.get("effective_readonly") ? false : true, 'quick_creatable': self.get("effective_readonly") ? false : true, + 'read_only_mode': self.get("effective_readonly") ? true : false, + 'confirm_on_delete': false, }); var embedded = (this.field.views || {}).kanban; if (embedded) { @@ -3559,6 +3610,7 @@ instance.web.form.Many2ManyQuickCreate = instance.web.Widget.extend({ var self = this; self.$text.val(""); self.trigger('added', id); + this.m2m.dataset_changed(); }, }); } @@ -3613,7 +3665,7 @@ instance.web.form.AbstractFormPopup = instance.web.OldWidget.extend({ width: '90%', min_width: '800px', close: function() { - self.check_exit(); + self.check_exit(true); }, title: this.options.title || "", }, this.$element).open(); @@ -3671,9 +3723,10 @@ instance.web.form.AbstractFormPopup = instance.web.OldWidget.extend({ }, on_select_elements: function(element_ids) { }, - check_exit: function() { + check_exit: function(no_destroy) { if (this.created_elements.length > 0) { this.on_select_elements(this.created_elements); + this.created_elements = []; } this.destroy(); }, @@ -3762,7 +3815,8 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend self.view_list = new instance.web.form.SelectCreateListView(self, self.dataset, false, _.extend({'deletable': false, - 'selectable': !self.options.disable_multiple_selection + 'selectable': !self.options.disable_multiple_selection, + 'read_only': true, }, self.options.list_view_options || {})); self.view_list.popup = self; self.view_list.appendTo($(".oe-select-create-popup-view-list", self.$element)).pipe(function() { @@ -3928,13 +3982,22 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(_.exte instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, { init: function(field_manager, node) { + var self = this; this._super(field_manager, node); - this.iframe = this.element_id + '_iframe'; this.binary_value = false; + this.fileupload_id = _.uniqueId('oe_fileupload'); + $(window).on(this.fileupload_id, function() { + var args = [].slice.call(arguments).slice(1); + self.on_file_uploaded.apply(self, args); + }); + }, + stop: function() { + $(window).off(this.fileupload_id); + this._super.apply(this, arguments); }, initialize_content: function() { this.$element.find('input.oe-binary-file').change(this.on_file_change); - this.$element.find('button.oe-binary-file-save').click(this.on_save_as); + this.$element.find('button.oe_binary_file_save').click(this.on_save_as); this.$element.find('.oe-binary-file-clear').click(this.on_clear); }, human_filesize : function(size) { @@ -3950,8 +4013,8 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(_.extend( // TODO: on modern browsers, we could directly read the file locally on client ready to be used on image cropper // http://www.html5rocks.com/tutorials/file/dndfiles/ // http://deepliquid.com/projects/Jcrop/demos.php?demo=handler - window[this.iframe] = this.on_file_uploaded; - if ($(e.target).val() != '') { + + if ($(e.target).val() !== '') { this.$element.find('form.oe-binary-form input[name=session_id]').val(this.session.session_id); this.$element.find('form.oe-binary-form').submit(); this.$element.find('.oe-binary-progress').show(); @@ -3959,12 +4022,12 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(_.extend( } }, on_file_uploaded: function(size, name, content_type, file_base64) { - delete(window[this.iframe]); if (size === false) { this.do_warn("File Upload", "There was a problem while uploading your file"); // TODO: use openerp web crashmanager console.warn("Error while uploading file : ", name); } else { + this.filename = name; this.on_file_uploaded_and_valid.apply(this, arguments); } this.$element.find('.oe-binary-progress').hide(); @@ -3972,20 +4035,33 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(_.extend( }, on_file_uploaded_and_valid: function(size, name, content_type, file_base64) { }, - on_save_as: function() { - $.blockUI(); - this.session.get_file({ - url: '/web/binary/saveas_ajax', - data: {data: JSON.stringify({ - model: this.view.dataset.model, - id: (this.view.datarecord.id || ''), - field: this.name, - filename_field: (this.node.attrs.filename || ''), - context: this.view.dataset.get_context() - })}, - complete: $.unblockUI, - error: instance.webclient.crashmanager.on_rpc_error - }); + on_save_as: function(ev) { + var value = this.get('value'); + if (!value) { + this.do_warn(_t("Save As..."), _t("The field is empty, there's nothing to save !")); + ev.stopPropagation(); + } else if (this._dirty_flag) { + var link = this.$('.oe_binary_file_save_data')[0]; + link.download = this.filename || "download.bin"; // Works on only on Google Chrome + //link.target = '_blank'; + link.href = "data:application/octet-stream;base64," + value; + } else { + $.blockUI(); + this.session.get_file({ + url: '/web/binary/saveas_ajax', + data: {data: JSON.stringify({ + model: this.view.dataset.model, + id: (this.view.datarecord.id || ''), + field: this.name, + filename_field: (this.node.attrs.filename || ''), + context: this.view.dataset.get_context() + })}, + complete: $.unblockUI, + error: instance.webclient.crashmanager.on_rpc_error + }); + ev.stopPropagation(); + return false; + } }, on_clear: function() { if (this.get('value') !== false) { @@ -4053,14 +4129,6 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ template: 'FieldBinaryImage', - initialize_content: function() { - this._super(); - this.$placeholder = $(".oe_form_field-binary-image-placeholder", this.$element); - if (!this.get("effective_readonly")) - this.$element.find('.oe-binary').show(); - else - this.$element.find('.oe-binary').hide(); - }, set_value: function(value_) { this._super.apply(this, arguments); this.render_value(); @@ -4075,8 +4143,9 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ } else { url = "/web/static/src/img/placeholder.png"; } - var rendered = QWeb.render("FieldBinaryImage-img", {widget: this, url: url});; - this.$placeholder.html(rendered); + var img = QWeb.render("FieldBinaryImage-img", { widget: this, url: url }); + this.$element.find('> img').remove(); + this.$element.prepend(img); }, on_file_change: function() { this.render_value();