summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/view_form.js
diff options
context:
space:
mode:
authorXavier Morel <xmo@openerp.com>2012-04-19 10:12:13 +0200
committerXavier Morel <xmo@openerp.com>2012-04-19 10:12:13 +0200
commite7ab44929ff4aa3add8d00bab97fc3e879b9b91c (patch)
treea600579e5c3c00c473550db8da591b6634fcbe0f /addons/web/static/src/js/view_form.js
parent45c48d684270f9a88af668f99a1d027df57f68d3 (diff)
parentf5c37eabe94a04ca62d08f46c1cf3a084fa77f19 (diff)
[MERGE] from trunk
bzr revid: xmo@openerp.com-20120419081213-m3fhofkgydj6gp1m
Diffstat (limited to 'addons/web/static/src/js/view_form.js')
-rw-r--r--addons/web/static/src/js/view_form.js2829
1 files changed, 1559 insertions, 1270 deletions
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 50c5dcb976a..7e5b173fd37 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -1,31 +1,32 @@
-openerp.web.form = function (openerp) {
+openerp.web.form = function (instance) {
+var _t = instance.web._t,
+ _lt = instance.web._lt;
+var QWeb = instance.web.qweb;
-var _t = openerp.web._t,
- _lt = openerp.web._lt;
-var QWeb = openerp.web.qweb;
+/** @namespace */
+instance.web.form = {};
-openerp.web.views.add('form', 'openerp.web.FormView');
-openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# */{
+instance.web.views.add('form', 'instance.web.FormView');
+instance.web.FormView = instance.web.View.extend({
/**
* 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,
- form_template: "FormView",
+ template: "FormView",
display_name: _lt('Form'),
+ view_type: "form",
/**
- * @constructs openerp.web.FormView
- * @extends openerp.web.View
+ * @constructs instance.web.FormView
+ * @extends instance.web.View
*
- * @param {openerp.web.Session} session the current openerp session
- * @param {openerp.web.DataSet} dataset the dataset this view will work with
+ * @param {instance.web.Session} session the current openerp session
+ * @param {instance.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
+ * @property {instance.web.Registry} registry=instance.web.form.widgets widgets registry for this form view instance
*/
init: function(parent, dataset, view_id, options) {
this._super(parent);
@@ -34,98 +35,86 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
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.fields_registry = instance.web.form.widgets;
+ this.tags_registry = instance.web.form.tags;
this.has_been_loaded = $.Deferred();
- this.$form_header = null;
this.translatable_fields = [];
_.defaults(this.options, {
- "not_interactible_on_create": false
+ "not_interactible_on_create": false,
+ "initial_mode": "view",
});
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);
- }
+ this.mode = null;
+ this.rendering_engine = new instance.web.form.FormRenderingEngineReadonly(this);
+ this.qweb = null; // A QWeb instance will be created if the view is a QWeb template
},
destroy: function() {
- if (this.sidebar) {
- this.sidebar.attachments.destroy();
- this.sidebar.destroy();
- }
- _.each(this.widgets, function(w) {
+ _.each(this.get_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 "No data provided.";
+ throw new Error("No data provided.");
}
- if (this.root_frame) {
- throw "Form view does not support multiple calls to on_loaded";
+ if (this.arch) {
+ throw "Form view does not support multiple calls to on_loaded";
}
this.fields_order = [];
this.fields_view = data;
- this.rendered = QWeb.render(this.form_template, {'widget': this});
- this.$element.html(this.rendered);
-
- 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() {
+ this.rendering_engine.set_fields_registry(this.fields_registry);
+ this.rendering_engine.set_tags_registry(this.tags_registry);
+ if (!this.extract_qweb_template(data)) {
+ this.rendering_engine.set_fields_view(data);
+ var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container');
+ this.rendering_engine.render_to($dest);
+ }
+
+ this.$sidebar = this.options.$sidebar || this.$element.find('.oe_form_sidebar');
+
+ this.$buttons = $(QWeb.render("FormView.buttons", {'widget':self}));
+ if (this.options.$buttons) {
+ this.$buttons.appendTo(this.options.$buttons);
+ } else {
+ this.$element.find('.oe_form_buttons').replaceWith(this.$buttons);
+ }
+ this.$buttons
+ .on('click','button.oe_form_button_save',this.on_button_save)
+ .on('click','button.oe_form_button_cancel',this.on_button_cancel)
+ .on('click','button.oe_form_button_edit',this.on_button_edit)
+ .on('click','button.oe_form_button_create',this.on_button_create)
+ .on('click','button.oe_form_button_duplicate',this.on_button_duplicate)
+ .on('click','button.oe_form_button_delete',this.on_button_delete);
+
+ this.$pager = $(QWeb.render("FormView.pager", {'widget':self}));
+ if (this.options.$pager) {
+ this.$pager.appendTo(this.options.$pager);
+ } else {
+ this.$element.find('.oe_form_pager').replaceWith(this.$pager);
+ }
+ this.$pager.on('click','a[data-pager-action]',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', [{
+ if (!this.sidebar && this.options.$sidebar) {
+ this.sidebar = new instance.web.Sidebar(this);
+ this.sidebar.appendTo(this.$sidebar);
+ if(this.fields_view.toolbar) {
+ this.sidebar.add_toolbar(this.fields_view.toolbar);
+ }
+ this.sidebar.add_items('other', [{
label: _t('Set Default'),
form: this,
callback: function (item) {
@@ -133,9 +122,61 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
}]);
}
+ this.on("change:mode", this, this.switch_mode);
+ this.set({mode: this.options.initial_mode});
this.has_been_loaded.resolve();
+ return $.when();
+ },
+ extract_qweb_template: function(fvg) {
+ for (var i=0, ii=fvg.arch.children.length; i < ii; i++) {
+ var child = fvg.arch.children[i];
+ if (child.tag === "templates") {
+ this.qweb = new QWeb2.Engine();
+ this.qweb.add_template(instance.web.json_node_to_xml(child));
+ if (!this.qweb.has_template('form')) {
+ throw new Error("No QWeb template found for form view");
+ }
+ return true;
+ }
+ }
+ this.qweb = null;
+ return false;
+ },
+ get_fvg_from_qweb: function(record) {
+ var view = this.qweb.render('form', this.get_qweb_context(record));
+ var fvg = _.clone(this.fields_view);
+ fvg.arch = instance.web.xml_to_json(instance.web.str_to_xml(view).firstChild);
+ return fvg;
+ },
+ get_qweb_context: function(record) {
+ var self = this,
+ new_record = {};
+ _.each(record, function(value_, name) {
+ var r = _.clone(self.fields_view.fields[name] || {});
+ if ((r.type === 'date' || r.type === 'datetime') && value_) {
+ r.raw_value = instance.web.auto_str_to_date(value_);
+ } else {
+ r.raw_value = value_;
+ }
+ r.value = instance.web.format_value(value_, r);
+ new_record[name] = r;
+ });
+ return {
+ record : new_record,
+ new_record : !record.id
+ };
+ },
+ kill_current_form: function() {
+ _.each(this.getChildren(), function(el) {
+ el.destroy();
+ });
+ this.fields = {};
+ this.fields_order = [];
+ this.default_focus_field = null;
+ this.default_focus_button = null;
+ this.translatable_fields = [];
+ this.$element.find('.oe_form_container').empty();
},
-
do_load_state: function(state, warm) {
if (state.id && this.datarecord.id != state.id) {
if (!this.dataset.get_id_index(state.id)) {
@@ -147,9 +188,18 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
}
},
-
do_show: function () {
var self = this;
+ if (this.sidebar) {
+ this.sidebar.$element.show();
+ }
+ if (this.$buttons) {
+ this.$buttons.show();
+ this.$buttons.find('.oe_form_button_save').removeClass('oe_form_button_save_dirty');
+ }
+ if (this.$pager) {
+ this.$pager.show();
+ }
this.$element.show().css('visibility', 'hidden');
this.$element.removeClass('oe_form_dirty');
return this.has_been_loaded.pipe(function() {
@@ -165,17 +215,20 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
result.pipe(function() {
self.$element.css('visibility', 'visible');
});
- if (self.sidebar) {
- self.sidebar.$element.show();
- }
return result;
});
},
do_hide: function () {
- this._super();
if (this.sidebar) {
this.sidebar.$element.hide();
}
+ if (this.$buttons) {
+ this.$buttons.hide();
+ }
+ if (this.$pager) {
+ this.$pager.hide();
+ }
+ this._super();
},
on_record_loaded: function(record) {
var self = this, set_values = [];
@@ -185,13 +238,17 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
this.datarecord = record;
+ if (this.qweb) {
+ this.kill_current_form();
+ this.rendering_engine.set_fields_view(this.get_fvg_from_qweb(record));
+ var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container');
+ this.rendering_engine.render_to($dest);
+ }
+
_(this.fields).each(function (field, f) {
- field.reset();
+ field._dirty_flag = false;
var result = field.set_value(self.datarecord[f] || false);
set_values.push(result);
- $.when(result).then(function() {
- field.validate();
- });
});
return $.when.apply(null, set_values).pipe(function() {
if (!record.id) {
@@ -200,7 +257,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
_.each(self.fields_order, function(field_name) {
if (record[field_name] !== undefined) {
var field = self.fields[field_name];
- field.dirty = true;
+ field._dirty_flag = true;
self.do_onchange(field);
}
});
@@ -209,7 +266,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.is_initialized.resolve();
self.do_update_pager(record.id == null);
if (self.sidebar) {
- self.sidebar.attachments.do_update();
+ self.sidebar.do_attachement_update(self.dataset, self.datarecord.id);
}
if (self.default_focus_field) {
self.default_focus_field.focus();
@@ -218,20 +275,15 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.do_push_state({id:record.id});
}
self.$element.removeClass('oe_form_dirty');
+ self.$buttons.find('.oe_form_button_save').removeClass('oe_form_button_save_dirty');
});
},
on_form_changed: function() {
- for (var w in this.widgets) {
- w = this.widgets[w];
- w.process_modifiers();
- if (w.field) {
- w.validate();
- }
- w.update_dom();
- }
+ this.trigger("view_content_has_changed");
},
do_notify_change: function() {
this.$element.addClass('oe_form_dirty');
+ this.$buttons.find('.oe_form_button_save').addClass('oe_form_button_save_dirty');
},
on_pager_action: function(action) {
if (this.can_be_discarded()) {
@@ -253,11 +305,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
},
do_update_pager: function(hide_index) {
- var $pager = this.$form_header.find('div.oe_form_pager');
var index = hide_index ? '-' : this.dataset.index + 1;
- $pager.find('button').prop('disabled', this.dataset.ids.length < 2);
- $pager.find('span.oe_pager_index').html(index);
- $pager.find('span.oe_pager_count').html(this.dataset.ids.length);
+ this.$pager.find('button').prop('disabled', this.dataset.ids.length < 2).end()
+ .find('span.oe_pager_index').html(index).end()
+ .find('span.oe_pager_count').html(this.dataset.ids.length);
},
parse_on_change: function (on_change, widget) {
var self = this;
@@ -278,7 +329,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
'None': function () {return null;},
'context': function (i) {
context_index = i;
- var ctx = new openerp.web.CompoundContext(self.dataset.get_context(), widget.build_context() ? widget.build_context() : {});
+ var ctx = new instance.web.CompoundContext(self.dataset.get_context(), widget.build_context() ? widget.build_context() : {});
return ctx;
}
};
@@ -296,8 +347,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
// form field
if (self.fields[field]) {
- var value = self.fields[field].get_on_change_value();
- return value == null ? false : value;
+ var value_ = self.fields[field].get_value();
+ return value_ == null ? false : value_;
}
// parent field
var splitted = field.split('.');
@@ -360,17 +411,17 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
if (widget.field['change_default']) {
- var fieldname = widget.name, value;
+ var fieldname = widget.name, value_;
if (response.value && (fieldname in response.value)) {
// Use value from onchange if onchange executed
- value = response.value[fieldname];
+ value_ = response.value[fieldname];
} else {
// otherwise get form value for field
- value = self.fields[fieldname].get_on_change_value();
+ value_ = self.fields[fieldname].get_value();
}
- var condition = fieldname + '=' + value;
+ var condition = fieldname + '=' + value_;
- if (value) {
+ if (value_) {
can_process_onchange = self.rpc({
url: '/web/dataset/call',
async: false
@@ -411,10 +462,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
var field = this.fields[f];
// If field is not defined in the view, just ignore it
if (field) {
- var value = result.value[f];
- if (field.get_value() != value) {
- field.set_value(value);
- field.dirty = true;
+ var value_ = result.value[f];
+ if (field.get_value() != value_) {
+ field.set_value(value_);
+ field._dirty_flag = true;
if (!_.contains(processed, field.name)) {
this.do_onchange(field, processed);
}
@@ -424,7 +475,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.on_form_changed();
}
if (!_.isEmpty(result.warning)) {
- openerp.web.dialog($(QWeb.render("CrashManagerWarning", result.warning)), {
+ instance.web.dialog($(QWeb.render("CrashManagerWarning", result.warning)), {
modal: true,
buttons: [
{text: _t("Ok"), click: function() { $(this).dialog("close"); }}
@@ -447,19 +498,38 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return $.Deferred().reject();
}
},
+ switch_mode: function() {
+ var mode = this.get("mode");
+ var self = this;
+ if(mode=="view") {
+ self.$buttons.find('.oe_form_buttons_edit').hide();
+ self.$buttons.find('.oe_form_buttons_view').show();
+ _.each(this.fields,function(field){
+ field.set({"force_readonly": true});
+ });
+ } else {
+ self.$buttons.find('.oe_form_buttons_edit').show();
+ self.$buttons.find('.oe_form_buttons_view').hide();
+ _.each(this.fields,function(field){
+ field.set({"force_readonly": false});
+ });
+ }
+ self.mode = mode;
+ },
on_button_save: function() {
var self = this;
return this.do_save().then(function(result) {
- self.do_prev_view({'created': result.created, 'default': 'page'});
+ self.set({mode: "view"});
});
},
on_button_cancel: function() {
if (this.can_be_discarded()) {
- return this.do_prev_view({'default': 'page'});
+ this.set({mode: "view"});
}
},
on_button_new: function() {
var self = this;
+ this.set({mode: "edit"});
var def = $.Deferred();
$.when(this.has_been_loaded).then(function() {
if (self.can_be_discarded()) {
@@ -477,6 +547,44 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
});
return def.promise();
},
+ on_button_edit: function() {
+ return this.set({mode: "edit"});
+ },
+ on_button_create: function() {
+ this.dataset.index = null;
+ this.do_show();
+ },
+ on_button_duplicate: function() {
+ var self = this;
+ var def = $.Deferred();
+ $.when(this.has_been_loaded).then(function() {
+ self.dataset.call('copy', [self.datarecord.id, {}, self.dataset.context]).then(function(new_id) {
+ return self.on_created({ result : new_id });
+ }).then(function() {
+ return self.set({mode: "edit"});
+ }).then(function() {
+ def.resolve();
+ });
+ });
+ return def.promise();
+ },
+ on_button_delete: function() {
+ var self = this;
+ var def = $.Deferred();
+ $.when(this.has_been_loaded).then(function() {
+ if (self.datarecord.id && confirm(_t("Do you really want to delete this record?"))) {
+ self.dataset.unlink([self.datarecord.id]).then(function() {
+ self.on_pager_action('next');
+ def.resolve();
+ });
+ } else {
+ $.async_when().then(function () {
+ def.reject();
+ })
+ }
+ });
+ return def.promise();
+ },
can_be_discarded: function() {
return !this.$element.is('.oe_form_dirty') || confirm(_t("Warning, the record has been modified, your changes will be discarded."));
},
@@ -499,11 +607,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
f = self.fields[f];
if (!f.is_valid()) {
form_invalid = true;
- f.update_dom(true);
if (!first_invalid_field) {
first_invalid_field = f;
}
- } else if (f.name !== 'id' && !f.readonly && (!self.datarecord.id || f.is_dirty())) {
+ } else if (f.name !== 'id' && !f.get("readonly") && (!self.datarecord.id || f._dirty_flag)) {
// Special case 'id' field, do not save this field
// on 'create' : save all non readonly fields
// on 'edit' : save non readonly modified fields
@@ -511,20 +618,23 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
}
if (form_invalid) {
+ self.set({'display_invalid_fields': true});
first_invalid_field.focus();
self.on_invalid();
return $.Deferred().reject();
} else {
+ self.set({'display_invalid_fields': false});
var save_deferral;
if (!self.datarecord.id) {
//console.log("FormView(", self, ") : About to create", values);
save_deferral = self.dataset.create(values).pipe(function(r) {
return self.on_created(r, undefined, prepend_on_create);
}, null);
- } else if (_.isEmpty(values)) {
+ } else if (_.isEmpty(values) && ! self.force_dirty) {
//console.log("FormView(", self, ") : Nothing to save");
save_deferral = $.Deferred().resolve({}).promise();
} else {
+ self.force_dirty = false;
//console.log("FormView(", self, ") : About to save", values);
save_deferral = self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) {
return self.on_saved(r);
@@ -542,7 +652,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
var msg = "<ul>";
_.each(this.fields, function(f) {
if (!f.is_valid()) {
- msg += "<li>" + f.string + "</li>";
+ msg += "<li>" + f.node.attrs.string + "</li>";
}
});
msg += "</ul>";
@@ -580,14 +690,14 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.dataset.alter_ids(this.dataset.ids.concat([this.datarecord.id]));
this.dataset.index = this.dataset.ids.length - 1;
} else {
- this.dataset.alter_ids([this.datarecord.id].concat(this.dataset.ids));
+ this.dataset.alter_ids([this.datarecord.id].concat(this.dataset.ids));
this.dataset.index = 0;
}
this.do_update_pager();
if (this.sidebar) {
- this.sidebar.attachments.do_update();
+ this.sidebar.do_attachement_update(this.dataset, this.datarecord.id);
}
- //openerp.log("The record has been created with id #" + 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);
}
@@ -598,6 +708,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
reload: function() {
var self = this;
return this.reload_mutex.exec(function() {
+ if (self.dataset.index == null) {
+ self.do_prev_view();
+ return $.Deferred().reject().promise();
+ }
if (self.dataset.index == null || self.dataset.index < 0) {
return $.when(self.on_button_new());
} else {
@@ -607,15 +721,20 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
});
},
+ get_widgets: function() {
+ return _.filter(this.getChildren(), function(obj) {
+ return obj instanceof instance.web.form.Widget;
+ });
+ },
get_fields_values: function(blacklist) {
blacklist = blacklist || [];
var values = {};
var ids = this.get_selected_ids();
values["id"] = ids.length > 0 ? ids[0] : false;
- _.each(this.fields, function(value, key) {
+ _.each(this.fields, function(value_, key) {
if (_.include(blacklist, key))
return;
- var val = value.get_value();
+ var val = value_.get_value();
values[key] = val;
});
return values;
@@ -632,8 +751,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
});
},
is_dirty: function() {
- return _.any(this.fields, function (value) {
- return value.is_dirty();
+ return _.any(this.fields, function (value_) {
+ return value_._dirty_flag;
});
},
is_interactible_record: function() {
@@ -642,7 +761,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (this.options.not_interactible_on_create)
return false;
} else if (typeof(id) === "string") {
- if(openerp.web.BufferedDataSet.virtual_id_regex.test(id))
+ if(instance.web.BufferedDataSet.virtual_id_regex.test(id))
return false;
}
return true;
@@ -654,12 +773,12 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
var self = this;
var fields = _.chain(this.fields)
.map(function (field, name) {
- var value = field.get_value();
+ var value_ = field.get_value();
// ignore fields which are empty, invisible, readonly, o2m
// or m2m
- if (!value
- || field.invisible
- || field.readonly
+ if (!value_
+ || field.get('invisible')
+ || field.get("readonly")
|| field.field.type === 'one2many'
|| field.field.type === 'many2many') {
return false;
@@ -668,33 +787,33 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
switch(field.field.type) {
case 'selection':
displayed = _(field.values).find(function (option) {
- return option[0] === value;
+ return option[0] === value_;
})[1];
break;
case 'many2one':
- displayed = field.value[1] || value;
+ displayed = value_;
break;
default:
- displayed = value;
+ displayed = value_;
}
return {
name: name,
- string: field.string,
- value: value,
+ string: field.node_atts.string,
+ value: value_,
displayed: displayed,
// convert undefined to false
change_default: !!field.field.change_default
}
})
.compact()
- .sortBy(function (field) { return field.string; })
+ .sortBy(function (field) { return field.node_atts.string; })
.value();
var conditions = _.chain(fields)
.filter(function (field) { return field.change_default; })
.value();
- var d = new openerp.web.Dialog(this, {
+ var d = new instance.web.Dialog(this, {
title: _t("Set Default"),
args: {
fields: fields,
@@ -706,12 +825,12 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
var $defaults = d.$element.find('#formview_default_fields');
var field_to_set = $defaults.val();
if (!field_to_set) {
- $defaults.parent().addClass('invalid');
+ $defaults.parent().addClass('oe_form_invalid');
return;
}
var condition = d.$element.find('#formview_default_conditions').val(),
all_users = d.$element.find('#formview_default_all').is(':checked');
- new openerp.web.DataSet(self, 'ir.values').call(
+ new instance.web.DataSet(self, 'ir.values').call(
'set_default', [
self.dataset.model,
field_to_set,
@@ -725,9 +844,368 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
});
d.template = 'FormView.set_default';
d.open();
- }
+ },
+ register_field: function(field, name) {
+ this.fields[name] = field;
+ this.fields_order.push(name);
+ if (this.get_field(name).translate) {
+ this.translatable_fields.push(field);
+ }
+ field.on('changed_value', this, function() {
+ field._dirty_flag = true;
+ if (field.is_syntax_valid()) {
+ this.do_onchange(field);
+ this.on_form_changed(true);
+ this.do_notify_change();
+ }
+ });
+ },
+ get_field: function(field_name) {
+ return this.fields_view.fields[field_name];
+ },
+ is_create_mode: function() {
+ return !this.datarecord.id;
+ },
});
-openerp.web.FormDialog = openerp.web.Dialog.extend({
+
+/**
+ * Interface to be implemented by rendering engines for the form view.
+ */
+instance.web.form.FormRenderingEngineInterface = {
+ set_fields_view: function(fields_view) {},
+ set_fields_registry: function(fields_registry) {},
+ render_to: function($element) {},
+};
+
+/**
+ * Default rendering engine for the form view.
+ *
+ * It is necessary to set the view using set_view() before usage.
+ */
+instance.web.form.FormRenderingEngine = instance.web.Class.extend({
+ init: function(view) {
+ this.view = view;
+ },
+ set_fields_view: function(fvg) {
+ this.fvg = fvg;
+ },
+ set_tags_registry: function(tags_registry) {
+ this.tags_registry = tags_registry;
+ },
+ set_fields_registry: function(fields_registry) {
+ this.fields_registry = fields_registry;
+ },
+ render_to: function($target) {
+ var self = this;
+ this.$target = $target;
+
+ // TODO: I know this will save the world and all the kitten for a moment,
+ // but one day, we will have to get rid of xml2json
+ var xml = instance.web.json_node_to_xml(this.fvg.arch);
+ this.$form = $('<div class="oe_form">' + xml + '</div>');
+ if (this.fvg.arch.attrs && this.fvg.arch.attrs['layout'] !== 'manual') {
+ this.$form.attr('layout', 'auto');
+ }
+
+ this.fields_to_init = [];
+ this.tags_to_init = [];
+ this.labels = {};
+ this.process(this.$form);
+
+ this.$form.appendTo(this.$target);
+
+ _.each(this.fields_to_init, function($elem) {
+ var name = $elem.attr("name");
+ if (!self.fvg.fields[name]) {
+ throw new Error("Field '" + name + "' specified in view could not be found.");
+ }
+ var obj = self.fields_registry.get_any([$elem.attr('widget'), self.fvg.fields[name].type]);
+ if (!obj) {
+ throw new Error("Widget type '"+ key + "' is not implemented");
+ }
+ var w = new (obj)(self.view, instance.web.xml_to_json($elem[0]));
+ var $label = self.labels[$elem.attr("name")];
+ if ($label) {
+ w.set_input_id($label.attr("for"));
+ }
+ self.alter_field(w);
+ self.view.register_field(w, $elem.attr("name"));
+ w.replace($elem);
+ });
+ _.each(this.tags_to_init, function($elem) {
+ var tag_name = $elem[0].tagName.toLowerCase();
+ var obj = self.tags_registry.get_object(tag_name);
+ var w = new (obj)(self.view, instance.web.xml_to_json($elem[0]));
+ w.replace($elem);
+ })
+ // TODO: return a deferred
+ },
+ render_element: function(template, layout/* dictionaries */) {
+ var dicts = [].slice.call(arguments).slice(2);
+ dicts.unshift({ 'layout' : layout });
+ var dict = _.extend.apply(_, dicts);
+ dict['classnames'] = dict['class'] || ''; // class is a reserved word and might caused problem to Safari when used from QWeb
+ var alt_template = template + '.' + layout;
+ template = QWeb.has_template(alt_template) ? alt_template : template;
+ return $(QWeb.render(template, dict));
+ },
+ alter_field: function(field) {
+ },
+ toggle_layout_debugging: function() {
+ if (!this.$target.has('.oe_layout_debug_cell:first').length) {
+ this.$target.find('[title]').removeAttr('title');
+ this.$target.find('.oe_form_group_cell').each(function() {
+ var text = 'W:' + ($(this).attr('width') || '') + ' - C:' + $(this).attr('colspan');
+ $(this).attr('title', text);
+ });
+ }
+ this.$target.toggleClass('oe_layout_debugging');
+ },
+ process: function($tag, layout) {
+ var self = this;
+ if ($tag.attr('layout') === 'auto') {
+ $tag.addClass('oe_form_autolayout');
+ }
+ layout = $tag.attr('layout') || layout || 'auto';
+ $tag.removeAttr('layout');
+ var tagname = $tag[0].nodeName.toLowerCase();
+ if (this.tags_registry.contains(tagname)) {
+ this.tags_to_init.push($tag);
+ return $tag;
+ }
+ var fn = self['process_' + tagname];
+ if (fn) {
+ var args = [].slice.call(arguments);
+ args[0] = $tag;
+ args[1] = layout;
+ return fn.apply(self, args);
+ } else {
+ // generic tag handling, just process children
+ $tag.children().each(function() {
+ self.process($(this), layout);
+ });
+ self.handle_common_properties($tag, $tag);
+ $tag.removeAttr("modifiers");
+ return $tag;
+ }
+ },
+ process_sheet: function() {
+ this.process_form.apply(this, arguments);
+ },
+ process_form: function($form, layout) {
+ var $new_form = this.render_element('FormRenderingForm', layout, $form.getAttributes());
+ var $dst = (layout === 'auto') ? $new_form.find('group:first') : $new_form;
+ $new_form.attr("modifiers", $form.attr("modifiers"));
+ $form.children().appendTo($dst);
+ if ($form[0] === this.$form[0]) {
+ // If root element, replace it
+ this.$form = $new_form;
+ } else {
+ $form.before($new_form).remove();
+ }
+ this.process($new_form);
+ },
+ preprocess_field: function($field) {
+ var self = this;
+ var name = $field.attr('name'),
+ field_colspan = parseInt($field.attr('colspan'), 10),
+ field_modifiers = JSON.parse($field.attr('modifiers') || '{}');
+
+ if ($field.attr('nolabel') === '1')
+ return;
+ $field.attr('nolabel', '1');
+ var found = false;
+ this.$form.find('label[for="' + name + '"]').each(function(i ,el) {
+ $(el).parents().each(function(unused, tag) {
+ var name = tag.tagName.toLowerCase();
+ if (name === "field" || name in self.tags_registry.map)
+ found = true;
+ });
+ });
+ if (found)
+ return;
+
+ $label = $('<label/>').attr({
+ 'for' : name,
+ "modifiers": JSON.stringify({invisible: field_modifiers.invisible}),
+ "string": $field.attr('string'),
+ "help": $field.attr('help'),
+ });
+ $label.insertBefore($field);
+ if (field_colspan > 1) {
+ $field.attr('colspan', field_colspan - 1);
+ }
+ return $label;
+ },
+ process_field: function($field, layout) {
+ var $label = this.preprocess_field($field);
+ if ($label)
+ this.process($label, layout);
+ this.fields_to_init.push($field);
+ return $field;
+ },
+ process_group: function($group, layout) {
+ var self = this;
+ if ($group.parent().is('.oe_form_group_cell')) {
+ $group.parent().addClass('oe_form_group_nested');
+ }
+ $group.children('field').each(function() {
+ self.preprocess_field($(this));
+ });
+ var $new_group = this.render_element('FormRenderingGroup', layout, $group.getAttributes()),
+ $table;
+ if ($new_group.is('table')) {
+ $table = $new_group;
+ } else {
+ $table = $new_group.find('table:first');
+ }
+ $table.addClass('oe_form_group');
+ var $tr, $td,
+ cols = parseInt($group.attr('col') || 4, 10),
+ row_cols = cols;
+
+ var children = [];
+ $group.children().each(function(a,b,c) {
+ var $child = $(this),
+ colspan = parseInt($child.attr('colspan') || 1, 10),
+ tagName = $child[0].tagName.toLowerCase();
+ if (tagName === 'newline') {
+ $tr = null;
+ return;
+ }
+ if (!$tr || row_cols < colspan) {
+ $tr = $('<tr/>').addClass('oe_form_group_row').appendTo($table);
+ row_cols = cols;
+ }
+ row_cols -= colspan;
+
+ $td = $('<td/>').addClass('oe_form_group_cell').attr('colspan', colspan);
+ // invisibility transfer
+ var field_modifiers = JSON.parse($child.attr('modifiers') || '{}');
+ var invisible = field_modifiers.invisible;
+ field_modifiers.invisible = undefined;
+ $child.attr('modifiers', JSON.stringify(field_modifiers));
+ self.handle_common_properties($td, $("<dummy>").attr("modifiers", JSON.stringify({invisible: invisible})));
+
+ $tr.append($td.append($child));
+ children.push($child[0]);
+ });
+ if (row_cols && $td) {
+ $td.attr('colspan', parseInt($td.attr('colspan'), 10) + row_cols);
+ }
+ $group.before($new_group).remove();
+
+ // Now compute width of cells
+ $table.find('> tbody > tr').each(function() {
+ var to_compute = [],
+ row_cols = cols,
+ total = 100;
+ $(this).children().each(function() {
+ var $td = $(this),
+ $child = $td.children(':first');
+ switch ($child[0].tagName.toLowerCase()) {
+ case 'separator':
+ if ($child.attr('orientation') === 'vertical') {
+ $td.addClass('oe_vertical_separator').attr('width', '1');
+ $td.empty();
+ row_cols--;
+ }
+ break;
+ case 'label':
+ if ($child.attr('for')) {
+ $td.attr('width', '1%');
+ row_cols--;
+ total--;
+ }
+ break;
+ default:
+ to_compute.push($td);
+ }
+ });
+ var unit = Math.floor(total / row_cols);
+ _.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;
+ });
+ });
+ _.each(children, function(el) {
+ self.process($(el));
+ });
+ this.handle_common_properties($new_group, $group);
+ return $new_group;
+ },
+ process_notebook: function($notebook, layout) {
+ var self = this;
+ var pages = [];
+ $notebook.find('> page').each(function() {
+ 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', layout, page_attrs);
+ var $dst = (layout === 'auto') ? $new_page.find('group:first') : $new_page;
+ $page.children().appendTo($dst);
+ $page.before($new_page).remove();
+ self.handle_common_properties($new_page, $page);
+ });
+ var $new_notebook = this.render_element('FormRenderingNotebook', layout, { pages : pages });
+ $notebook.children().appendTo($new_notebook);
+ $notebook.before($new_notebook).remove();
+ $new_notebook.children().each(function() {
+ self.process($(this));
+ });
+ $new_notebook.tabs();
+ this.handle_common_properties($new_notebook, $notebook);
+ return $new_notebook;
+ },
+ process_separator: function($separator, layout) {
+ var $new_separator = this.render_element('FormRenderingSeparator', layout, $separator.getAttributes());
+ $separator.before($new_separator).remove();
+ this.handle_common_properties($new_separator, $separator);
+ return $new_separator;
+ },
+ process_label: function($label, layout) {
+ var name = $label.attr("for"),
+ field_orm = this.fvg.fields[name];
+ var dict = {
+ string: $label.attr('string') || (field_orm || {}).string || '',
+ help: $label.attr('help') || (field_orm || {}).help || '',
+ _for: name ? _.uniqueId('oe-field-input-') : undefined,
+ };
+ var align = parseFloat(dict.align);
+ if (isNaN(align) || align === 1) {
+ align = 'right';
+ } else if (align === 0) {
+ align = 'left';
+ } else {
+ align = 'center';
+ }
+ dict.align = align;
+ var $new_label = this.render_element('FormRenderingLabel', layout, dict);
+ $label.before($new_label).remove();
+ this.handle_common_properties($new_label, $label);
+ if (name) {
+ this.labels[name] = $new_label;
+ }
+ return $new_label;
+ },
+ handle_common_properties: function($new_element, $node) {
+ var str_modifiers = $node.attr("modifiers") || "{}"
+ var modifiers = JSON.parse(str_modifiers);
+ if (modifiers.invisible !== undefined)
+ new instance.web.form.InvisibilityChanger(this.view, this.view, modifiers.invisible, $new_element);
+ $new_element.addClass($node.attr("class") || "");
+ },
+});
+
+instance.web.form.FormRenderingEngineReadonly = instance.web.form.FormRenderingEngine.extend({
+ alter_field: function(field) {
+ field.set({"force_readonly": true});
+ },
+});
+
+instance.web.form.FormDialog = instance.web.Dialog.extend({
init: function(parent, options, view_id, dataset) {
this._super(parent, options);
this.dataset = dataset;
@@ -736,8 +1214,7 @@ openerp.web.FormDialog = openerp.web.Dialog.extend({
},
start: function() {
this._super();
- this.form = new openerp.web.FormView(this, this.dataset, this.view_id, {
- sidebar: false,
+ this.form = new instance.web.FormView(this, this.dataset, this.view_id, {
pager: false
});
this.form.appendTo(this.$element);
@@ -758,62 +1235,7 @@ openerp.web.FormDialog = openerp.web.Dialog.extend({
}
});
-/** @namespace */
-openerp.web.form = {};
-
-openerp.web.form.SidebarAttachments = openerp.web.OldWidget.extend({
- init: function(parent, form_view) {
- var $section = parent.add_section(_t('Attachments'), 'attachments');
- this.$div = $('<div class="oe-sidebar-attachments"></div>');
- $section.append(this.$div);
-
- this._super(parent, $section.attr('id'));
- this.view = form_view;
- },
- do_update: function() {
- if (!this.view.datarecord.id) {
- this.on_attachments_loaded([]);
- } else {
- (new openerp.web.DataSetSearch(
- this, 'ir.attachment', this.view.dataset.get_context(),
- [
- ['res_model', '=', this.view.dataset.model],
- ['res_id', '=', this.view.datarecord.id],
- ['type', 'in', ['binary', 'url']]
- ])).read_slice(['name', 'url', 'type'], {}).then(this.on_attachments_loaded);
- }
- },
- on_attachments_loaded: function(attachments) {
- this.attachments = attachments;
- this.$div.html(QWeb.render('FormView.sidebar.attachments', this));
- this.$element.find('.oe-binary-file').change(this.on_attachment_changed);
- this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
- },
- on_attachment_changed: function(e) {
- window[this.element_id + '_iframe'] = this.do_update;
- var $e = $(e.target);
- if ($e.val() != '') {
- this.$element.find('form.oe-binary-form').submit();
- $e.parent().find('input[type=file]').prop('disabled', true);
- $e.parent().find('button').prop('disabled', true).find('img, span').toggle();
- }
- },
- on_attachment_delete: function(e) {
- var self = this, $e = $(e.currentTarget);
- var name = _.str.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
- if (confirm(_.str.sprintf(_t("Do you really want to delete the attachment %s?"), name))) {
- this.rpc('/web/dataset/unlink', {
- model: 'ir.attachment',
- ids: [parseInt($e.attr('data-id'))]
- }, function(r) {
- $e.parent().remove();
- self.do_notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
- });
- }
- }
-});
-
-openerp.web.form.compute_domain = function(expr, fields) {
+instance.web.form.compute_domain = function(expr, fields) {
var stack = [];
for (var i = expr.length - 1; i >= 0; i--) {
var ex = expr[i];
@@ -842,7 +1264,7 @@ openerp.web.form.compute_domain = function(expr, fields) {
_t("Unknown field %s in domain %s"),
ex[0], JSON.stringify(expr)));
}
- var field_value = field.get_value ? fields[ex[0]].get_value() : fields[ex[0]].value;
+ var field_value = field.get_value ? field.get_value() : field.value;
var op = ex[1];
var val = ex[2];
@@ -884,60 +1306,84 @@ openerp.web.form.compute_domain = function(expr, fields) {
return _.all(stack, _.identity);
};
-openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.form.Widget# */{
- form_template: 'Widget',
+/**
+ * Must be applied over an class already possessing the GetterSetterMixin.
+ *
+ * Apply the result of the "invisible" domain to this.$element.
+ */
+instance.web.form.InvisibilityChangerMixin = {
+ init: function(field_manager, invisible_domain) {
+ this._ic_field_manager = field_manager
+ this._ic_invisible_modifier = invisible_domain;
+ this._ic_field_manager.on("view_content_has_changed", this, function() {
+ var result = this._ic_invisible_modifier === undefined ? false :
+ instance.web.form.compute_domain(this._ic_invisible_modifier, this._ic_field_manager.fields);
+ this.set({"invisible": result});
+ });
+ this.set({invisible: this._ic_invisible_modifier === true});
+ },
+ start: function() {
+ var check_visibility = function() {
+ if (this.get("invisible")) {
+ this.$element.hide();
+ } else {
+ this.$element.show();
+ }
+ };
+ this.on("change:invisible", this, check_visibility);
+ _.bind(check_visibility, this)();
+ },
+};
+
+instance.web.form.InvisibilityChanger = instance.web.Class.extend(_.extend({}, instance.web.GetterSetterMixin, instance.web.form.InvisibilityChangerMixin, {
+ init: function(parent, field_manager, invisible_domain, $element) {
+ this.setParent(parent);
+ instance.web.GetterSetterMixin.init.call(this);
+ instance.web.form.InvisibilityChangerMixin.init.call(this, field_manager, invisible_domain);
+ this.$element = $element;
+ this.start();
+ },
+}));
+
+instance.web.form.Widget = instance.web.Widget.extend(_.extend({}, instance.web.form.InvisibilityChangerMixin, {
/**
- * @constructs openerp.web.form.Widget
- * @extends openerp.web.OldWidget
+ * @constructs instance.web.form.Widget
+ * @extends instance.web.Widget
*
* @param view
* @param node
*/
init: function(view, node) {
+ this._super(view);
this.view = view;
this.node = node;
this.modifiers = JSON.parse(this.node.attrs.modifiers || '{}');
- this.always_invisible = (this.modifiers.invisible && this.modifiers.invisible === true);
- this.type = this.type || node.tag;
- this.element_name = this.element_name || this.type;
-
- this._super(view);
-
- this.children = node.children;
- this.colspan = parseInt(node.attrs.colspan || 1, 10);
- this.decrease_max_width = 0;
-
- this.string = this.string || node.attrs.string;
- this.help = this.help || node.attrs.help;
- this.invisible = this.modifiers['invisible'] === true;
- this.classname = 'oe_form_' + this.type;
-
- this.align = parseFloat(this.node.attrs.align);
- if (isNaN(this.align) || this.align === 1) {
- this.align = 'right';
- } else if (this.align === 0) {
- this.align = 'left';
- } else {
- this.align = 'center';
- }
+ instance.web.form.InvisibilityChangerMixin.init.call(this, view, this.modifiers.invisible);
- this.width = this.node.attrs.width;
+ this.view.on("view_content_has_changed", this, this.process_modifiers);
+ },
+ renderElement: function() {
+ this._super();
+ this.$element.addClass(this.node.attrs["class"] || "");
+ },
+ start: function() {
+ this._super();
+ instance.web.form.InvisibilityChangerMixin.start.call(this);
},
destroy: function() {
- this._super.apply(this, arguments);
$.fn.tipsy.clear();
+ this._super.apply(this, arguments);
},
process_modifiers: function() {
- var compute_domain = openerp.web.form.compute_domain;
+ var compute_domain = instance.web.form.compute_domain;
+ var to_set = {};
for (var a in this.modifiers) {
- this[a] = compute_domain(this.modifiers[a], this.view.fields);
+ if (!_.include(["invisible"], a)) {
+ var val = compute_domain(this.modifiers[a], this.view.fields);
+ to_set[a] = val;
+ }
}
- },
- update_dom: function() {
- this.$element.toggle(!this.invisible);
- },
- renderElement: function() {
- this.$element.html(QWeb.render(this.form_template, { "widget": this }));
+ this.set(to_set);
},
do_attach_tooltip: function(widget, trigger, options) {
widget = widget || this;
@@ -947,12 +1393,12 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo
delayOut: 0,
fade: true,
title: function() {
- var template = widget.form_template + '.tooltip';
+ var template = widget.template + '.tooltip';
if (!QWeb.has_template(template)) {
template = 'WidgetLabel.tooltip';
}
return QWeb.render(template, {
- debug: openerp.connection.debug,
+ debug: instance.connection.debug,
widget: widget
})},
gravity: $.fn.tipsy.autoBounds(50, 'nw'),
@@ -979,7 +1425,7 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo
},
_build_eval_context: function(blacklist) {
var a_dataset = this.view.dataset;
- return new openerp.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values(blacklist));
+ return new instance.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values(blacklist));
},
/**
* Builds a new context usable for operations related to fields by merging
@@ -994,7 +1440,7 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo
if (v_context.__ref || true) { //TODO: remove true
var fields_values = this._build_eval_context(blacklist);
- v_context = new openerp.web.CompoundContext(v_context).set_eval_context(fields_values);
+ v_context = new instance.web.CompoundContext(v_context).set_eval_context(fields_values);
}
return v_context;
},
@@ -1005,235 +1451,28 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo
var final_domain = n_domain !== null ? n_domain : f_domain;
if (!(final_domain instanceof Array) || true) { //TODO: remove true
var fields_values = this._build_eval_context();
- final_domain = new openerp.web.CompoundDomain(final_domain).set_eval_context(fields_values);
+ final_domain = new instance.web.CompoundDomain(final_domain).set_eval_context(fields_values);
}
return final_domain;
}
-});
+}));
-openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({
- form_template: 'WidgetFrame',
- init: function(view, node) {
- this._super(view, node);
- this.columns = parseInt(node.attrs.col || 4, 10);
- this.x = 0;
- this.y = 0;
- this.table = [];
- this.add_row();
- for (var i = 0; i < node.children.length; i++) {
- var n = node.children[i];
- if (n.tag == "newline") {
- this.add_row();
- } else {
- this.handle_node(n);
- }
- }
- this.set_row_cells_with(this.table[this.table.length - 1]);
- },
- renderElement: function() {
- this._super();
- var self = this;
- _.each(this.table, function(row) {
- _.each(row, function(td) {
- td.$element = self.$element.find('.' + td.element_class);
- td.renderElement();
- });
- });
- },
- start: function() {
- _.each(this.table, function(row) {
- _.each(row, function(td) {
- td.start();
- });
- });
- },
- add_row: function(){
- if (this.table.length) {
- this.set_row_cells_with(this.table[this.table.length - 1]);
- }
- var row = [];
- this.table.push(row);
- this.x = 0;
- this.y += 1;
- return row;
- },
- set_row_cells_with: function(row) {
- var bypass = 0,
- max_width = 100,
- row_length = row.length;
- for (var i = 0; i < row.length; i++) {
- if (row[i].always_invisible) {
- row_length--;
- } else {
- bypass += row[i].width === undefined ? 0 : 1;
- max_width -= row[i].decrease_max_width;
- }
- }
- var size_unit = Math.round(max_width / (this.columns - bypass)),
- colspan_sum = 0;
- for (var i = 0; i < row.length; i++) {
- var w = row[i];
- if (w.always_invisible) {
- continue;
- }
- colspan_sum += w.colspan;
- if (w.width === undefined) {
- var width = (i === row_length - 1 && colspan_sum === this.columns) ? max_width : Math.round(size_unit * w.colspan);
- max_width -= width;
- w.width = width + '%';
- }
- }
- },
- handle_node: function(node) {
- var type = {};
- if (node.tag == 'field') {
- type = this.view.fields_view.fields[node.attrs.name] || {};
- if (node.attrs.widget == 'statusbar' && node.attrs.nolabel !== '1') {
- // This way we can retain backward compatibility between addons and old clients
- node.attrs.colspan = (parseInt(node.attrs.colspan, 10) || 1) + 1;
- node.attrs.nolabel = '1';
- }
- }
- var widget = instanciate_widget(this.view.registry.get_any(
- [node.attrs.widget, type.type, node.tag]), this.view, node);
- if (node.tag == 'field') {
- if (!this.view.default_focus_field || node.attrs.default_focus == '1') {
- this.view.default_focus_field = widget;
- }
- if (node.attrs.nolabel != '1') {
- var label = instanciate_widget(this.view.registry.get_object('label'), this.view, node);
- label["for"] = widget;
- this.add_widget(label, widget.colspan + 1);
- }
- }
- this.add_widget(widget);
- },
- add_widget: function(widget, colspan) {
- var current_row = this.table[this.table.length - 1];
- if (!widget.always_invisible) {
- colspan = colspan || widget.colspan;
- if (current_row.length && (this.x + colspan) > this.columns) {
- current_row = this.add_row();
- }
- this.x += widget.colspan;
- }
- current_row.push(widget);
- return widget;
- }
-});
-
-openerp.web.form.WidgetGroup = openerp.web.form.WidgetFrame.extend({
- form_template: 'WidgetGroup'
-}),
-
-openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({
- form_template: 'WidgetNotebook',
- init: function(view, node) {
- this._super(view, node);
- this.pages = [];
- for (var i = 0; i < node.children.length; i++) {
- var n = node.children[i];
- if (n.tag == "page") {
- var page = instanciate_widget(this.view.registry.get_object('notebookpage'),
- this.view, n, this, this.pages.length);
- this.pages.push(page);
- }
- }
- },
- renderElement: function() {
- this._super();
- var self = this;
- _.each(this.pages, function(page) {
- page.$element = self.$element.find('.' + page.element_class);
- page.renderElement();
- });
- },
- start: function() {
- var self = this;
- this._super.apply(this, arguments);
- this.$element.find('> ul > li').each(function (index, tab_li) {
- var page = self.pages[index],
- id = _.uniqueId(self.element_name + '-');
- page.element_id = id;
- $(tab_li).find('a').attr('href', '#' + id);
- });
- this.$element.find('> div').each(function (index, page) {
- page.id = self.pages[index].element_id;
- });
- this.$element.tabs();
- this.view.on_button_new.add_first(this.do_select_first_visible_tab);
- if (openerp.connection.debug) {
- this.do_attach_tooltip(this, this.$element.find('ul:first'), {
- gravity: 's'
- });
- }
- _.each(this.pages, function(page) {
- page.start();
- });
- },
- do_select_first_visible_tab: function() {
- for (var i = 0; i < this.pages.length; i++) {
- var page = this.pages[i];
- if (page.invisible === false) {
- this.$element.tabs('select', page.index);
- break;
- }
- }
- }
-});
-
-openerp.web.form.WidgetNotebookPage = openerp.web.form.WidgetFrame.extend({
- form_template: 'WidgetNotebookPage',
- init: function(view, node, notebook, index) {
- this.notebook = notebook;
- this.index = index;
- this.element_name = 'page_' + index;
- this._super(view, node);
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element_tab = this.notebook.$element.find(
- '> ul > li:eq(' + this.index + ')');
- },
- update_dom: function() {
- if (this.invisible && this.index === this.notebook.$element.tabs('option', 'selected')) {
- this.notebook.do_select_first_visible_tab();
- }
- this.$element_tab.toggle(!this.invisible);
- this.$element.toggle(!this.invisible);
- }
-});
-
-openerp.web.form.WidgetSeparator = openerp.web.form.Widget.extend({
- form_template: 'WidgetSeparator',
- init: function(view, node) {
- this._super(view, node);
- this.orientation = node.attrs.orientation || 'horizontal';
- if (this.orientation === 'vertical') {
- this.width = '1';
- }
- this.classname += '_' + this.orientation;
- }
-});
-
-openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
- form_template: 'WidgetButton',
+instance.web.form.WidgetButton = instance.web.form.Widget.extend({
+ template: 'WidgetButton',
init: function(view, node) {
this._super(view, node);
this.force_disabled = false;
- if (this.string) {
- // We don't have button key bindings in the webclient
- this.string = this.string.replace(/_/g, '');
- }
- if (node.attrs.default_focus == '1') {
+ this.string = (this.node.attrs.string || '').replace(/_/g, '');
+ if (this.node.attrs.default_focus == '1') {
// TODO fme: provide enter key binding to widgets
this.view.default_focus_button = this;
}
+ this.view.on('view_content_has_changed', this, this.check_disable);
},
start: function() {
this._super.apply(this, arguments);
- this.$element.find("button").click(this.on_click);
- if (this.help || openerp.connection.debug) {
+ this.$element.click(this.on_click);
+ if (this.node.attrs.help || instance.connection.debug) {
this.do_attach_tooltip();
}
},
@@ -1251,7 +1490,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
var exec_action = function() {
if (self.node.attrs.confirm) {
var def = $.Deferred();
- var dialog = openerp.web.dialog($('<div>' + self.node.attrs.confirm + '</div>'), {
+ var dialog = instance.web.dialog($('<div/>').text(self.node.attrs.confirm), {
title: _t('Confirm'),
modal: true,
buttons: [
@@ -1275,6 +1514,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
}
};
if (!this.node.attrs.special) {
+ this.view.force_dirty = true;
return this.view.recursive_save().pipe(exec_action);
} else {
return exec_action();
@@ -1285,7 +1525,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
var context = this.node.attrs.context;
if (context && context.__ref) {
- context = new openerp.web.CompoundContext(context);
+ context = new instance.web.CompoundContext(context);
context.set_eval_context(this._build_eval_context());
}
@@ -1295,81 +1535,57 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
self.view.reload();
});
},
- update_dom: function() {
- this._super.apply(this, arguments);
- this.check_disable();
- },
check_disable: function() {
- var disabled = (this.readonly || this.force_disabled || !this.view.is_interactible_record());
- this.$element.find('button').prop('disabled', disabled);
- this.$element.find("button").css('color', disabled ? 'grey' : '');
+ var disabled = (this.force_disabled || !this.view.is_interactible_record());
+ this.$element.prop('disabled', disabled);
+ this.$element.css('color', disabled ? 'grey' : '');
}
});
-openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
- form_template: 'WidgetLabel',
- init: function(view, node) {
- this.element_name = 'label_' + node.attrs.name;
-
- this._super(view, node);
-
- if (this.node.tag == 'label' && !this.string && this.node.children.length) {
- this.string = this.node.children[0];
- this.align = 'left';
- }
-
- if (this.node.tag == 'label' && (this.align === 'left' || this.node.attrs.colspan || (this.string && this.string.length > 32))) {
- this.form_template = "WidgetParagraph";
- this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
- // Widgets default to right-aligned, but paragraph defaults to
- // left-aligned
- if (isNaN(parseFloat(this.node.attrs.align))) {
- this.align = 'left';
- }
-
- this.multilines = this.string && _.str.lines(this.string).length > 1;
- } else {
- this.colspan = 1;
- this.width = '1%';
- this.decrease_max_width = 1;
- this.nowrap = true;
- }
- },
- renderElement: function() {
- var rendered;
- if (this['for'] && this.type !== 'label') {
- rendered = QWeb.render(this.form_template, {widget: this['for']});
- } else {
- // Actual label widgets should not have a false and have type label
- rendered = QWeb.render(this.form_template, {widget: this});
- }
- this.$element.html(rendered);
- },
- start: function() {
- this._super();
- var self = this;
- if (this['for'] && (this['for'].help || openerp.connection.debug)) {
- this.do_attach_tooltip(self['for']);
- }
- this.$element.find("label").dblclick(function() {
- var widget = self['for'] || self;
- openerp.log(widget.element_class , widget);
- window.w = widget;
- });
- }
-});
+/**
+ * Interface implemented by the form view or any other object
+ * able to provide the features necessary for the fields to work.
+ *
+ * Properties:
+ * - display_invalid_fields : if true, all fields where is_valid() return true should
+ * be displayed as invalid.
+ * Events:
+ * - view_content_has_changed : when the values of the fields have changed. When
+ * this event is triggered all fields should reprocess their modifiers.
+ */
+instance.web.form.FieldManagerInterface = {
+ /**
+ * Must return the asked field as in fields_get.
+ */
+ get_field: function(field_name) {},
+ /**
+ * Called by the field when the translate button is clicked.
+ */
+ open_translate_dialog: function(field) {},
+ /**
+ * Returns true when the view is in create mode.
+ */
+ is_create_mode: function() {},
+};
/**
* Interface to be implemented by fields.
*
- * Novajs Attributes:
- * - ...
- *
- * Novajs Events:
- * - ...
+ * Properties:
+ * - readonly: boolean. If set to true the field should appear in readonly mode.
+ * - force_readonly: boolean, When it is true, the field should always appear
+ * in read only mode, no matter what the value of the "readonly" property can be.
+ * Events:
+ * - changed_value: triggered to inform the view to check on_changes
*
*/
-openerp.web.form.FieldInterface = {
+instance.web.form.FieldInterface = {
+ /**
+ * Constructor takes 2 arguments:
+ * - field_manager: Implements FieldManagerInterface
+ * - node: the "<field>" node in json form
+ */
+ init: function(field_manager, node) {},
/**
* Called by the form view to indicate the value of the field.
*
@@ -1386,7 +1602,7 @@ openerp.web.form.FieldInterface = {
* as well as any format commonly returned in a on_change. It must be able to autodetect those formats as
* no information is ever given to know which format is used.
*/
- set_value: function(value) {},
+ set_value: function(value_) {},
/**
* Get the current value of the widget.
*
@@ -1405,221 +1621,307 @@ openerp.web.form.FieldInterface = {
* syntax for "read" and "write" (example: m2o: set_value([0, "Administrator"]), get_value() => 0).
*/
get_value: function() {},
+ /**
+ * Inform the current object of the id it should use to match a html <label> that exists somewhere in the
+ * view.
+ */
+ set_input_id: function(id) {},
+ /**
+ * Returns true if is_syntax_valid() returns true and the value is semantically
+ * valid too according to the semantic restrictions applied to the field.
+ */
+ is_valid: function() {},
+ /**
+ * Returns true if the field holds a value which is syntaxically correct, ignoring
+ * the potential semantic restrictions applied to the field.
+ */
+ is_syntax_valid: function() {},
+ /**
+ * Must set the focus on the field.
+ */
+ focus: function() {},
};
/**
- * Abstract class for classes implementing FieldInterface. Should be renamed to AbstractField some
- * day.
+ * Abstract class for classes implementing FieldInterface.
+ *
+ * Properties:
+ * - effective_readonly: when it is true, the widget is displayed as readonly. Vary depending
+ * the values of the "readonly" property and the "force_readonly" property on the field manager.
+ * - value: useful property to hold the value of the field. By default, set_value() and get_value()
+ * set and retrieve the value property. Changing the value property also triggers automatically
+ * a 'changed_value' event that inform the view to trigger on_changes.
+ *
*/
-openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.form.Field# */{
+instance.web.form.AbstractField = instance.web.form.Widget.extend(/** @lends instance.web.form.AbstractField# */{
/**
- * @constructs openerp.web.form.Field
- * @extends openerp.web.form.Widget
+ * @constructs instance.web.form.AbstractField
+ * @extends instance.web.form.Widget
*
- * @param view
+ * @param field_manager
* @param node
*/
- init: function(view, node) {
- this.name = node.attrs.name;
- this.value = undefined;
- view.fields[this.name] = this;
- view.fields_order.push(this.name);
- this.type = node.attrs.widget || view.fields_view.fields[node.attrs.name].type;
- this.element_name = "field_" + this.name + "_" + this.type;
-
- this._super(view, node);
-
- if (node.attrs.nolabel != '1' && this.colspan > 1) {
- this.colspan--;
- }
- this.field = view.fields_view.fields[node.attrs.name] || {};
- this.string = node.attrs.string || this.field.string;
- this.help = node.attrs.help || this.field.help;
- this.nolabel = (this.field.nolabel || node.attrs.nolabel) === '1';
- this.readonly = this.modifiers['readonly'] === true;
- this.required = this.modifiers['required'] === true;
- this.invalid = this.dirty = false;
-
- this.classname = 'oe_form_field_' + this.type;
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
+ this.field_manager = field_manager;
+ this.name = this.node.attrs.name;
+ this.set({'value': false});
+ this.field = this.field_manager.get_field(this.name);
+ this.set({required: this.modifiers['required'] === true});
+
+ // some events to make the property "effective_readonly" sync automatically with "readonly" and
+ // "force_readonly"
+ this.set({"readonly": this.modifiers['readonly'] === true});
+ var test_effective_readonly = function() {
+ this.set({"effective_readonly": this.get("readonly") || !!this.get("force_readonly")});
+ };
+ this.on("change:readonly", this, test_effective_readonly);
+ this.on("change:force_readonly", this, test_effective_readonly);
+ _.bind(test_effective_readonly, this)();
+
+ this.on("change:value", this, function() {
+ if (! this._inhibit_on_change)
+ this.trigger('changed_value');
+ this._check_css_flags();
+ });
},
start: function() {
this._super.apply(this, arguments);
if (this.field.translate) {
- this.view.translatable_fields.push(this);
this.$element.addClass('oe_form_field_translatable');
- this.$element.find('.oe_field_translate').click(this.on_translate);
+ this.$element.find('.oe_field_translate').click(_.bind(function() {
+ this.field_manager.open_translate_dialog(this);
+ }, this));
}
- if (this.nolabel && openerp.connection.debug) {
+ if (instance.connection.debug) {
this.do_attach_tooltip(this, this.$element);
}
+ if (!this.disable_utility_classes) {
+ var set_required = function() {
+ this.$element.toggleClass('oe_form_required', this.get("required"));
+ };
+ this.on("change:required", this, set_required);
+ _.bind(set_required, this)();
+ }
},
- set_value: function(value) {
- this.value = value;
- this.invalid = false;
- this.update_dom();
- this.on_value_changed();
- },
- set_value_from_ui: function() {
- this.on_value_changed();
- },
- on_value_changed: function() {
- },
- on_translate: function() {
- this.view.open_translate_dialog(this);
+ set_value: function(value_) {
+ this._inhibit_on_change = true;
+ this.set({'value': value_});
+ this._inhibit_on_change = false;
},
get_value: function() {
- return this.value;
+ return this.get('value');
},
is_valid: function() {
- return !this.invalid;
+ return this.is_syntax_valid() && (! this.get('required') || ! this.is_false());
},
- is_dirty: function() {
- return this.dirty && !this.readonly;
+ is_syntax_valid: function() {
+ return true;
},
- get_on_change_value: function() {
- return this.get_value();
+ /**
+ * Method useful to implement to ease validity testing. Must return true if the current
+ * value is similar to false in OpenERP.
+ */
+ is_false: function() {
+ return this.get('value') === false;
},
- update_dom: function(show_invalid) {
- this._super.apply(this, arguments);
+ _check_css_flags: function(show_invalid) {
if (this.field.translate) {
- this.$element.find('.oe_field_translate').toggle(!!this.view.datarecord.id);
+ this.$element.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode());
}
if (!this.disable_utility_classes) {
- this.$element.toggleClass('disabled', this.readonly);
- this.$element.toggleClass('required', this.required);
- if (show_invalid) {
- this.$element.toggleClass('invalid', !this.is_valid());
+ if (this.field_manager.get('display_invalid_fields')) {
+ this.$element.toggleClass('oe_form_invalid', !this.is_valid());
}
}
},
- on_ui_change: function() {
- this.dirty = true;
- this.validate();
- if (this.is_valid()) {
- this.set_value_from_ui();
- this.view.do_onchange(this);
- this.view.on_form_changed(true);
- this.view.do_notify_change();
- } else {
- this.update_dom(true);
- }
- },
- validate: function() {
- this.invalid = false;
+ focus: function() {
},
- focus: function($element) {
- if ($element) {
- setTimeout(function() {
- $element.focus();
- }, 50);
- }
- },
- reset: function() {
- this.dirty = false;
+ /**
+ * Utility method to focus an element, but only after a small amount of time.
+ */
+ delay_focus: function($elem) {
+ setTimeout(function() {
+ $elem.focus();
+ }, 50);
},
+ /**
+ * Utility method to get the widget options defined in the field xml description.
+ */
get_definition_options: function() {
if (!this.definition_options) {
var str = this.node.attrs.options || '{}';
this.definition_options = JSON.parse(str);
}
return this.definition_options;
- }
+ },
+ set_input_id: function(id) {
+ this.id_for_label = id;
+ },
});
-openerp.web.form.FieldChar = openerp.web.form.Field.extend({
- form_template: 'FieldChar',
- init: function (view, node) {
- this._super(view, node);
- this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
- },
+/**
+ * A mixin to apply on any field that has to completely re-render when its readonly state
+ * switch.
+ */
+instance.web.form.ReinitializeFieldMixin = {
+ /**
+ * Default implementation of start(), use it or call explicitly initialize_field().
+ */
start: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').change(this.on_ui_change);
+ this._super();
+ this.initialize_field();
},
- set_value: function(value) {
- this._super.apply(this, arguments);
- var show_value = openerp.web.format_value(value, this, '');
- this.$element.find('input').val(show_value);
- return show_value;
+ initialize_field: function() {
+ this.on("change:effective_readonly", this, function() {
+ this.destroy_content();
+ this.renderElement();
+ this.initialize_content();
+ this.render_value();
+ });
+ this.initialize_content();
+ this.render_value();
},
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').prop('readonly', this.readonly);
+ /**
+ * Called to destroy anything that could have been created previously, called before a
+ * re-initialization.
+ */
+ destroy_content: function() {},
+ /**
+ * Called to initialize the content.
+ */
+ initialize_content: function() {},
+ /**
+ * Called to render the value. Should also be explicitly called at the end of a set_value().
+ */
+ render_value: function() {},
+};
+
+instance.web.form.FieldChar = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldChar',
+ init: function (field_manager, node) {
+ this._super(field_manager, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
},
- set_value_from_ui: function() {
- this.value = openerp.web.parse_value(this.$element.find('input').val(), this);
- this._super();
+ initialize_content: function() {
+ var self = this;
+ this.$element.find('input').change(function() {
+ self.set({'value': instance.web.parse_value(self.$element.find('input').val(), self)});
+ });
},
- validate: function() {
- this.invalid = false;
- try {
- var value = openerp.web.parse_value(this.$element.find('input').val(), this, '');
- this.invalid = this.required && value === '';
- } catch(e) {
- this.invalid = true;
+ set_value: function(value_) {
+ this._super(value_);
+ this.render_value();
+ },
+ render_value: function() {
+ var show_value = instance.web.format_value(this.get('value'), this, '');
+ if (!this.get("effective_readonly")) {
+ this.$element.find('input').val(show_value);
+ } else {
+ if (this.password) {
+ show_value = new Array(show_value.length + 1).join('*');
+ }
+ this.$element.text(show_value);
}
},
- focus: function($element) {
- this._super($element || this.$element.find('input:first'));
+ is_syntax_valid: function() {
+ if (!this.get("effective_readonly")) {
+ try {
+ var value_ = instance.web.parse_value(this.$element.find('input').val(), this, '');
+ return true;
+ } catch(e) {
+ return false;
+ }
+ }
+ return true;
+ },
+ is_false: function() {
+ return this.get('value') === '';
+ },
+ focus: function() {
+ this.delay_focus(this.$element.find('input:first'));
}
-});
+}));
-openerp.web.form.FieldID = openerp.web.form.FieldChar.extend({
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').prop('readonly', true);
- }
+instance.web.form.FieldID = instance.web.form.FieldChar.extend({
+
});
-openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({
- form_template: 'FieldEmail',
- start: function() {
- this._super.apply(this, arguments);
+instance.web.form.FieldEmail = instance.web.form.FieldChar.extend({
+ template: 'FieldEmail',
+ initialize_content: function() {
+ this._super();
this.$element.find('button').click(this.on_button_clicked);
},
+ render_value: function() {
+ if (!this.get("effective_readonly")) {
+ this._super();
+ } else {
+ this.$element.find('a')
+ .attr('href', 'mailto:' + this.get('value'))
+ .text(this.get('value'));
+ }
+ },
on_button_clicked: function() {
- if (!this.value || !this.is_valid()) {
+ if (!this.get('value') || !this.is_syntax_valid()) {
this.do_warn("E-mail error", "Can't send email to invalid e-mail address");
} else {
- location.href = 'mailto:' + this.value;
+ location.href = 'mailto:' + this.get('value');
}
}
});
-openerp.web.form.FieldUrl = openerp.web.form.FieldChar.extend({
- form_template: 'FieldUrl',
- start: function() {
- this._super.apply(this, arguments);
+instance.web.form.FieldUrl = instance.web.form.FieldChar.extend({
+ template: 'FieldUrl',
+ initialize_content: function() {
+ this._super();
this.$element.find('button').click(this.on_button_clicked);
},
+ render_value: function() {
+ if (!this.get("effective_readonly")) {
+ this._super();
+ } else {
+ var tmp = this.get('value');
+ var s = /(\w+):(.+)/.exec(tmp);
+ if (!s) {
+ tmp = "http://" + this.get('value');
+ }
+ this.$element.find('a').attr('href', tmp).text(tmp);
+ }
+ },
on_button_clicked: function() {
- if (!this.value) {
+ if (!this.get('value')) {
this.do_warn("Resource error", "This resource is empty");
} else {
- window.open(this.value);
+ var url = $.trim(this.get('value'));
+ if(/^www\./i.test(url))
+ url = 'http://'+url;
+ window.open(url);
}
}
});
-openerp.web.form.FieldFloat = openerp.web.form.FieldChar.extend({
- init: function (view, node) {
- this._super(view, node);
- if (node.attrs.digits) {
+instance.web.form.FieldFloat = instance.web.form.FieldChar.extend({
+ is_field_number: true,
+ init: function (field_manager, node) {
+ this._super(field_manager, node);
+ this.set({'value': 0});
+ if (this.node.attrs.digits) {
this.digits = py.eval(node.attrs.digits);
} else {
- this.digits = view.fields_view.fields[node.attrs.name].digits;
+ this.digits = this.field.digits;
}
},
- set_value: function(value) {
- if (value === false || value === undefined) {
+ set_value: function(value_) {
+ if (value_ === false || value_ === undefined) {
// As in GTK client, floats default to 0
- value = 0;
+ value_ = 0;
}
- this._super.apply(this, [value]);
+ this._super.apply(this, [value_]);
}
});
-openerp.web.DateTimeWidget = openerp.web.OldWidget.extend({
+instance.web.DateTimeWidget = instance.web.OldWidget.extend({
template: "web.datetimepicker",
jqueryui_object: 'datetimepicker',
type_of_date: "datetime",
@@ -1640,46 +1942,46 @@ openerp.web.DateTimeWidget = openerp.web.OldWidget.extend({
showButtonPanel: true
});
this.$element.find('img.oe_datepicker_trigger').click(function() {
- if (!self.readonly && !self.picker('widget').is(':visible')) {
- self.picker('setDate', self.value ? openerp.web.auto_str_to_date(self.value) : new Date());
+ if (!self.get("effective_readonly") && !self.picker('widget').is(':visible')) {
+ self.picker('setDate', self.get('value') ? instance.web.auto_str_to_date(self.get('value')) : new Date());
self.$input_picker.show();
self.picker('show');
self.$input_picker.hide();
}
});
this.set_readonly(false);
- this.value = false;
+ this.set({'value': false});
},
picker: function() {
return $.fn[this.jqueryui_object].apply(this.$input_picker, arguments);
},
- on_picker_select: function(text, instance) {
+ on_picker_select: function(text, instance_) {
var date = this.picker('getDate');
this.$input.val(date ? this.format_client(date) : '').change();
},
- set_value: function(value) {
- this.value = value;
- this.$input.val(value ? this.format_client(value) : '');
+ set_value: function(value_) {
+ this.set({'value': value_});
+ this.$input.val(value_ ? this.format_client(value_) : '');
},
get_value: function() {
- return this.value;
+ return this.get('value');
},
- set_value_from_ui: function() {
- var value = this.$input.val() || false;
- this.value = this.parse_client(value);
+ set_value_from_ui_: function() {
+ var value_ = this.$input.val() || false;
+ this.set({'value': this.parse_client(value_)});
},
set_readonly: function(readonly) {
this.readonly = readonly;
this.$input.prop('readonly', this.readonly);
this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly);
},
- is_valid: function(required) {
- var value = this.$input.val();
- if (value === "") {
- return !required;
+ is_valid_: function() {
+ var value_ = this.$input.val();
+ if (value_ === "") {
+ return true;
} else {
try {
- this.parse_client(value);
+ this.parse_client(value_);
return true;
} catch(e) {
return false;
@@ -1687,99 +1989,120 @@ openerp.web.DateTimeWidget = openerp.web.OldWidget.extend({
}
},
parse_client: function(v) {
- return openerp.web.parse_value(v, {"widget": this.type_of_date});
+ return instance.web.parse_value(v, {"widget": this.type_of_date});
},
format_client: function(v) {
- return openerp.web.format_value(v, {"widget": this.type_of_date});
+ return instance.web.format_value(v, {"widget": this.type_of_date});
},
on_change: function() {
- if (this.is_valid()) {
- this.set_value_from_ui();
+ if (this.is_valid_()) {
+ this.set_value_from_ui_();
}
}
});
-openerp.web.DateWidget = openerp.web.DateTimeWidget.extend({
+instance.web.DateWidget = instance.web.DateTimeWidget.extend({
jqueryui_object: 'datepicker',
type_of_date: "date"
});
-openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({
- form_template: "EmptyComponent",
+instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: "EmptyComponent",
build_widget: function() {
- return new openerp.web.DateTimeWidget(this);
+ return new instance.web.DateTimeWidget(this);
},
- start: function() {
- var self = this;
- this._super.apply(this, arguments);
- this.datewidget = this.build_widget();
- this.datewidget.on_change.add_last(this.on_ui_change);
- this.datewidget.appendTo(this.$element);
+ destroy_content: function() {
+ if (this.datewidget) {
+ this.datewidget.destroy();
+ this.datewidget = undefined;
+ }
+ },
+ initialize_content: function() {
+ if (!this.get("effective_readonly")) {
+ this.datewidget = this.build_widget();
+ this.datewidget.on_change.add_last(_.bind(function() {
+ this.set({'value': this.datewidget.get_value()});
+ }, this));
+ this.datewidget.appendTo(this.$element);
+ }
},
- set_value: function(value) {
- this._super(value);
- this.datewidget.set_value(value);
+ set_value: function(value_) {
+ this._super(value_);
+ this.render_value();
},
- get_value: function() {
- return this.datewidget.get_value();
+ render_value: function() {
+ if (!this.get("effective_readonly")) {
+ this.datewidget.set_value(this.get('value'));
+ } else {
+ this.$element.text(instance.web.format_value(this.get('value'), this, ''));
+ }
},
- update_dom: function() {
- this._super.apply(this, arguments);
- this.datewidget.set_readonly(this.readonly);
+ is_syntax_valid: function() {
+ if (!this.get("effective_readonly")) {
+ return this.datewidget.is_valid_();
+ }
+ return true;
},
- validate: function() {
- this.invalid = !this.datewidget.is_valid(this.required);
+ is_false: function() {
+ return this.get('value') === '';
},
- focus: function($element) {
- this._super($element || this.datewidget.$input);
+ focus: function() {
+ if (this.datewidget && this.datewidget.$input)
+ this.delay_focus(this.datewidget.$input);
}
-});
+}));
-openerp.web.form.FieldDate = openerp.web.form.FieldDatetime.extend({
+instance.web.form.FieldDate = instance.web.form.FieldDatetime.extend({
build_widget: function() {
- return new openerp.web.DateWidget(this);
+ return new instance.web.DateWidget(this);
}
});
-openerp.web.form.FieldText = openerp.web.form.Field.extend({
- form_template: 'FieldText',
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('textarea').change(this.on_ui_change);
+instance.web.form.FieldText = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldText',
+ initialize_content: function() {
+ this.$textarea = this.$element.find('textarea');
this.resized = false;
+ if (!this.get("effective_readonly")) {
+ this.$textarea.change(_.bind(function() {
+ this.set({'value': instance.web.parse_value(this.$textarea.val(), this)});
+ }, this));
+ } else {
+ this.$textarea.attr('disabled', 'disabled');
+ }
},
- set_value: function(value) {
+ set_value: function(value_) {
this._super.apply(this, arguments);
- var show_value = openerp.web.format_value(value, this, '');
- this.$element.find('textarea').val(show_value);
+ this.render_value();
+ },
+ render_value: function() {
+ var show_value = instance.web.format_value(this.get('value'), this, '');
+ this.$textarea.val(show_value);
if (!this.resized && this.view.options.resize_textareas) {
this.do_resize(this.view.options.resize_textareas);
this.resized = true;
}
},
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('textarea').prop('readonly', this.readonly);
- },
- set_value_from_ui: function() {
- this.value = openerp.web.parse_value(this.$element.find('textarea').val(), this);
- this._super();
- },
- validate: function() {
- this.invalid = false;
- try {
- var value = openerp.web.parse_value(this.$element.find('textarea').val(), this, '');
- this.invalid = this.required && value === '';
- } catch(e) {
- this.invalid = true;
+ is_syntax_valid: function() {
+ if (!this.get("effective_readonly")) {
+ try {
+ var value_ = instance.web.parse_value(this.$textarea.val(), this, '');
+ return true;
+ } catch(e) {
+ return false;
+ }
}
+ return true;
+ },
+ is_false: function() {
+ return this.get('value') === '';
},
focus: function($element) {
- this._super($element || this.$element.find('textarea:first'));
+ this.delay_focus(this.$textarea);
},
do_resize: function(max_height) {
max_height = parseInt(max_height, 10);
- var $input = this.$element.find('textarea'),
+ var $input = this.$textarea,
$div = $('<div style="position: absolute; z-index: 1000; top: 0"/>').width($input.width()),
new_height;
$div.text($input.val());
@@ -1797,64 +2120,60 @@ openerp.web.form.FieldText = openerp.web.form.Field.extend({
$div.remove();
$input.height(new_height);
},
- reset: function() {
- this.resized = false;
- }
-});
+}));
-openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({
- form_template: 'FieldBoolean',
+instance.web.form.FieldBoolean = instance.web.form.AbstractField.extend({
+ template: 'FieldBoolean',
start: function() {
- var self = this;
this._super.apply(this, arguments);
- this.$element.find('input').click(self.on_ui_change);
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.$element.find('input')[0].checked = value;
- },
- set_value_from_ui: function() {
- this.value = this.$element.find('input').is(':checked');
- this._super();
+ this.$checkbox = $("input", this.$element);
+ this.$element.click(_.bind(function() {
+ this.set({'value': this.$checkbox.is(':checked')});
+ }, this));
+ var check_readonly = function() {
+ this.$checkbox.prop('disabled', this.get("effective_readonly"));
+ };
+ this.on("change:effective_readonly", this, check_readonly);
+ _.bind(check_readonly, this)();
},
- update_dom: function() {
+ set_value: function(value_) {
this._super.apply(this, arguments);
- this.$element.find('input').prop('disabled', this.readonly);
+ this.$checkbox[0].checked = value_;
},
- focus: function($element) {
- this._super($element || this.$element.find('input:first'));
+ focus: function() {
+ this.delay_focus(this.$checkbox);
}
});
-openerp.web.form.FieldProgressBar = openerp.web.form.Field.extend({
- form_template: 'FieldProgressBar',
+instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({
+ template: 'FieldProgressBar',
start: function() {
this._super.apply(this, arguments);
- this.$element.find('div').progressbar({
- value: this.value,
- disabled: this.readonly
+ this.$element.progressbar({
+ value: this.get('value'),
+ disabled: this.get("effective_readonly")
});
},
- set_value: function(value) {
+ set_value: function(value_) {
this._super.apply(this, arguments);
- var show_value = Number(value);
+ var show_value = Number(value_);
if (isNaN(show_value)) {
show_value = 0;
}
- var formatted_value = openerp.web.format_value(show_value, { type : 'float' }, '0');
- this.$element.find('div').progressbar('option', 'value', show_value).find('span').html(formatted_value + '%');
+ var formatted_value = instance.web.format_value(show_value, { type : 'float' }, '0');
+ this.$element.progressbar('option', 'value', show_value).find('span').html(formatted_value + '%');
}
});
-openerp.web.form.FieldTextXml = openerp.web.form.Field.extend({
+instance.web.form.FieldTextXml = instance.web.form.AbstractField.extend({
// to replace view editor
});
-openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
- form_template: 'FieldSelection',
- init: function(view, node) {
+instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldSelection',
+ init: function(field_manager, node) {
var self = this;
- this._super(view, node);
+ this._super(field_manager, node);
this.values = _.clone(this.field.selection);
_.each(this.values, function(v, i) {
if (v[0] === false && v[1] === '') {
@@ -1863,7 +2182,7 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
});
this.values.unshift([false, '']);
},
- start: function() {
+ initialize_content: function() {
// Flag indicating whether we're in an event chain containing a change
// event on the select, in order to know what to do on keyup[RETURN]:
// * If the user presses [RETURN] as part of changing the value of a
@@ -1876,9 +2195,10 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
// changing the selected value), takes the action as validating the
// row
var ischanging = false;
- this._super.apply(this, arguments);
this.$element.find('select')
- .change(this.on_ui_change)
+ .change(_.bind(function() {
+ this.set({'value': this.values[this.$element.find('select')[0].selectedIndex][0]});
+ }, this))
.change(function () { ischanging = true; })
.click(function () { ischanging = false; })
.keyup(function (e) {
@@ -1887,32 +2207,37 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
ischanging = false;
});
},
- set_value: function(value) {
- value = value === null ? false : value;
- value = value instanceof Array ? value[0] : value;
- this._super(value);
- var index = 0;
- for (var i = 0, ii = this.values.length; i < ii; i++) {
- if (this.values[i][0] === value) index = i;
- }
- this.$element.find('select')[0].selectedIndex = index;
- },
- set_value_from_ui: function() {
- this.value = this.values[this.$element.find('select')[0].selectedIndex][0];
- this._super();
+ set_value: function(value_) {
+ value_ = value_ === null ? false : value_;
+ value_ = value_ instanceof Array ? value_[0] : value_;
+ this._super(value_);
+ this.render_value();
},
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('select').prop('disabled', this.readonly);
+ render_value: function() {
+ if (!this.get("effective_readonly")) {
+ var index = 0;
+ for (var i = 0, ii = this.values.length; i < ii; i++) {
+ if (this.values[i][0] === this.get('value')) index = i;
+ }
+ this.$element.find('select')[0].selectedIndex = index;
+ } else {
+ var self = this;
+ var option = _(this.values)
+ .detect(function (record) { return record[0] === self.get('value'); });
+ this.$element.text(option ? option[1] : this.values[0][1]);
+ }
},
- validate: function() {
- var value = this.values[this.$element.find('select')[0].selectedIndex];
- this.invalid = !(value && !(this.required && value[0] === false));
+ is_syntax_valid: function() {
+ if (this.get("effective_readonly")) {
+ return true;
+ }
+ var value_ = this.values[this.$element.find('select')[0].selectedIndex];
+ return !! value_;
},
- focus: function($element) {
- this._super($element || this.$element.find('select:first'));
+ focus: function() {
+ this.delay_focus(this.$element.find('select:first'));
}
-});
+}));
// jquery autocomplete tweak to allow html
(function() {
@@ -1921,8 +2246,8 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
function filter( array, term ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
- return $.grep( array, function(value) {
- return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
+ return $.grep( array, function(value_) {
+ return matcher.test( $( "<div>" ).html( value_.label || value_.value || value_ ).text() );
});
}
@@ -1946,114 +2271,88 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
});
})();
-openerp.web.form.dialog = function(content, options) {
+instance.web.form.dialog = function(content, options) {
options = _.extend({
width: '90%',
height: 'auto',
min_width: '800px'
}, options || {});
- var dialog = new openerp.web.Dialog(null, options, content).open();
+ var dialog = new instance.web.Dialog(null, options, content).open();
return dialog.$element;
};
-openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
- form_template: 'FieldMany2One',
- init: function(view, node) {
- this._super(view, node);
+instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: "FieldMany2One",
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
this.limit = 7;
- this.value = null;
- this.cm_id = _.uniqueId('m2o_cm_');
+ this.set({'value': false});
+ this.display_value = {};
this.last_search = [];
- this.tmp_value = undefined;
+ this.floating = false;
+ this.inhibit_on_change = false;
this.orderer = new openerp.web.DropMisordered();
},
start: function() {
this._super();
+ instance.web.form.ReinitializeFieldMixin.start.call(this);
+ this.on("change:value", this, function() {
+ this.floating = false;
+ this.render_value();
+ });
+ },
+ initialize_content: function() {
+ if (!this.get("effective_readonly"))
+ this.render_editable();
+ this.render_value();
+ },
+ render_editable: function() {
var self = this;
this.$input = this.$element.find("input");
+
+ self.$input.tipsy({
+ title: function() {
+ return "No element was selected, you should create or select one from the dropdown list.";
+ },
+ trigger:'manual',
+ fade: true,
+ });
+
this.$drop_down = this.$element.find(".oe-m2o-drop-down-button");
- this.$menu_btn = this.$element.find(".oe-m2o-cm-button");
-
- // context menu
- var init_context_menu_def = $.Deferred().then(function(e) {
- var rdataset = new openerp.web.DataSet(self, "ir.values", self.build_context());
- rdataset.call("get", ['action', 'client_action_relate',
- [[self.field.relation, false]], false, rdataset.get_context()], false, 0)
- .then(function(result) {
- self.related_entries = result;
-
- var $cmenu = $("#" + self.cm_id);
- $cmenu.append(QWeb.render("FieldMany2One.context_menu", {widget: self}));
- var bindings = {};
- bindings[self.cm_id + "_search"] = function() {
- if (self.readonly)
- return;
- self._search_create_popup("search");
- };
- bindings[self.cm_id + "_create"] = function() {
- if (self.readonly)
- return;
- self._search_create_popup("form");
- };
- bindings[self.cm_id + "_open"] = function() {
- if (!self.value) {
- return;
- }
- var pop = new openerp.web.form.FormOpenPopup(self.view);
- pop.show_element(
- self.field.relation,
- self.value[0],
- self.build_context(),
- {
- title: _t("Open: ") + (self.string || self.name)
- }
- );
- pop.on_write_completed.add_last(function() {
- self.set_value(self.value[0]);
- });
- };
- _.each(_.range(self.related_entries.length), function(i) {
- bindings[self.cm_id + "_related_" + i] = function() {
- self.open_related(self.related_entries[i]);
- };
- });
- var cmenu = self.$menu_btn.contextMenu(self.cm_id, {'noRightClick': true,
- bindings: bindings, itemStyle: {"color": ""},
- onContextMenu: function() {
- if(self.value) {
- $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").removeClass("oe-m2o-disabled-cm");
- } else {
- $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm");
- }
- if (!self.readonly) {
- $("#" + self.cm_id + " .oe_m2o_menu_item_noreadonly").removeClass("oe-m2o-disabled-cm");
- } else {
- $("#" + self.cm_id + " .oe_m2o_menu_item_noreadonly").addClass("oe-m2o-disabled-cm");
- }
- return true;
- }, menuStyle: {width: "200px"}
- });
- $.async_when().then(function() {self.$menu_btn.trigger(e);});
+ this.$follow_button = $(".oe-m2o-cm-button", this.$element);
+
+ this.$follow_button.click(function() {
+ if (!self.get('value')) {
+ return;
+ }
+ var pop = new instance.web.form.FormOpenPopup(self.view);
+ pop.show_element(
+ self.field.relation,
+ self.get("value"),
+ self.build_context(),
+ {
+ title: _t("Open: ") + (self.string || self.name)
+ }
+ );
+ pop.on_write_completed.add_last(function() {
+ self.display_value = {};
+ self.render_value();
});
});
- var ctx_callback = function(e) {init_context_menu_def.resolve(e); e.preventDefault()};
- this.$menu_btn.click(ctx_callback);
// some behavior for input
this.$input.keyup(function() {
if (self.$input.val() === "") {
- self._change_int_value(null);
- } else if (self.value === null || (self.value && self.$input.val() !== self.value[1])) {
- self._change_int_value(undefined);
+ self.set({value: false});
+ } else {
+ self.floating = true;
}
});
this.$drop_down.click(function() {
- if (self.readonly)
- return;
if (self.$input.autocomplete("widget").is(":visible")) {
self.$input.autocomplete("close");
} else {
- if (self.value) {
+ if (self.get("value") && ! self.floating) {
self.$input.autocomplete("search", "");
} else {
self.$input.autocomplete("search");
@@ -2061,16 +2360,43 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
self.$input.focus();
}
});
+ var tip_def = $.Deferred();
+ var untip_def = $.Deferred();
+ var tip_delay = 200;
+ var tip_duration = 3000;
var anyoneLoosesFocus = function() {
- if (!self.$input.is(":focus") &&
- !self.$input.autocomplete("widget").is(":visible") &&
- !self.value) {
- if (self.value === undefined && self.last_search.length > 0) {
- self._change_int_ext_value(self.last_search[0]);
+ if (self.floating) {
+ if (self.last_search.length > 0) {
+ if (self.last_search[0][0] != self.get("value")) {
+ self.display_value = {};
+ self.display_value["" + self.last_search[0][0]] = self.last_search[0][1];
+ self.set({value: self.last_search[0][0]});
+ } else {
+ self.render_value();
+ }
} else {
- self._change_int_ext_value(null);
+ self.set({value: false});
}
}
+ if (! self.get("value")) {
+ tip_def.reject();
+ untip_def.reject();
+ tip_def = $.Deferred();
+ tip_def.then(function() {
+ self.$input.tipsy("show");
+ });
+ setTimeout(function() {
+ tip_def.resolve();
+ untip_def.reject();
+ untip_def = $.Deferred();
+ untip_def.then(function() {
+ self.$input.tipsy("hide");
+ });
+ setTimeout(function() {untip_def.resolve();}, tip_duration);
+ }, tip_delay);
+ } else {
+ tip_def.reject();
+ }
};
this.$input.focusout(anyoneLoosesFocus);
@@ -2082,9 +2408,11 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
isSelecting = true;
var item = ui.item;
if (item.id) {
- self._change_int_value([item.id, item.name]);
+ self.display_value = {};
+ self.display_value["" + item.id] = item.name;
+ self.set({value: item.id});
} else if (item.action) {
- self._change_int_value(undefined);
+ self.floating = true;
item.action();
return false;
}
@@ -2112,7 +2440,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
var search_val = request.term;
var self = this;
- var dataset = new openerp.web.DataSet(this, this.field.relation, self.build_context());
+ var dataset = new instance.web.DataSet(this, this.field.relation, self.build_context());
this.orderer.add(dataset.name_search(
search_val, self.build_domain(), 'ilike', this.limit + 1)).then(function(data) {
@@ -2133,7 +2461,6 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
values.push({label: _t("<em>   Search More...</em>"), action: function() {
dataset.name_search(search_val, self.build_domain(), 'ilike'
, false, function(data) {
- self._change_int_value(null);
self._search_create_popup("search", data);
});
}});
@@ -2142,7 +2469,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
var raw_result = _(data.result).map(function(x) {return x[1];});
if (search_val.length > 0 &&
!_.include(raw_result, search_val) &&
- (!self.value || search_val !== self.value[1])) {
+ (!self.get("value") || self.floating)) {
values.push({label: _.str.sprintf(_t('<em>   Create "<strong>%s</strong>"</em>'),
$('<span />').text(search_val).html()), action: function() {
self._quick_create(search_val);
@@ -2150,7 +2477,6 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
}
// create...
values.push({label: _t("<em>   Create and Edit...</em>"), action: function() {
- self._change_int_value(null);
self._search_create_popup("form", undefined, {"default_name": search_val});
}});
@@ -2160,13 +2486,14 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
_quick_create: function(name) {
var self = this;
var slow_create = function () {
- self._change_int_value(null);
self._search_create_popup("form", undefined, {"default_name": name});
};
if (self.get_definition_options().quick_create === undefined || self.get_definition_options().quick_create) {
- new openerp.web.DataSet(this, this.field.relation, self.build_context())
+ new instance.web.DataSet(this, this.field.relation, self.build_context())
.name_create(name, function(data) {
- self._change_int_ext_value(data);
+ self.display_value = {};
+ self.display_value["" + data[0]] = data[1];
+ self.set({value: data[0]});
}).fail(function(error, event) {
event.preventDefault();
slow_create();
@@ -2177,7 +2504,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
// all search/create popup handling
_search_create_popup: function(view, ids, context) {
var self = this;
- var pop = new openerp.web.form.SelectCreatePopup(this);
+ var pop = new instance.web.form.SelectCreatePopup(this);
pop.select_element(
self.field.relation,
{
@@ -2187,100 +2514,71 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
disable_multiple_selection: true
},
self.build_domain(),
- new openerp.web.CompoundContext(self.build_context(), context || {})
+ new instance.web.CompoundContext(self.build_context(), context || {})
);
pop.on_select_elements.add(function(element_ids) {
- new openerp.web.DataSet(self, self.field.relation, self.build_context())
- .name_get([element_ids[0]], function(data) {
- self._change_int_ext_value(data[0]);
- });
+ self.set({value: element_ids[0]});
});
},
- _change_int_ext_value: function(value) {
- this._change_int_value(value);
- this.$input.val(this.value ? this.value[1] : "");
- },
- _change_int_value: function(value) {
- this.value = value;
- var back_orig_value = this.original_value;
- if (this.value === null || this.value) {
- this.original_value = this.value;
+ render_value: function(no_recurse) {
+ var self = this;
+ if (! this.get("value")) {
+ this.display_string("");
+ return;
}
- if (back_orig_value === undefined) { // first use after a set_value()
+ var display = this.display_value["" + this.get("value")];
+ if (display) {
+ this.display_string(display);
return;
}
- if (this.value !== undefined && ((back_orig_value ? back_orig_value[0] : null)
- !== (this.value ? this.value[0] : null))) {
- this.on_ui_change();
+ if (! no_recurse) {
+ var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.view.dataset.get_context());
+ dataset.name_get([self.get("value")], function(data) {
+ self.display_value["" + self.get("value")] = data[0][1];
+ self.render_value(true);
+ });
}
},
- set_value: function(value) {
- value = value || null;
- this.invalid = false;
+ display_string: function(str) {
var self = this;
- this.tmp_value = value;
- self.update_dom();
- self.on_value_changed();
- var real_set_value = function(rval) {
- self.tmp_value = undefined;
- self.value = rval;
- self.original_value = undefined;
- self._change_int_ext_value(rval);
- };
- if (value && !(value instanceof Array)) {
- // name_get in a m2o does not use the context of the field
- new openerp.web.DataSet(this, this.field.relation, self.view.dataset.get_context())
- .name_get([value], function(data) {
- real_set_value(data[0]);
- }).fail(function() {self.tmp_value = undefined;});
+ if (!this.get("effective_readonly")) {
+ this.$input.val(str);
} else {
- $.async_when().then(function() {real_set_value(value);});
- }
- },
- get_value: function() {
- if (this.tmp_value !== undefined) {
- if (this.tmp_value instanceof Array) {
- return this.tmp_value[0];
- }
- return this.tmp_value ? this.tmp_value : false;
- }
- if (this.value === undefined)
- return this.original_value ? this.original_value[0] : false;
- return this.value ? this.value[0] : false;
- },
- validate: function() {
- this.invalid = false;
- var val = this.tmp_value !== undefined ? this.tmp_value : this.value;
- if (val === null) {
- this.invalid = this.required;
+ this.$element.find('a')
+ .unbind('click')
+ .text(str)
+ .click(function () {
+ self.do_action({
+ type: 'ir.actions.act_window',
+ res_model: self.field.relation,
+ res_id: self.get("value"),
+ context: self.build_context(),
+ views: [[false, 'form']],
+ target: 'current'
+ });
+ return false;
+ });
}
},
- open_related: function(related) {
+ set_value: function(value_) {
var self = this;
- if (!self.value)
- return;
- var additional_context = {
- active_id: self.value[0],
- active_ids: [self.value[0]],
- active_model: self.field.relation
- };
- self.rpc("/web/action/load", {
- action_id: related[2].id,
- context: additional_context
- }, function(result) {
- result.result.context = _.extend(result.result.context || {}, additional_context);
- self.do_action(result.result);
- });
+ if (value_ instanceof Array) {
+ this.display_value = {};
+ this.display_value["" + value_[0]] = value_[1];
+ value_ = value_[0];
+ }
+ value_ = value_ || false;
+ this.inhibit_on_change = true;
+ this._super(value_);
+ this.inhibit_on_change = false;
},
- focus: function ($element) {
- this._super($element || this.$input);
+ is_false: function() {
+ return ! this.get("value");
},
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$input.prop('readonly', this.readonly);
+ focus: function () {
+ this.delay_focus(this.$input);
}
-});
-openerp.web.check_interface(openerp.web.form.FieldMany2One, openerp.web.form.FieldInterface);
+}));
/*
# Values: (0, 0, { fields }) create
@@ -2327,24 +2625,24 @@ var commands = {
return [6, false, ids];
}
};
-openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
- form_template: 'FieldOne2Many',
+instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
multi_selection: false,
- init: function(view, node) {
- this._super(view, node);
+ disable_utility_classes: true,
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
+ lazy_build_o2m_kanban_view();
this.is_loaded = $.Deferred();
this.initial_is_loaded = this.is_loaded;
this.is_setted = $.Deferred();
this.form_last_update = $.Deferred();
this.init_form_last_update = this.form_last_update;
- this.disable_utility_classes = true;
},
start: function() {
this._super.apply(this, arguments);
var self = this;
- this.dataset = new openerp.web.form.One2ManyDataSet(this, this.field.relation);
+ this.dataset = new instance.web.form.One2ManyDataSet(this, this.field.relation);
this.dataset.o2m = this;
this.dataset.parent_view = this.view;
this.dataset.child_name = this.name;
@@ -2356,16 +2654,23 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
this.is_setted.then(function() {
self.load_views();
});
+ this.is_loaded.then(function() {
+ self.on("change:effective_readonly", self, function() {
+ self.is_loaded = self.is_loaded.pipe(function() {
+ self.viewmanager.destroy();
+ return $.when(self.load_views()).then(function() {
+ self.reload_current_view();
+ });
+ });
+ });
+ });
},
trigger_on_change: function() {
var tmp = this.doing_on_change;
this.doing_on_change = true;
- this.on_ui_change();
+ this.trigger('changed_value');
this.doing_on_change = tmp;
},
- is_readonly: function() {
- return this.readonly || this.force_readonly;
- },
load_views: function() {
var self = this;
@@ -2376,21 +2681,21 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
var view = {
view_id: false,
view_type: mode == "tree" ? "list" : mode,
- options: { sidebar : false }
+ options: {}
};
if (self.field.views && self.field.views[mode]) {
view.embedded_view = self.field.views[mode];
}
if(view.view_type === "list") {
view.options.selectable = self.multi_selection;
- if (self.is_readonly()) {
+ if (self.get("effective_readonly")) {
view.options.addable = null;
view.options.deletable = null;
view.options.isClarkGable = false;
}
} else if (view.view_type === "form") {
- if (self.is_readonly()) {
- view.view_type = 'page';
+ if (self.get("effective_readonly")) {
+ view.view_type = 'form';
}
view.options.not_interactible_on_create = true;
}
@@ -2398,12 +2703,14 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
});
this.views = views;
- this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views, {});
+ this.viewmanager = new instance.web.ViewManager(this, this.dataset, views, {
+ $sidebar: false,
+ });
this.viewmanager.template = 'One2Many.viewmanager';
- this.viewmanager.registry = openerp.web.views.extend({
- list: 'openerp.web.form.One2ManyListView',
- form: 'openerp.web.form.One2ManyFormView',
- page: 'openerp.web.PageView'
+ this.viewmanager.registry = instance.web.views.extend({
+ list: 'instance.web.form.One2ManyListView',
+ form: 'instance.web.form.One2ManyFormView',
+ kanban: 'instance.web.form.One2ManyKanbanView',
});
var once = $.Deferred().then(function() {
self.init_form_last_update.resolve();
@@ -2412,12 +2719,12 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
self.initial_is_loaded.resolve();
});
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
+ controller.o2m = self;
if (view_type == "list") {
- controller.o2m = self;
- if (self.is_readonly())
+ if (self.get("effective_readonly"))
controller.set_editable(false);
- } else if (view_type == "form" || view_type == 'page') {
- if (view_type == 'page' || self.is_readonly()) {
+ } else if (view_type === "form") {
+ if (self.get("effective_readonly")) {
$(".oe_form_buttons", controller.$element).children().remove();
}
controller.on_record_loaded.add_last(function() {
@@ -2451,7 +2758,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
var view = self.viewmanager.views[active_view].controller;
if(active_view === "list") {
return view.reload_content();
- } else if (active_view === "form" || active_view === 'page') {
+ } else if (active_view === "form") {
if (self.dataset.index === null && self.dataset.ids.length >= 1) {
self.dataset.index = 0;
}
@@ -2460,18 +2767,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
};
self.form_last_update = self.form_last_update.pipe(act, act);
return self.form_last_update;
- } else if (active_view === "graph") {
+ } else if (view.do_search) {
return view.do_search(self.build_domain(), self.dataset.get_context(), []);
}
}, undefined);
},
- set_value: function(value) {
- value = value || [];
+ set_value: function(value_) {
+ value_ = value_ || [];
var self = this;
this.dataset.reset_ids([]);
- if(value.length >= 1 && value[0] instanceof Array) {
+ if(value_.length >= 1 && value_[0] instanceof Array) {
var ids = [];
- _.each(value, function(command) {
+ _.each(value_, function(command) {
var obj = {values: command[2]};
switch (command[0]) {
case commands.CREATE:
@@ -2500,10 +2807,10 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
});
this._super(ids);
this.dataset.set_ids(ids);
- } else if (value.length >= 1 && typeof(value[0]) === "object") {
+ } else if (value_.length >= 1 && typeof(value_[0]) === "object") {
var ids = [];
this.dataset.delete_all = true;
- _.each(value, function(command) {
+ _.each(value_, function(command) {
var obj = {values: command};
obj['id'] = _.uniqueId(self.dataset.virtual_id_prefix);
obj.defaults = {};
@@ -2514,8 +2821,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
this._super(ids);
this.dataset.set_ids(ids);
} else {
- this._super(value);
- this.dataset.reset_ids(value);
+ this._super(value_);
+ this.dataset.reset_ids(value_);
}
if (this.dataset.index === null && this.dataset.ids.length > 0) {
this.dataset.index = 0;
@@ -2572,61 +2879,37 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
return false;
}, this));
},
- is_valid: function() {
- this.validate();
- return this._super();
- },
- validate: function() {
- this.invalid = false;
+ is_syntax_valid: function() {
if (!this.viewmanager.views[this.viewmanager.active_view])
- return;
+ return true;
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
if (this.viewmanager.active_view === "form") {
for (var f in view.fields) {
f = view.fields[f];
if (!f.is_valid()) {
- this.invalid = true;
- return;
+ return false;
}
}
}
+ return true;
},
- is_dirty: function() {
- this.save_any_view();
- return this._super();
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- var self = this;
- if (this.previous_readonly !== this.readonly) {
- this.previous_readonly = this.readonly;
- if (this.viewmanager) {
- this.is_loaded = this.is_loaded.pipe(function() {
- self.viewmanager.destroy();
- return $.when(self.load_views()).then(function() {
- self.reload_current_view();
- });
- });
- }
- }
- }
});
-openerp.web.form.One2ManyDataSet = openerp.web.BufferedDataSet.extend({
+instance.web.form.One2ManyDataSet = instance.web.BufferedDataSet.extend({
get_context: function() {
this.context = this.o2m.build_context([this.o2m.name]);
return this.context;
}
});
-openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
+instance.web.form.One2ManyListView = instance.web.ListView.extend({
_template: 'One2Many.listview',
do_add_record: function () {
if (this.options.editable) {
this._super.apply(this, arguments);
} else {
var self = this;
- var pop = new openerp.web.form.SelectCreatePopup(this);
+ var pop = new instance.web.form.SelectCreatePopup(this);
pop.on_default_get.add(self.dataset.on_default_get);
pop.select_element(
self.o2m.field.relation,
@@ -2657,7 +2940,7 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
},
do_activate_record: function(index, id) {
var self = this;
- var pop = new openerp.web.form.FormOpenPopup(self.o2m.view);
+ var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
title: _t("Open: ") + self.name,
auto_write: false,
@@ -2668,7 +2951,7 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
},
form_view_options: {'not_interactible_on_create':true},
- readonly: self.o2m.is_readonly()
+ readonly: self.o2m.get("effective_readonly")
});
pop.on_write.add(function(id, data) {
self.o2m.dataset.write(id, data, {}, function(r) {
@@ -2683,12 +2966,12 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
}
});
-openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
+instance.web.form.One2ManyFormView = instance.web.FormView.extend({
form_template: 'One2Many.formview',
on_loaded: function(data) {
this._super(data);
var self = this;
- this.$form_header.find('button.oe_form_button_create').click(function() {
+ this.$buttons.find('button.oe_form_button_create').click(function() {
self.do_save().then(self.on_button_new);
});
},
@@ -2701,12 +2984,43 @@ openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
}
});
-openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
- form_template: 'FieldMany2Many',
+var lazy_build_o2m_kanban_view = function() {
+if (! instance.web_kanban || instance.web.form.One2ManyKanbanView)
+ return;
+instance.web.form.One2ManyKanbanView = instance.web_kanban.KanbanView.extend({
+ open_record: function(id) {
+ var self = this;
+ var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
+ pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
+ title: _t("Open: ") + self.name,
+ auto_write: false,
+ alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
+ parent_view: self.o2m.view,
+ child_name: self.o2m.name,
+ read_function: function() {
+ return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
+ },
+ form_view_options: {'not_interactible_on_create':true},
+ readonly: self.o2m.get("effective_readonly"),
+ });
+ pop.on_write.add(function(id, data) {
+ self.o2m.dataset.write(id, data, {}, function(r) {
+ self.o2m.reload_current_view();
+ });
+ });
+
+ },
+});
+}
+
+/*
+ * TODO niv: clean those deferred stuff, it could be better
+ */
+instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
multi_selection: false,
- init: function(view, node) {
- this._super(view, node);
- this.list_id = _.uniqueId("many2many");
+ disable_utility_classes: true,
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
this.is_loaded = $.Deferred();
this.initial_is_loaded = this.is_loaded;
this.is_setted = $.Deferred();
@@ -2716,43 +3030,44 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
var self = this;
- this.dataset = new openerp.web.form.Many2ManyDataSet(this, this.field.relation);
+ this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
this.dataset.m2m = this;
this.dataset.on_unlink.add_last(function(ids) {
- self.on_ui_change();
+ self.dataset_changed();
});
this.is_setted.then(function() {
self.load_view();
});
+ this.is_loaded.then(function() {
+ self.on("change:effective_readonly", self, function() {
+ self.is_loaded = self.is_loaded.pipe(function() {
+ self.list_view.destroy();
+ return $.when(self.load_view()).then(function() {
+ self.reload_content();
+ });
+ });
+ });
+ })
},
- set_value: function(value) {
- value = value || [];
- if (value.length >= 1 && value[0] instanceof Array) {
- value = value[0][2];
+ set_value: function(value_) {
+ value_ = value_ || [];
+ if (value_.length >= 1 && value_[0] instanceof Array) {
+ value_ = value_[0][2];
}
- this._super(value);
- this.dataset.set_ids(value);
+ this._super(value_);
+ this.dataset.set_ids(value_);
var self = this;
self.reload_content();
this.is_setted.resolve();
},
- get_value: function() {
- return [commands.replace_with(this.dataset.ids)];
- },
- validate: function() {
- this.invalid = false;
- },
- is_readonly: function() {
- return this.readonly || this.force_readonly;
- },
load_view: function() {
var self = this;
- this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
- 'addable': self.is_readonly() ? null : _t("Add"),
- 'deletable': self.is_readonly() ? false : true,
+ 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,
- 'isClarkGable': self.is_readonly() ? false : true
+ 'isClarkGable': self.get("effective_readonly") ? false : true
});
var embedded = (this.field.views || {}).tree;
if (embedded) {
@@ -2765,7 +3080,7 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
loaded.resolve();
});
$.async_when().then(function () {
- self.list_view.appendTo($("#" + self.list_id));
+ self.list_view.appendTo(self.$element);
});
return loaded;
},
@@ -2775,24 +3090,12 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
return self.list_view.reload_content();
});
},
- update_dom: function() {
- this._super.apply(this, arguments);
- var self = this;
- if (this.previous_readonly !== this.readonly) {
- this.previous_readonly = this.readonly;
- if (this.list_view) {
- this.is_loaded = this.is_loaded.pipe(function() {
- self.list_view.destroy();
- return $.when(self.load_view()).then(function() {
- self.reload_content();
- });
- });
- }
- }
- }
+ dataset_changed: function() {
+ this.set({'value': [commands.replace_with(this.dataset.ids)]});
+ },
});
-openerp.web.form.Many2ManyDataSet = openerp.web.DataSetStatic.extend({
+instance.web.form.Many2ManyDataSet = instance.web.DataSetStatic.extend({
get_context: function() {
this.context = this.m2m.build_context();
return this.context;
@@ -2801,25 +3104,25 @@ openerp.web.form.Many2ManyDataSet = openerp.web.DataSetStatic.extend({
/**
* @class
- * @extends openerp.web.ListView
+ * @extends instance.web.ListView
*/
-openerp.web.form.Many2ManyListView = openerp.web.ListView.extend(/** @lends openerp.web.form.Many2ManyListView# */{
+instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends instance.web.form.Many2ManyListView# */{
do_add_record: function () {
- var pop = new openerp.web.form.SelectCreatePopup(this);
+ var pop = new instance.web.form.SelectCreatePopup(this);
pop.select_element(
this.model,
{
title: _t("Add: ") + this.name
},
- new openerp.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]),
+ new instance.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]),
this.m2m_field.build_context()
);
var self = this;
pop.on_select_elements.add(function(element_ids) {
- _.each(element_ids, function(element_id) {
- if(! _.detect(self.dataset.ids, function(x) {return x == element_id;})) {
- self.dataset.set_ids([].concat(self.dataset.ids, [element_id]));
- self.m2m_field.on_ui_change();
+ _.each(element_ids, function(one_id) {
+ if(! _.detect(self.dataset.ids, function(x) {return x == one_id;})) {
+ self.dataset.set_ids([].concat(self.dataset.ids, [one_id]));
+ self.m2m_field.dataset_changed();
self.reload_content();
}
});
@@ -2827,10 +3130,10 @@ openerp.web.form.Many2ManyListView = openerp.web.ListView.extend(/** @lends open
},
do_activate_record: function(index, id) {
var self = this;
- var pop = new openerp.web.form.FormOpenPopup(this);
+ var pop = new instance.web.form.FormOpenPopup(this);
pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), {
title: _t("Open: ") + this.name,
- readonly: this.getParent().is_readonly()
+ readonly: this.getParent().get("effective_readonly")
});
pop.on_write_completed.add_last(function() {
self.reload_content();
@@ -2840,9 +3143,9 @@ openerp.web.form.Many2ManyListView = openerp.web.ListView.extend(/** @lends open
/**
* @class
- * @extends openerp.web.OldWidget
+ * @extends instance.web.OldWidget
*/
-openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends openerp.web.form.SelectCreatePopup# */{
+instance.web.form.SelectCreatePopup = instance.web.OldWidget.extend(/** @lends instance.web.form.SelectCreatePopup# */{
template: "SelectCreatePopup",
/**
* options:
@@ -2868,7 +3171,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.initial_ids = this.options.initial_ids;
this.created_elements = [];
this.renderElement();
- openerp.web.form.dialog(this.$element, {
+ instance.web.form.dialog(this.$element, {
close: function() {
self.check_exit();
},
@@ -2879,7 +3182,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
start: function() {
this._super();
var self = this;
- this.dataset = new openerp.web.ProxyDataSet(this, this.model,
+ this.dataset = new instance.web.ProxyDataSet(this, this.model,
this.context);
this.dataset.create_function = function() {
return self.options.create_function.apply(null, arguments).then(function(r) {
@@ -2899,10 +3202,10 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
contexts: [this.context]
}, function (results) {
var search_defaults = {};
- _.each(results.context, function (value, key) {
+ _.each(results.context, function (value_, key) {
var match = /^search_default_(.*)$/.exec(key);
if (match) {
- search_defaults[match[1]] = value;
+ search_defaults[match[1]] = value_;
}
});
self.setup_search_view(search_defaults);
@@ -2920,7 +3223,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
if (this.searchview) {
this.searchview.destroy();
}
- this.searchview = new openerp.web.SearchView(this,
+ this.searchview = new instance.web.SearchView(this,
this.dataset, false, search_defaults);
this.searchview.on_search.add(function(domains, contexts, groupbys) {
if (self.initial_ids) {
@@ -2932,13 +3235,13 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
}
});
this.searchview.on_loaded.add_last(function () {
- self.view_list = new openerp.web.form.SelectCreateListView(self,
+ self.view_list = new instance.web.form.SelectCreateListView(self,
self.dataset, false,
_.extend({'deletable': false,
'selectable': !self.options.disable_multiple_selection
}, self.options.list_view_options || {}));
self.view_list.popup = self;
- self.view_list.appendTo($("#" + self.element_id + "_view_list")).pipe(function() {
+ self.view_list.appendTo($(".oe-select-create-popup-view-list", self.$element)).pipe(function() {
self.view_list.do_show();
}).pipe(function() {
self.searchview.do_search();
@@ -2960,7 +3263,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
});
});
});
- this.searchview.appendTo($("#" + this.element_id + "_search"));
+ this.searchview.appendTo($(".oe-select-create-popup-view-list", self.$element));
},
do_search: function(domains, contexts, groupbys) {
var self = this;
@@ -2974,14 +3277,14 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
},
create_row: function() {
var self = this;
- var wdataset = new openerp.web.DataSetSearch(this, this.model, this.context, this.domain);
+ var wdataset = new instance.web.DataSetSearch(this, this.model, this.context, this.domain);
wdataset.parent_view = this.options.parent_view;
wdataset.child_name = this.options.child_name;
return wdataset.create.apply(wdataset, arguments);
},
write_row: function() {
var self = this;
- var wdataset = new openerp.web.DataSetSearch(this, this.model, this.context, this.domain);
+ var wdataset = new instance.web.DataSetSearch(this, this.model, this.context, this.domain);
wdataset.parent_view = this.options.parent_view;
wdataset.child_name = this.options.child_name;
return wdataset.write.apply(wdataset, arguments);
@@ -3005,11 +3308,11 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.view_list.$element.hide();
}
this.dataset.index = null;
- this.view_form = new openerp.web.FormView(this, this.dataset, false, self.options.form_view_options);
+ this.view_form = new instance.web.FormView(this, this.dataset, false, self.options.form_view_options);
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
- this.view_form.appendTo(this.$element.find("#" + this.element_id + "_view_form"));
+ this.view_form.appendTo(this.$element.find(".oe-select-create-popup-view-form"));
this.view_form.on_loaded.add_last(function() {
var $buttons = self.view_form.$element.find(".oe_form_buttons");
$buttons.html(QWeb.render("SelectCreatePopup.form.buttons", {widget:self}));
@@ -3045,7 +3348,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
on_default_get: function(res) {}
});
-openerp.web.form.SelectCreateListView = openerp.web.ListView.extend({
+instance.web.form.SelectCreateListView = instance.web.ListView.extend({
do_add_record: function () {
this.popup.new_object();
},
@@ -3061,9 +3364,9 @@ openerp.web.form.SelectCreateListView = openerp.web.ListView.extend({
/**
* @class
- * @extends openerp.web.OldWidget
+ * @extends instance.web.OldWidget
*/
-openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp.web.form.FormOpenPopup# */{
+instance.web.form.FormOpenPopup = instance.web.OldWidget.extend(/** @lends instance.web.form.FormOpenPopup# */{
template: "FormOpenPopup",
/**
* options:
@@ -3081,7 +3384,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
this.context = context || {};
this.options = _.defaults(options || {}, {"auto_write": true});
this.renderElement();
- openerp.web.dialog(this.$element, {
+ instance.web.dialog(this.$element, {
title: options.title || '',
modal: true,
width: 960,
@@ -3091,7 +3394,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
},
start: function() {
this._super();
- this.dataset = new openerp.web.form.FormOpenDataset(this, this.model, this.context);
+ this.dataset = new instance.web.form.FormOpenDataset(this, this.model, this.context);
this.dataset.fop = this;
this.dataset.ids = [this.row_id];
this.dataset.index = 0;
@@ -3103,7 +3406,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
if (!this.options.auto_write)
return;
var self = this;
- var wdataset = new openerp.web.DataSetSearch(this, this.model, this.context, this.domain);
+ var wdataset = new instance.web.DataSetSearch(this, this.model, this.context, this.domain);
wdataset.parent_view = this.options.parent_view;
wdataset.child_name = this.options.child_name;
wdataset.write(id, data, {}, function(r) {
@@ -3113,14 +3416,14 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
on_write_completed: function() {},
setup_form_view: function() {
var self = this;
- var FormClass = this.options.readonly
- ? openerp.web.views.get_object('page')
- : openerp.web.views.get_object('form');
- this.view_form = new FormClass(this, this.dataset, false, self.options.form_view_options);
+ var FormClass = instance.web.views.get_object('form');
+ var options = _.clone(self.options.form_view_options) || {};
+ options.initial_mode = this.options.readonly ? "view" : "edit";
+ this.view_form = new FormClass(this, this.dataset, false, options);
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
- this.view_form.appendTo(this.$element.find("#" + this.element_id + "_view_form"));
+ this.view_form.appendTo(this.$element.find(".oe-form-open-popup-form-view"));
this.view_form.on_loaded.add_last(function() {
var $buttons = self.view_form.$element.find(".oe_form_buttons");
$buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
@@ -3144,7 +3447,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
}
});
-openerp.web.form.FormOpenDataset = openerp.web.ProxyDataSet.extend({
+instance.web.form.FormOpenDataset = instance.web.ProxyDataSet.extend({
read_ids: function() {
if (this.fop.options.read_function) {
return this.fop.options.read_function.apply(null, arguments);
@@ -3154,40 +3457,28 @@ openerp.web.form.FormOpenDataset = openerp.web.ProxyDataSet.extend({
}
});
-openerp.web.form.FieldReference = openerp.web.form.Field.extend({
- form_template: 'FieldReference',
- init: function(view, node) {
- this._super(view, node);
+instance.web.form.FieldReference = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldReference',
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
this.fields_view = {
fields: {
selection: {
- selection: view.fields_view.fields[this.name].selection
+ selection: this.view.fields_view.fields[this.name].selection
},
m2o: {
relation: null
}
}
};
- this.get_fields_values = view.get_fields_values;
- this.get_selected_ids = view.get_selected_ids;
+ this.get_fields_values = this.view.get_fields_values;
+ this.get_selected_ids = this.view.get_selected_ids;
this.do_onchange = this.on_form_changed = this.do_notify_change = this.on_nop;
this.dataset = this.view.dataset;
- this.widgets_counter = 0;
this.view_id = 'reference_' + _.uniqueId();
- this.widgets = {};
this.fields = {};
this.fields_order = [];
- this.selection = new openerp.web.form.FieldSelection(this, { attrs: {
- name: 'selection',
- widget: 'selection'
- }});
this.reference_ready = true;
- this.selection.on_value_changed.add_last(this.on_selection_changed);
- this.m2o = new openerp.web.form.FieldMany2One(this, { attrs: {
- name: 'm2o',
- widget: 'many2one'
- }});
- this.m2o.on_ui_change.add_last(this.on_ui_change);
},
on_nop: function() {
},
@@ -3195,59 +3486,82 @@ openerp.web.form.FieldReference = openerp.web.form.Field.extend({
if (this.reference_ready) {
var sel = this.selection.get_value();
this.m2o.field.relation = sel;
- this.m2o.set_value(null);
+ this.m2o.set_value(false);
this.m2o.$element.toggle(sel !== false);
}
},
- start: function() {
- this._super();
+ destroy_content: function() {
+ if (this.selection) {
+ this.selection.destroy();
+ this.selection = undefined;
+ }
+ if (this.m2o) {
+ this.m2o.destroy();
+ this.m2o = undefined;
+ }
+ },
+ initialize_content: function() {
+ this.selection = new instance.web.form.FieldSelection(this, { attrs: {
+ name: 'selection',
+ widget: 'selection'
+ }});
+ this.selection.set({readonly: this.get('effective_readonly')});
+ this.selection.on("change:value", this, this.on_selection_changed);
this.selection.$element = $(".oe_form_view_reference_selection", this.$element);
this.selection.renderElement();
this.selection.start();
+
+ this.m2o = new instance.web.form.FieldMany2One(this, { attrs: {
+ name: 'm2o',
+ widget: 'many2one'
+ }});
+ this.m2o.set({"readonly": this.get("effective_readonly")});
+ this.m2o.on("change:value", this, this.data_changed);
this.m2o.$element = $(".oe_form_view_reference_m2o", this.$element);
this.m2o.renderElement();
this.m2o.start();
},
- is_valid: function() {
- return this.required === false || typeof(this.get_value()) === 'string';
+ is_false: function() {
+ return typeof(this.get_value()) !== 'string';
},
- is_dirty: function() {
- return this.selection.is_dirty() || this.m2o.is_dirty();
+ set_value: function(value_) {
+ this._super(value_);
+ this.render_value();
},
- set_value: function(value) {
- this._super(value);
+ render_value: function() {
this.reference_ready = false;
var vals = [], sel_val, m2o_val;
- if (typeof(value) === 'string') {
- vals = value.split(',');
+ if (typeof(this.get('value')) === 'string') {
+ vals = this.get('value').split(',');
}
sel_val = vals[0] || false;
m2o_val = vals[1] ? parseInt(vals[1], 10) : false;
- this.selection.set_value(sel_val);
+ if (!this.get("effective_readonly")) {
+ this.selection.set_value(sel_val);
+ }
this.m2o.field.relation = sel_val;
this.m2o.set_value(m2o_val);
this.m2o.$element.toggle(sel_val !== false);
this.reference_ready = true;
},
- get_value: function() {
+ data_changed: function() {
var model = this.selection.get_value(),
id = this.m2o.get_value();
if (typeof(model) === 'string' && typeof(id) === 'number') {
- return model + ',' + id;
+ this.set({'value': model + ',' + id});
} else {
- return false;
+ this.set({'value': false});
}
- }
-});
+ },
+}));
-openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
+instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
this.iframe = this.element_id + '_iframe';
this.binary_value = false;
},
- start: function() {
- 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('.oe-binary-file-clear').click(this.on_clear);
@@ -3281,7 +3595,6 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
console.warn("Error while uploading file : ", name);
} else {
this.on_file_uploaded_and_valid.apply(this, arguments);
- this.on_ui_change();
}
this.$element.find('.oe-binary-progress').hide();
this.$element.find('.oe-binary').show();
@@ -3300,48 +3613,64 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
context: this.view.dataset.get_context()
})},
complete: $.unblockUI,
- error: openerp.webclient.crashmanager.on_rpc_error
+ error: instance.webclient.crashmanager.on_rpc_error
});
},
on_clear: function() {
- if (this.value !== false) {
- this.value = false;
+ if (this.get('value') !== false) {
this.binary_value = false;
- this.on_ui_change();
+ this.set({'value': false});
}
return false;
}
-});
+}));
-openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({
- form_template: 'FieldBinaryFile',
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('.oe-binary-file-set, .oe-binary-file-clear').toggle(!this.readonly);
- this.$element.find('input[type=text]').prop('readonly', this.readonly);
+instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
+ template: 'FieldBinaryFile',
+ initialize_content: function() {
+ this._super();
+ if (this.get("effective_readonly")) {
+ var self = this;
+ this.$element.find('a').click(function() {
+ if (self.get('value')) {
+ self.on_save_as();
+ }
+ return false;
+ });
+ }
},
- set_value: function(value) {
+ set_value: function(value_) {
this._super.apply(this, arguments);
- var show_value;
- if (this.node.attrs.filename) {
- show_value = this.view.datarecord[this.node.attrs.filename] || '';
+ this.render_value();
+ },
+ render_value: function() {
+ if (!this.get("effective_readonly")) {
+ var show_value;
+ if (this.node.attrs.filename) {
+ show_value = this.view.datarecord[this.node.attrs.filename] || '';
+ } else {
+ show_value = (this.get('value') != null && this.get('value') !== false) ? this.get('value') : '';
+ }
+ this.$element.find('input').eq(0).val(show_value);
} else {
- show_value = (value != null && value !== false) ? value : '';
+ this.$element.find('a').show(!!this.get('value'));
+ if (this.get('value')) {
+ var show_value = _t("Download") + " " + (this.view.datarecord[this.node.attrs.filename] || '');
+ this.$element.find('a').text(show_value);
+ }
}
- this.$element.find('input').eq(0).val(show_value);
},
on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
- this.value = file_base64;
this.binary_value = true;
+ this.set({'value': file_base64});
var show_value = name + " (" + this.human_filesize(size) + ")";
this.$element.find('input').eq(0).val(show_value);
this.set_filename(name);
},
- set_filename: function(value) {
+ set_filename: function(value_) {
var filename = this.node.attrs.filename;
if (this.view.fields[filename]) {
- this.view.fields[filename].set_value(value);
- this.view.fields[filename].on_ui_change();
+ this.view.fields[filename].set({value: value_});
}
},
on_clear: function() {
@@ -3351,58 +3680,59 @@ openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({
}
});
-openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({
- form_template: 'FieldBinaryImage',
- start: function() {
- this._super.apply(this, arguments);
- this.$image = this.$element.find('img.oe-binary-image');
+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();
},
- update_dom: function() {
+ set_value: function(value_) {
this._super.apply(this, arguments);
- this.$element.find('.oe-binary').toggle(!this.readonly);
+ this.render_value();
},
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.set_image_maxwidth();
-
+ render_value: function() {
var url;
- if (value && value.substr(0, 10).indexOf(' ') == -1) {
- url = 'data:image/png;base64,' + this.value;
- } else {
+ if (this.get('value') && this.get('value').substr(0, 10).indexOf(' ') == -1) {
+ url = 'data:image/png;base64,' + this.get('value');
+ } else if (this.get('value')) {
url = '/web/binary/image?session_id=' + this.session.session_id + '&model=' +
this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime());
+ } else {
+ url = "/web/static/src/img/placeholder.png";
}
- this.$image.attr('src', url);
- },
- set_image_maxwidth: function() {
- this.$image.css('max-width', this.$element.width());
+ var rendered = QWeb.render("FieldBinaryImage-img", {widget: this, url: url});;
+ this.$placeholder.html(rendered);
},
on_file_change: function() {
- this.set_image_maxwidth();
+ this.render_value();
this._super.apply(this, arguments);
},
on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
- this.value = file_base64;
+ this.set({'value': file_base64});
this.binary_value = true;
- this.$image.attr('src', 'data:' + (content_type || 'image/png') + ';base64,' + file_base64);
+ this.render_value();
},
on_clear: function() {
this._super.apply(this, arguments);
- this.$image.attr('src', '/web/static/src/img/placeholder.png');
+ this.render_value();
}
});
-openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
- form_template: "EmptyComponent",
+instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
+ template: "EmptyComponent",
start: function() {
this._super();
this.selected_value = null;
this.render_list();
},
- set_value: function(value) {
- this._super(value);
- this.selected_value = value;
+ set_value: function(value_) {
+ this._super(value_);
+ this.selected_value = value_;
this.render_list();
},
@@ -3420,7 +3750,7 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
});
}
- var content = openerp.web.qweb.render("FieldStatus.content", {widget: this, _:_});
+ var content = instance.web.qweb.render("FieldStatus.content", {widget: this, _:_});
this.$element.html(content);
var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}");
@@ -3457,77 +3787,36 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
}
});
-openerp.web.form.WidgetHtml = openerp.web.form.Widget.extend({
- renderElement: function () {
- var $root = $('<div class="oe_form_html_view">');
- this.render_children(this, $root);
- var rendered = $root.html();
- this.$element.html(rendered);
- },
- render_children: function (object, $into) {
- var self = this,
- fields = this.view.fields_view.fields;
- _(object.children).each(function (child) {
- if (typeof child === 'string') {
- $into.text(child);
- } else if (child.tag === 'field') {
- var widget = instanciate_widget(self.view.registry.get_object('frame'),
- self.view, {tag: 'ueule', attrs: {}, children: [child] });
- widget.appendTo($into);
- } else {
- var $child = $(document.createElement(child.tag))
- .attr(child.attrs)
- .appendTo($into);
- self.render_children(child, $child);
- }
- });
- }
-});
-
-
/**
- * Registry of form widgets, called by :js:`openerp.web.FormView`
+ * Registry of form widgets, called by :js:`instance.web.FormView`
*/
-openerp.web.form.widgets = new openerp.web.Registry({
- 'frame' : 'openerp.web.form.WidgetFrame',
- 'group' : 'openerp.web.form.WidgetGroup',
- 'notebook' : 'openerp.web.form.WidgetNotebook',
- 'notebookpage' : 'openerp.web.form.WidgetNotebookPage',
- 'separator' : 'openerp.web.form.WidgetSeparator',
- 'label' : 'openerp.web.form.WidgetLabel',
- 'button' : 'openerp.web.form.WidgetButton',
- 'char' : 'openerp.web.form.FieldChar',
- 'id' : 'openerp.web.form.FieldID',
- 'email' : 'openerp.web.form.FieldEmail',
- 'url' : 'openerp.web.form.FieldUrl',
- 'text' : 'openerp.web.form.FieldText',
- 'date' : 'openerp.web.form.FieldDate',
- 'datetime' : 'openerp.web.form.FieldDatetime',
- 'selection' : 'openerp.web.form.FieldSelection',
- 'many2one' : 'openerp.web.form.FieldMany2One',
- 'many2many' : 'openerp.web.form.FieldMany2Many',
- 'one2many' : 'openerp.web.form.FieldOne2Many',
- 'one2many_list' : 'openerp.web.form.FieldOne2Many',
- 'reference' : 'openerp.web.form.FieldReference',
- 'boolean' : 'openerp.web.form.FieldBoolean',
- 'float' : 'openerp.web.form.FieldFloat',
- 'integer': 'openerp.web.form.FieldFloat',
- 'float_time': 'openerp.web.form.FieldFloat',
- 'progressbar': 'openerp.web.form.FieldProgressBar',
- 'image': 'openerp.web.form.FieldBinaryImage',
- 'binary': 'openerp.web.form.FieldBinaryFile',
- 'statusbar': 'openerp.web.form.FieldStatus',
- 'html': 'openerp.web.form.WidgetHtml'
+instance.web.form.widgets = new instance.web.Registry({
+ 'char' : 'instance.web.form.FieldChar',
+ 'id' : 'instance.web.form.FieldID',
+ 'email' : 'instance.web.form.FieldEmail',
+ 'url' : 'instance.web.form.FieldUrl',
+ 'text' : 'instance.web.form.FieldText',
+ 'date' : 'instance.web.form.FieldDate',
+ 'datetime' : 'instance.web.form.FieldDatetime',
+ 'selection' : 'instance.web.form.FieldSelection',
+ 'many2one' : 'instance.web.form.FieldMany2One',
+ 'many2many' : 'instance.web.form.FieldMany2Many',
+ 'one2many' : 'instance.web.form.FieldOne2Many',
+ 'one2many_list' : 'instance.web.form.FieldOne2Many',
+ 'reference' : 'instance.web.form.FieldReference',
+ 'boolean' : 'instance.web.form.FieldBoolean',
+ 'float' : 'instance.web.form.FieldFloat',
+ 'integer': 'instance.web.form.FieldFloat',
+ 'float_time': 'instance.web.form.FieldFloat',
+ 'progressbar': 'instance.web.form.FieldProgressBar',
+ 'image': 'instance.web.form.FieldBinaryImage',
+ 'binary': 'instance.web.form.FieldBinaryFile',
+ 'statusbar': 'instance.web.form.FieldStatus'
});
-var instanciate_widget = function(claz, view, node, o1, o2) {
- var widget = new (claz)(view, node, o1, o2);
- widget.element_class = (['formview', view.view_id, widget.element_name,
- view.widgets_counter++].join("_")).replace(/[^\r\n\f0-9A-Za-z_-]/g, "_");
- view.widgets[widget.element_class] = widget;
- return widget;
-}
-
+instance.web.form.tags = new instance.web.Registry({
+ 'button' : 'instance.web.form.WidgetButton',
+});
};