openerp.web.form = function (openerp) { var _t = openerp.web._t, _lt = openerp.web._lt; var QWeb = openerp.web.qweb; openerp.web.views.add('form', 'openerp.web.FormView'); openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# */{ /** * Indicates that this view is not searchable, and thus that no search * view should be displayed (if there is one active). */ searchable: false, readonly : false, template: "FormView", display_name: _lt('Form'), /** * @constructs openerp.web.FormView * @extends openerp.web.View * * @param {openerp.web.Session} session the current openerp session * @param {openerp.web.DataSet} dataset the dataset this view will work with * @param {String} view_id the identifier of the OpenERP view object * @param {Object} options * - sidebar : [true|false] * - resize_textareas : [true|false|max_height] * * @property {openerp.web.Registry} registry=openerp.web.form.widgets widgets registry for this form view instance */ init: function(parent, dataset, view_id, options) { this._super(parent); this.set_default_options(options); this.dataset = dataset; this.model = dataset.model; this.view_id = view_id || false; this.fields_view = {}; this.widgets = {}; this.widgets_counter = 0; this.fields = {}; this.fields_order = []; this.datarecord = {}; this.default_focus_field = null; this.default_focus_button = null; this.registry = openerp.web.form.widgets; this.has_been_loaded = $.Deferred(); this.$form_header = null; this.translatable_fields = []; _.defaults(this.options, { "not_interactible_on_create": false }); this.is_initialized = $.Deferred(); this.mutating_mutex = new $.Mutex(); this.on_change_mutex = new $.Mutex(); this.reload_mutex = new $.Mutex(); }, start: function() { this._super(); return this.init_view(); }, init_view: function() { if (this.embedded_view) { var def = $.Deferred().then(this.on_loaded); var self = this; $.async_when().then(function() {def.resolve(self.embedded_view);}); return def.promise(); } else { var context = new openerp.web.CompoundContext(this.dataset.get_context()); return this.rpc("/web/view/load", { "model": this.model, "view_id": this.view_id, "view_type": "form", toolbar: this.options.sidebar, context: context }, this.on_loaded); } }, destroy: function() { if (this.sidebar) { this.sidebar.attachments.destroy(); this.sidebar.destroy(); } _.each(this.widgets, function(w) { w.destroy(); }); this._super(); }, reposition: function ($e) { this.$element = $e; this.on_loaded(); }, on_loaded: function(data) { var self = this; if (!data) { throw new Error("No data provided."); } if (this.arch) { throw "Form view does not support multiple calls to on_loaded"; } this.fields_order = []; this.fields_view = data; this.arch = this.preprocess_arch(data); var html_view = openerp.web.xml_to_str(this.arch); this.$element.find('.oe_form_content').append(html_view); //this.root_frame = instanciate_widget(this.registry.get_object('frame'), this, this.fields_view.arch); //var to_append = $(".oe_form_header", this.$element); //this.root_frame.appendTo(to_append.length > 0 ? to_append : this.$element); //this.root_frame.$element.children().unwrap(); this.$form_header = this.$element.find('.oe_form_header:first'); this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() { var action = $(this).data('pager-action'); self.on_pager_action(action); }); this.$form_header.find('button.oe_form_button_save').click(this.on_button_save); this.$form_header.find('button.oe_form_button_cancel').click(this.on_button_cancel); if (!this.sidebar && this.options.sidebar && this.options.sidebar_id) { this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id); this.sidebar.start(); this.sidebar.do_unfold(); this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this); this.sidebar.add_toolbar(this.fields_view.toolbar); this.set_common_sidebar_sections(this.sidebar); this.sidebar.add_section(_t('Customize'), 'customize'); this.sidebar.add_items('customize', [{ label: _t('Set Default'), form: this, callback: function (item) { item.form.open_defaults_dialog(); } }]); } this.has_been_loaded.resolve(); }, preprocess_arch: function(data) { // TODO: extract embeded views before preprocessing // Cut down this function into rendering API amongst form, page and kanban // // OpenERP views spec : // - @width is obsolete ? var self = this, baseclass = 'oe_layout_', fields = data.fields, arch = $.parseXML(data.arch_string); // Step #1: // - If field has no @string, fetch it from fvg.fields. // - If field has no label, create one. // - Unless @nolabel, create unique @id and @for pair $(arch).find('field').each(function() { var $field = $(this), name = $field.attr('name'), field_orm = fields[name], field_id = _.uniqueId([self.dataset.model, name, '#'].join('.')); if (!field_orm) { throw new Error("Field '" + name + "' specified in view could not be found."); } var $label = $(arch).find('label[for="' + name + '"]'), label_string = $field.attr('string') || field_orm.string || ''; if ($label.length) { label_string = $label.attr('string') || $label.text(); } else { // TODO: find a way to prevent @xmlns. $label = $('