From b2d921759cf633dc1d83ff510561cc1025d4ced8 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 29 Mar 2011 18:34:37 +0200 Subject: [PATCH] [CHANGE] Refactored form view (WIP) bzr revid: fme@openerp.com-20110329163437-08373sb1eck11lhy --- addons/base/static/openerp/base.css | 5 + addons/base/static/openerp/base.xml | 6 +- addons/base/static/openerp/js/base_views.js | 134 +++++++++++++++----- 3 files changed, 110 insertions(+), 35 deletions(-) diff --git a/addons/base/static/openerp/base.css b/addons/base/static/openerp/base.css index f27a4a23ccc..02a5af04c64 100644 --- a/addons/base/static/openerp/base.css +++ b/addons/base/static/openerp/base.css @@ -395,6 +395,11 @@ body.openerp { padding-left: 10px; } +/* Form */ +.openerp .required.error { + border: 1px solid #900; +} + /* Inputs */ .openerp input[type="text"], .openerp input[type="password"], .openerp select, .openerp textarea { -moz-box-sizing: border-box; diff --git a/addons/base/static/openerp/base.xml b/addons/base/static/openerp/base.xml index fec047e4388..2980cc20f4d 100644 --- a/addons/base/static/openerp/base.xml +++ b/addons/base/static/openerp/base.xml @@ -163,7 +163,9 @@
- +
@@ -247,7 +249,7 @@ - +
diff --git a/addons/base/static/openerp/js/base_views.js b/addons/base/static/openerp/js/base_views.js index d7938cbf2da..f28e4f8204d 100644 --- a/addons/base/static/openerp/js/base_views.js +++ b/addons/base/static/openerp/js/base_views.js @@ -1230,22 +1230,24 @@ openerp.base.FormView = openerp.base.Controller.extend({ this.widgets_counter = 0; this.fields = {}; this.datarecord = {}; + this.ready = false; }, start: function() { //this.log('Starting FormView '+this.model+this.view_id) this.rpc("/base/formview/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded); }, on_loaded: function(data) { + var self = this; this.fields_view = data.fields_view; //this.log(this.fields_view); var frame = new openerp.base.WidgetFrame(this, this.fields_view.arch); this.$element.html(QWeb.render("FormView", { "frame": frame, "view": this })); - for (var i in this.widgets) { - this.widgets[i].start(); - } - // bind to all wdigets that have onchange ?? + _.each(this.widgets, function(w) { + w.start(); + }); + this.$element.find('button.form_save').click(this.do_save); this.dataset.on_active_id.add(this.on_record_loaded); }, @@ -1254,12 +1256,49 @@ openerp.base.FormView = openerp.base.Controller.extend({ for (var f in this.fields) { this.fields[f].set_value(this.datarecord.values[f]); } - this.process_widgets_attrs(); + this.on_form_changed(); + this.ready = true; }, - process_widgets_attrs: function() { + on_form_changed: function(widget) { for (var w in this.widgets) { - this.widgets[w].process_attrs(); + w = this.widgets[w]; + w.process_attrs(); + w.update_dom(); } + if (widget) { + // TODO: check if and trigger + // if (onchange for this field) { + // this.ready = false; + // rpc - process.callback ( this.ready = true; ) + // } + } + }, + do_save: function() { + if (!this.ready) { + return false; + } + var invalid = false; + var values = {}; + for (var f in this.fields) { + f = this.fields[f]; + if (f.invalid) { + invalid = true; + } else { + values[f.name] = f.value; + } + } + if (invalid) { + this.on_invalid(); + } else { + console.log("Save form", values); + // TODO: save values via datarecord + // rpc - save.callbacl on_saved + } + }, + on_invalid: function() { + }, + on_saved: function() { + // Check response for exceptions, display error } }); @@ -1348,6 +1387,7 @@ openerp.base.Widget = openerp.base.Controller.extend({ init: function(view, node) { this.view = view; this.node = node; + this.attrs = eval('(' + (this.node.attrs.attrs || '{}') + ')'); this.type = this.type || node.tag; this.element_name = this.element_name || this.type; this.element_id = [this.view.element_id, this.element_name, this.view.widgets_counter++].join("_"); @@ -1367,12 +1407,8 @@ openerp.base.Widget = openerp.base.Controller.extend({ this.$element = $('#' + this.element_id); }, process_attrs: function() { - if (this.node.attrs.attrs) { - var attrs = eval('(' + this.node.attrs.attrs + ')'); - for (var a in attrs) { - this[a] = this.eval_attrs(attrs[a]); - } - this.attrs_change(); + for (var a in this.attrs) { + this[a] = this.eval_attrs(this.attrs[a]); } }, eval_attrs: function(expr) { @@ -1434,7 +1470,7 @@ openerp.base.Widget = openerp.base.Controller.extend({ } return _.indexOf(stack, false) == -1; }, - attrs_change: function() { + update_dom: function() { this.$element.toggle(!this.invisible); }, render: function() { @@ -1567,8 +1603,8 @@ openerp.base.WidgetLabel = openerp.base.Widget.extend({ openerp.base.Field = openerp.base.Widget.extend({ init: function(view, node) { - this.value = undefined; this.name = node.attrs.name; + this.value = undefined; view.fields[this.name] = this; this.type = node.attrs.widget || view.fields_view.fields[node.attrs.name].type; this.element_name = "field_" + this.name + "_" + this.type; @@ -1585,16 +1621,21 @@ openerp.base.Field = openerp.base.Widget.extend({ this.nolabel = (node.attrs.nolabel == '1'); this.readonly = (node.attrs.readonly == '1'); this.required = (node.attrs.required == '1'); + this.invalid = false; }, set_value: function(value) { this.value = value; }, - attrs_change: function() { + get_value: function(value) { + return value; + }, + update_dom: function() { this._super.apply(this, arguments); - this.$element.find('input, select, textarea').attr({ - 'disabled' : this.readonly, - 'required' : this.required - }); + this.$element.toggleClass('disabled', this.readonly); + this.$element.toggleClass('required', this.required); + }, + on_ui_change: function() { + this.view.on_form_changed(this); } }); @@ -1605,25 +1646,27 @@ openerp.base.FieldChar = openerp.base.Field.extend({ }, start: function() { this._super.apply(this, arguments); - // this.$element.bind('change',) ... blur, focus, ... + this.$element.find('input').change(this.on_ui_change); }, set_value: function(value) { this._super.apply(this, arguments); if (value != null && value !== false) { - this.$element.find('input').val(this.to_string(value)); + this.$element.find('input').val(value); } }, get_value: function() { - return this.from_string(this.$element.find('input').val()); }, - to_string: function(value) { - return value.toString(); + update_dom: function() { + this._super.apply(this, arguments); + this.$element.find('input').attr({ + 'disabled' : this.readonly, + 'required' : this.required + }); }, - from_string: function(value) { - return value.toString(); - }, - on_change: function() { - //this.view.update_field(this.name,value); + on_ui_change: function() { + this.value = this.$element.find('input').val(); + this.invalid = this.required && this.value == ""; + this._super.apply(this, arguments); } }); @@ -1633,9 +1676,34 @@ openerp.base.FieldEmail = openerp.base.FieldChar.extend({ openerp.base.FieldUrl = openerp.base.FieldChar.extend({ }); -openerp.base.FieldFloat = openerp.base.FieldChar.extend({ - to_string: function(value) { - return value.toFixed(2); +openerp.base.FieldFloat = openerp.base.Field.extend({ + init: function(view, node) { + this._super(view, node); + this.template = "FieldChar"; + }, + start: function() { + this._super.apply(this, arguments); + this.$element.find('input').change(this.on_ui_change); + }, + set_value: function(value) { + this._super.apply(this, arguments); + if (value != null && value !== false) { + this.$element.find('input').val(value.toFixed(2)); + } + }, + get_value: function() { + }, + update_dom: function() { + this._super.apply(this, arguments); + this.$element.find('input').attr({ + 'disabled' : this.readonly, + 'required' : this.required + }); + }, + on_ui_change: function() { + this.value = this.$element.find('input').val(); + this.invalid = this.required && this.value == ""; + this._super.apply(this, arguments); } });