[MERGE] openerp-web.
bzr revid: vda@tinyerp.com-20110627102112-fdq1j7o7emt6en03
This commit is contained in:
@@ -383,11 +383,6 @@ class DataSet(openerpweb.Controller):
|
||||
reads = Model.read(ids, fields or False, context)
|
||||
reads.sort(key=lambda obj: ids.index(obj['id']))
|
||||
return reads
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def read(self, request, model, ids, fields=False):
|
||||
return self.do_search_read(request, model, ids, fields,
|
||||
request.session.eval_context(request.context))
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def get(self, request, model, ids, fields=False):
|
||||
|
||||
@@ -48,7 +48,7 @@ var QWeb2 = {
|
||||
if (o !== null && o !== undefined) {
|
||||
if (o.constructor === Array) {
|
||||
if (o[1] !== null && o[1] !== undefined) {
|
||||
return ' ' + o[0] + '="' + this.html_escape(o[1]) + '"';
|
||||
return ' ' + o[0] + '="' + this.html_escape(o[1], true) + '"';
|
||||
}
|
||||
} else if (typeof o === 'object') {
|
||||
var r = '';
|
||||
@@ -670,15 +670,10 @@ QWeb2.Element = (function() {
|
||||
this.top("(function(" + value + ") {");
|
||||
this.bottom("})(dict);");
|
||||
this.indent();
|
||||
if (this.children.length === 1) {
|
||||
var lines = this.children[0].node.data.split(/\r?\n/);
|
||||
for (var i = 0, ilen = lines.length; i < ilen; i++) {
|
||||
this.top(lines[i]);
|
||||
}
|
||||
} else {
|
||||
this.engine.tools.exception("'js' code block contains " + this.children.length + " nodes instead of 1");
|
||||
var lines = this.engine.tools.xml_node_to_string(this.node, true).split(/\r?\n/);
|
||||
for (var i = 0, ilen = lines.length; i < ilen; i++) {
|
||||
this.top(lines[i]);
|
||||
}
|
||||
// Maybe I could handle the children ?
|
||||
this.process_children = false;
|
||||
},
|
||||
compile_action_debug : function(value) {
|
||||
|
||||
@@ -474,9 +474,10 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
|
||||
background: #AAAAAA;
|
||||
}
|
||||
.openerp .filter_icon {
|
||||
height: 22px;
|
||||
padding: 1px 2px 0 2px;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin: 0;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.openerp .filter_label {
|
||||
font-weight: bold;
|
||||
@@ -537,14 +538,6 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
|
||||
.openerp .searchview_group_content {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.openerp .searchview_group_content .oe-searchview-render-line {
|
||||
width:0;
|
||||
}
|
||||
|
||||
|
||||
.openerp .oe-searchview-render-line {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.openerp .searchview_extended_group {
|
||||
padding: 3px;
|
||||
@@ -1055,18 +1048,14 @@ background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
|
||||
.openerp .oe-m2o-drop-down-button img,
|
||||
.openerp .oe-m2o-cm-button img {
|
||||
margin-bottom: -4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp .oe-m2o-disabled-cm {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.openerp .oe-dialog-warning {
|
||||
.openerp .oe-dialog-warning p {
|
||||
padding-left: 1em;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.openerp .oe-dialog-warning img {
|
||||
float: left;
|
||||
position: relative;
|
||||
top: -0.5em;
|
||||
margin:0 7px 7px 0;
|
||||
}
|
||||
|
||||
@@ -399,7 +399,6 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
|
||||
on_rpc_response: function() {
|
||||
},
|
||||
on_rpc_error: function(error) {
|
||||
this.on_log(error.message, error.data.debug);
|
||||
},
|
||||
/**
|
||||
* The session is validated either by login or by restoration of a previous session
|
||||
@@ -830,8 +829,15 @@ openerp.base.CrashManager = openerp.base.Dialog.extend({
|
||||
},
|
||||
on_rpc_error: function(error) {
|
||||
this.error = error;
|
||||
if (error.code === 200) {
|
||||
this.dialog_title = "OpenERP Warning";
|
||||
if (error.data.fault_code) {
|
||||
var split = error.data.fault_code.split('\n')[0].split(' -- ');
|
||||
if (split.length > 1) {
|
||||
error.type = split.shift();
|
||||
error.data.fault_code = error.data.fault_code.substr(error.type.length + 4);
|
||||
}
|
||||
}
|
||||
if (error.code === 200 && error.type) {
|
||||
this.dialog_title = "OpenERP " + _.capitalize(error.type);
|
||||
this.template = 'DialogWarning';
|
||||
this.open({
|
||||
width: 'auto',
|
||||
|
||||
@@ -235,7 +235,7 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
|
||||
this._super(session);
|
||||
this.model = model;
|
||||
this.context = context || {};
|
||||
this.index = 0;
|
||||
this.index = null;
|
||||
this.count = 0;
|
||||
},
|
||||
start: function() {
|
||||
@@ -310,9 +310,10 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
|
||||
context: this.context
|
||||
}, callback);
|
||||
},
|
||||
unlink: function(ids) {
|
||||
// to implement in children
|
||||
this.notification.notify("Unlink", ids);
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
var self = this;
|
||||
return this.call_and_eval("unlink", [ids, this.context], null, 1,
|
||||
callback, error_callback);
|
||||
},
|
||||
call: function (method, args, callback, error_callback) {
|
||||
return this.rpc('/base/dataset/call', {
|
||||
@@ -356,15 +357,20 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
|
||||
this.count = this.ids.length;
|
||||
},
|
||||
read_slice: function (fields, offset, limit, callback) {
|
||||
var self = this;
|
||||
offset = offset || 0;
|
||||
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
|
||||
this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
||||
},
|
||||
set_ids: function (ids) {
|
||||
this.ids = ids;
|
||||
this.count = this.ids.length;
|
||||
this.index = this.index <= this.count - 1 ?
|
||||
this.index : (this.count > 0 ? this.count - 1 : 0);
|
||||
},
|
||||
unlink: function(ids) {
|
||||
this.on_unlink(ids);
|
||||
return $.Deferred().resolve({result: true});
|
||||
},
|
||||
on_unlink: function(ids) {
|
||||
this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
|
||||
@@ -438,9 +444,149 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
|
||||
this._sort.unshift((reverse ? '-' : '') + field);
|
||||
return undefined;
|
||||
},
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
var self = this;
|
||||
return this._super(ids, function(result) {
|
||||
self.ids = _.without.apply(_, [self.ids].concat(ids));
|
||||
self.count = self.ids.length;
|
||||
self.index = self.index <= self.count - 1 ?
|
||||
self.index : (self.count > 0 ? self.count -1 : 0);
|
||||
if (callback)
|
||||
callback(result);
|
||||
}, error_callback);
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.BufferedDataSet = openerp.base.DataSetStatic.extend({
|
||||
virtual_id_prefix: "one2many_v_id_",
|
||||
virtual_id_regex: /one2many_v_id_.*/,
|
||||
debug_mode: true,
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.reset_ids([]);
|
||||
},
|
||||
create: function(data, callback, error_callback) {
|
||||
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data};
|
||||
this.to_create.push(cached);
|
||||
this.cache.push(cached);
|
||||
this.on_change();
|
||||
var to_return = $.Deferred().then(callback);
|
||||
setTimeout(function() {to_return.resolve({result: cached.id});}, 0);
|
||||
return to_return.promise();
|
||||
},
|
||||
write: function (id, data, callback) {
|
||||
var self = this;
|
||||
var record = _.detect(this.to_create, function(x) {return x.id === id;});
|
||||
record = record || _.detect(this.to_write, function(x) {return x.id === id;});
|
||||
if (record) {
|
||||
$.extend(record.values, data);
|
||||
} else {
|
||||
record = {id: id, values: data};
|
||||
self.to_write.push(record);
|
||||
}
|
||||
var cached = _.detect(this.cache, function(x) {return x.id === id;});
|
||||
$.extend(cached.values, record.values);
|
||||
this.on_change();
|
||||
var to_return = $.Deferred().then(callback);
|
||||
setTimeout(function () {to_return.resolve({result: true});}, 0);
|
||||
return to_return.promise();
|
||||
},
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
var self = this;
|
||||
_.each(ids, function(id) {
|
||||
if (! _.detect(self.to_create, function(x) { return x.id === id; })) {
|
||||
self.to_delete.push({id: id})
|
||||
}
|
||||
});
|
||||
this.to_create = _.reject(this.to_create, function(x) { return _.include(ids, x.id);});
|
||||
this.to_write = _.reject(this.to_write, function(x) { return _.include(ids, x.id);});
|
||||
this.cache = _.reject(this.cache, function(x) { return _.include(ids, x.id);});
|
||||
this.set_ids(_.without.apply(_, [this.ids].concat(ids)));
|
||||
this.on_change();
|
||||
var to_return = $.Deferred().then(callback);
|
||||
setTimeout(function () {to_return.resolve({result: true});}, 0);
|
||||
return to_return.promise();
|
||||
},
|
||||
reset_ids: function(ids) {
|
||||
this.set_ids(ids);
|
||||
this.to_delete = [];
|
||||
this.to_create = [];
|
||||
this.to_write = [];
|
||||
this.cache = [];
|
||||
},
|
||||
on_change: function() {},
|
||||
read_ids: function (ids, fields, callback) {
|
||||
var self = this;
|
||||
var to_get = [];
|
||||
_.each(ids, function(id) {
|
||||
var cached = _.detect(self.cache, function(x) {return x.id === id;});
|
||||
var created = _.detect(self.to_create, function(x) {return x.id === id;});
|
||||
if (created) {
|
||||
_.each(fields, function(x) {if (cached.values[x] === undefined) cached.values[x] = false;});
|
||||
} else {
|
||||
if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined}))
|
||||
to_get.push(id);
|
||||
}
|
||||
});
|
||||
var completion = $.Deferred().then(callback);
|
||||
var return_records = function() {
|
||||
var records = _.map(ids, function(id) {
|
||||
return _.extend({}, _.detect(self.cache, function(c) {return c.id === id;}).values, {"id": id});
|
||||
});
|
||||
if (self.debug_mode) {
|
||||
if (_.include(records, undefined)) {
|
||||
throw "Record not correctly loaded";
|
||||
}
|
||||
}
|
||||
setTimeout(function () {completion.resolve(records);}, 0);
|
||||
}
|
||||
if(to_get.length > 0) {
|
||||
var rpc_promise = this._super(to_get, fields, function(records) {
|
||||
_.each(records, function(record, index) {
|
||||
var id = to_get[index];
|
||||
var cached = _.detect(self.cache, function(x) {return x.id === id;});
|
||||
if (!cached) {
|
||||
self.cache.push({id: id, values: record});
|
||||
} else {
|
||||
// I assume cache value is prioritary
|
||||
_.defaults(cached.values, record);
|
||||
}
|
||||
});
|
||||
return_records();
|
||||
});
|
||||
$.when(rpc_promise).fail(function() {completion.reject();});
|
||||
} else {
|
||||
return_records();
|
||||
}
|
||||
return completion.promise();
|
||||
},
|
||||
});
|
||||
|
||||
openerp.base.ReadOnlyDataSetSearch = openerp.base.DataSetSearch.extend({
|
||||
create: function(data, callback, error_callback) {
|
||||
this.on_create(data);
|
||||
var to_return = $.Deferred().then(callback);
|
||||
setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
|
||||
return to_return.promise();
|
||||
},
|
||||
on_create: function(data) {},
|
||||
write: function (id, data, callback) {
|
||||
this.on_write(id);
|
||||
var to_return = $.Deferred().then(callback);
|
||||
setTimeout(function () {to_return.resolve({"result": true});}, 0);
|
||||
return to_return.promise();
|
||||
},
|
||||
on_write: function(id) {},
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
this.on_unlink(ids);
|
||||
var to_return = $.Deferred().then(callback);
|
||||
setTimeout(function () {to_return.resolve({"result": true});}, 0);
|
||||
return to_return.promise();
|
||||
},
|
||||
on_unlink: function(ids) {}
|
||||
});
|
||||
|
||||
openerp.base.CompoundContext = function() {
|
||||
this.__ref = "compound_context";
|
||||
this.__contexts = [];
|
||||
|
||||
@@ -36,6 +36,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
this.default_focus_button = null;
|
||||
this.registry = openerp.base.form.widgets;
|
||||
this.has_been_loaded = $.Deferred();
|
||||
this.$form_header = null;
|
||||
},
|
||||
start: function() {
|
||||
//this.log('Starting FormView '+this.model+this.view_id)
|
||||
@@ -59,72 +60,80 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
_.each(this.widgets, function(w) {
|
||||
w.start();
|
||||
});
|
||||
this.$element.find('div.oe_form_pager button[data-pager-action]').click(function() {
|
||||
this.$form_header = this.$element.find('#' + this.element_id + '_header');
|
||||
this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() {
|
||||
var action = $(this).data('pager-action');
|
||||
self.on_pager_action(action);
|
||||
});
|
||||
|
||||
this.$element.find('#' + this.element_id + '_header button.oe_form_button_save').click(this.do_save);
|
||||
this.$element.find('#' + this.element_id + '_header button.oe_form_button_save_edit').click(this.do_save_edit);
|
||||
this.$element.find('#' + this.element_id + '_header button.oe_form_button_cancel').click(this.do_cancel);
|
||||
this.$element.find('#' + this.element_id + '_header button.oe_form_button_new').click(this.on_button_new);
|
||||
this.$form_header.find('button.oe_form_button_save').click(this.do_save);
|
||||
this.$form_header.find('button.oe_form_button_save_edit').click(this.do_save_edit);
|
||||
this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
|
||||
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
|
||||
|
||||
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
|
||||
this.has_been_loaded.resolve();
|
||||
},
|
||||
do_show: function () {
|
||||
var self = this;
|
||||
self.$element.show();
|
||||
if (this.dataset.index === null || (this.dataset.index === 0 && this.dataset.ids.length == 0)) {
|
||||
if (this.dataset.index === null) {
|
||||
// null index means we should start a new record
|
||||
// 0 index with empty ids means we called the form with empty dataset (wizards, switched to form from empty list, ...)
|
||||
this.on_button_new();
|
||||
} else {
|
||||
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
|
||||
}
|
||||
self.$element.show();
|
||||
this.view_manager.sidebar.do_refresh(true);
|
||||
},
|
||||
do_hide: function () {
|
||||
this.$element.hide();
|
||||
},
|
||||
on_record_loaded: function(record) {
|
||||
if (!record) {
|
||||
throw("Form: No record received");
|
||||
}
|
||||
if (!record.id) {
|
||||
this.$form_header.find('.oe_form_on_create').show();
|
||||
this.$form_header.find('.oe_form_on_update').hide();
|
||||
this.$form_header.find('button.oe_form_button_new').hide();
|
||||
} else {
|
||||
this.$form_header.find('.oe_form_on_create').hide();
|
||||
this.$form_header.find('.oe_form_on_update').show();
|
||||
this.$form_header.find('button.oe_form_button_new').show();
|
||||
}
|
||||
this.touched = false;
|
||||
if (record) {
|
||||
this.datarecord = record;
|
||||
for (var f in this.fields) {
|
||||
this.datarecord = record;
|
||||
for (var f in this.fields) {
|
||||
var field = this.fields[f];
|
||||
field.touched = false;
|
||||
field.set_value(this.datarecord[f] || false);
|
||||
field.validate();
|
||||
}
|
||||
if (!record.id) {
|
||||
// New record: Second pass in order to trigger the onchanges
|
||||
this.touched = true;
|
||||
this.show_invalid = false;
|
||||
for (var f in record) {
|
||||
var field = this.fields[f];
|
||||
field.touched = false;
|
||||
field.set_value(this.datarecord[f] || false);
|
||||
field.validate();
|
||||
}
|
||||
if (!record.id) {
|
||||
// New record: Second pass in order to trigger the onchanges
|
||||
this.touched = true;
|
||||
this.show_invalid = false;
|
||||
for (var f in record) {
|
||||
this.on_form_changed(this.fields[f]);
|
||||
if (field) {
|
||||
field.touched = true;
|
||||
this.do_onchange(field);
|
||||
}
|
||||
}
|
||||
this.on_form_changed();
|
||||
this.show_invalid = this.ready = true;
|
||||
} else {
|
||||
this.log("No record received");
|
||||
}
|
||||
this.on_form_changed();
|
||||
this.show_invalid = this.ready = true;
|
||||
this.do_update_pager(record.id == null);
|
||||
this.do_update_sidebar();
|
||||
if (this.default_focus_field) {
|
||||
this.default_focus_field.focus();
|
||||
}
|
||||
},
|
||||
on_form_changed: function(widget) {
|
||||
if (widget && widget.node.attrs.on_change) {
|
||||
this.do_onchange(widget);
|
||||
} else {
|
||||
for (var w in this.widgets) {
|
||||
w = this.widgets[w];
|
||||
w.process_attrs();
|
||||
w.update_dom();
|
||||
}
|
||||
on_form_changed: function() {
|
||||
for (var w in this.widgets) {
|
||||
w = this.widgets[w];
|
||||
w.process_attrs();
|
||||
w.update_dom();
|
||||
}
|
||||
},
|
||||
on_pager_action: function(action) {
|
||||
@@ -157,6 +166,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
this.ready = false;
|
||||
var onchange = _.trim(widget.node.attrs.on_change);
|
||||
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
|
||||
console.log("Onchange triggered for field '%s' -> %s", widget.name, onchange);
|
||||
if (call) {
|
||||
var method = call[1], args = [];
|
||||
var argument_replacement = {
|
||||
@@ -195,12 +205,14 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
on_processed_onchange: function(response, processed) {
|
||||
var result = response.result;
|
||||
if (result.value) {
|
||||
console.log(" |-> Onchange Response :", result.value);
|
||||
for (var f in result.value) {
|
||||
var field = this.fields[f];
|
||||
if (field) {
|
||||
var value = result.value[f];
|
||||
processed.push(field.name);
|
||||
if (field.get_value() != value) {
|
||||
console.log(" |-> Onchange Action : change '%s' value from '%s' to '%s'", field.name, field.get_value(), value);
|
||||
field.set_value(value);
|
||||
if (_.indexOf(processed, field.name) < 0) {
|
||||
this.do_onchange(field, processed);
|
||||
@@ -252,18 +264,23 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
if (!this.ready) {
|
||||
return false;
|
||||
}
|
||||
var invalid = false;
|
||||
var values = {};
|
||||
var invalid = false,
|
||||
values = {},
|
||||
first_invalid_field = null;
|
||||
for (var f in this.fields) {
|
||||
f = this.fields[f];
|
||||
if (f.invalid) {
|
||||
invalid = true;
|
||||
f.update_dom();
|
||||
if (!first_invalid_field) {
|
||||
first_invalid_field = f;
|
||||
}
|
||||
} else if (f.touched) {
|
||||
values[f.name] = f.get_value();
|
||||
}
|
||||
}
|
||||
if (invalid) {
|
||||
first_invalid_field.focus();
|
||||
this.on_invalid();
|
||||
return false;
|
||||
} else {
|
||||
@@ -360,12 +377,13 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
if (!this.datarecord.id) {
|
||||
this.on_attachments_loaded([]);
|
||||
} else {
|
||||
this.rpc('/base/dataset/search_read', {
|
||||
// TODO fme: modify this so it doesn't try to load attachments when there is not sidebar
|
||||
/*this.rpc('/base/dataset/search_read', {
|
||||
model: 'ir.attachment',
|
||||
fields: ['name', 'url', 'type'],
|
||||
domain: [['res_model', '=', this.dataset.model], ['res_id', '=', this.datarecord.id], ['type', 'in', ['binary', 'url']]],
|
||||
context: this.dataset.context
|
||||
}, this.on_attachments_loaded);
|
||||
}, this.on_attachments_loaded);*/
|
||||
}
|
||||
},
|
||||
on_attachments_loaded: function(attachments) {
|
||||
@@ -553,7 +571,7 @@ openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({
|
||||
var widget_type = node.attrs.widget || type.type || node.tag;
|
||||
var widget = new (this.view.registry.get_object(widget_type)) (this.view, node);
|
||||
if (node.tag == 'field') {
|
||||
if (node.attrs.default_focus == '1') {
|
||||
if (!this.view.default_focus_field || node.attrs.default_focus == '1') {
|
||||
this.view.default_focus_field = widget;
|
||||
}
|
||||
if (node.attrs.nolabel != '1') {
|
||||
@@ -718,7 +736,8 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
|
||||
this.validate();
|
||||
if (!this.invalid) {
|
||||
this.set_value_from_ui();
|
||||
this.view.on_form_changed(this);
|
||||
this.view.do_onchange(this);
|
||||
this.view.on_form_changed();
|
||||
} else {
|
||||
this.update_dom();
|
||||
}
|
||||
@@ -857,7 +876,7 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
|
||||
}
|
||||
},
|
||||
validate: function() {
|
||||
this.invalid = this.required && this.$element.find('input')[this.jqueryui_object]('getDate') === '';
|
||||
this.invalid = this.required && !this.$element.find('input')[this.jqueryui_object]('getDate');
|
||||
},
|
||||
focus: function() {
|
||||
this.$element.find('input').focus();
|
||||
@@ -1074,6 +1093,7 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
|
||||
this.value = null;
|
||||
this.cm_id = _.uniqueId('m2o_cm_');
|
||||
this.last_search = [];
|
||||
this.tmp_value = undefined;
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
@@ -1259,11 +1279,32 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
|
||||
},
|
||||
set_value_from_ui: function() {},
|
||||
set_value: function(value) {
|
||||
this._super(value);
|
||||
this.original_value = value;
|
||||
this._change_int_ext_value(value);
|
||||
value = value || null;
|
||||
var self = this;
|
||||
var _super = this._super;
|
||||
this.tmp_value = value;
|
||||
var real_set_value = function(rval) {
|
||||
this.tmp_value = undefined;
|
||||
_super.apply(self, rval);
|
||||
self.original_value = rval;
|
||||
self._change_int_ext_value(rval);
|
||||
};
|
||||
if(typeof(value) === "number") {
|
||||
var dataset = new openerp.base.DataSetStatic(this.session, this.field.relation, []);
|
||||
dataset.call("name_get", [value], function(data) {
|
||||
real_set_value(data.result[0]);
|
||||
}).fail(function() {self.tmp_value = undefined;});
|
||||
} else {
|
||||
setTimeout(function() {real_set_value(value);}, 0);
|
||||
}
|
||||
},
|
||||
get_value: function() {
|
||||
if (this.tmp_value !== undefined) {
|
||||
if (this.tmp_value instanceof Array) {
|
||||
return this.tmp_value[0];
|
||||
}
|
||||
return this.tmp_value;
|
||||
}
|
||||
if (this.value === undefined)
|
||||
throw "theorically unreachable state";
|
||||
return this.value ? this.value[0] : false;
|
||||
@@ -1276,23 +1317,29 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
# Values: (0, 0, { fields }) create
|
||||
# (1, ID, { fields }) update
|
||||
# (2, ID) remove (delete)
|
||||
# (3, ID) unlink one (target id or target of relation)
|
||||
# (4, ID) link
|
||||
# (5) unlink all (only valid for one2many)
|
||||
*/
|
||||
|
||||
openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldOne2Many";
|
||||
this.is_started = $.Deferred();
|
||||
this.is_setted = $.Deferred();
|
||||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
var self = this;
|
||||
|
||||
this.dataset = new openerp.base.DataSetStatic(this.session, this.field.relation);
|
||||
this.dataset.on_unlink.add_last(function(ids) {
|
||||
self.dataset.set_ids(_.without.apply(_, [self.dataset.ids].concat(ids)));
|
||||
this.dataset = new openerp.base.BufferedDataSet(this.session, this.field.relation);
|
||||
this.dataset.on_change.add_last(function() {
|
||||
self.on_ui_change();
|
||||
self.reload_current_view();
|
||||
});
|
||||
|
||||
var modes = this.node.attrs.mode;
|
||||
@@ -1328,14 +1375,6 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
|
||||
self.is_started.resolve();
|
||||
});
|
||||
this.viewmanager.start();
|
||||
|
||||
$.when(this.is_started, this.is_setted).then(function() {
|
||||
if (modes[0] == "tree") {
|
||||
var view = self.viewmanager.views[self.viewmanager.active_view].controller;
|
||||
view.reload_content();
|
||||
}
|
||||
// TODO niv: handle other types of views
|
||||
});
|
||||
},
|
||||
reload_current_view: function() {
|
||||
var self = this;
|
||||
@@ -1343,18 +1382,61 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
|
||||
if(self.viewmanager.active_view === "list") {
|
||||
view.reload_content();
|
||||
} else if (self.viewmanager.active_view === "form") {
|
||||
// TODO niv: but fme did not implemented delete in form view anyway
|
||||
// TODO niv: implement
|
||||
}
|
||||
},
|
||||
set_value_from_ui: function() {},
|
||||
set_value: function(value) {
|
||||
if(value != false) {
|
||||
this.dataset.set_ids(value);
|
||||
this.is_setted.resolve();
|
||||
value = value || [];
|
||||
var self = this;
|
||||
if(value.length >= 1 && value[0] instanceof Array) {
|
||||
var ids = [];
|
||||
_each(value, function(command) {
|
||||
if(command[0] == 0) {
|
||||
var obj = {id: _.uniqueId(self.dataset.virtual_id_prefix), values: command[2]};
|
||||
self.dataset.to_create.push(obj);
|
||||
self.dataset.cache.push(_.clone(obj));
|
||||
ids.push(obj.id);
|
||||
} else if(command[0] == 1) {
|
||||
var obj = {id: command[1], values: command[2]};
|
||||
self.dataset.to_write.push(obj);
|
||||
self.dataset.cache.push(_.clone(obj));
|
||||
ids.push(obj.id);
|
||||
} else if(command[0] == 2) {
|
||||
self.dataset.to_delete.push({id: command[1]});
|
||||
} else if(command[0] == 4) {
|
||||
ids.push(command[1]);
|
||||
}
|
||||
});
|
||||
this._super(ids);
|
||||
this.dataset.set_ids(ids);
|
||||
} else {
|
||||
this._super(value);
|
||||
this.dataset.reset_ids(value);
|
||||
}
|
||||
$.when(this.is_started).then(function() {
|
||||
self.reload_current_view();
|
||||
});
|
||||
},
|
||||
get_value: function(value) {
|
||||
//TODO niv
|
||||
return [];
|
||||
get_value: function() {
|
||||
var self = this;
|
||||
var val = _.map(this.dataset.ids, function(id) {
|
||||
var alter_order = _.detect(self.dataset.to_create, function(x) {return x.id === id;});
|
||||
if (alter_order) {
|
||||
return [0, 0, alter_order.values];
|
||||
}
|
||||
alter_order = _.detect(self.dataset.to_write, function(x) {return x.id === id;});
|
||||
if (alter_order) {
|
||||
return [1, alter_order.id, alter_order.values];
|
||||
}
|
||||
return [4, id];
|
||||
});
|
||||
val = val.concat(_.map(this.dataset.to_delete, function(v, k) {return [2, x.id];}));
|
||||
return val;
|
||||
},
|
||||
validate: function() {
|
||||
this.invalid = false;
|
||||
// TODO niv
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1364,14 +1446,15 @@ openerp.base.form.One2ManyListView = openerp.base.ListView.extend({
|
||||
var pop = new openerp.base.form.SelectCreatePopup(null, self.o2m.view.session);
|
||||
pop.select_element(self.o2m.field.relation,{
|
||||
initial_view: "form",
|
||||
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined
|
||||
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
|
||||
auto_create: false
|
||||
});
|
||||
pop.on_select_elements.add(function(element_ids) {
|
||||
var ids = self.o2m.dataset.ids;
|
||||
_.each(element_ids, function(x) {if (!_.include(ids, x)) ids.push(x);});
|
||||
self.o2m.dataset.set_ids(ids);
|
||||
self.o2m.on_ui_change();
|
||||
self.o2m.reload_current_view();
|
||||
pop.on_create.add(function(data) {
|
||||
self.o2m.dataset.create(data, function(r) {
|
||||
self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result]));
|
||||
pop.stop();
|
||||
self.o2m.reload_current_view();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1382,7 +1465,6 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
|
||||
this.template = "FieldMany2Many";
|
||||
this.list_id = _.uniqueId("many2many");
|
||||
this.is_started = $.Deferred();
|
||||
this.is_setted = $.Deferred();
|
||||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
@@ -1392,8 +1474,7 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
|
||||
this.dataset = new openerp.base.DataSetStatic(
|
||||
this.session, this.field.relation);
|
||||
this.dataset.on_unlink.add_last(function(ids) {
|
||||
self.list_view.reload_content();
|
||||
|
||||
//TODO niv: should check this for other cases
|
||||
self.on_ui_change();
|
||||
});
|
||||
|
||||
@@ -1406,15 +1487,18 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
|
||||
self.is_started.resolve();
|
||||
});
|
||||
this.list_view.start();
|
||||
$.when(this.is_started, this.is_setted).then(function() {
|
||||
self.list_view.reload_content();
|
||||
});
|
||||
},
|
||||
set_value: function(value) {
|
||||
if (value != false) {
|
||||
this.dataset.set_ids(value);
|
||||
this.is_setted.resolve();
|
||||
value = value || [];
|
||||
if (value.length >= 1 && value[0] instanceof Array) {
|
||||
value = value[0][2];
|
||||
}
|
||||
this._super(value);
|
||||
this.dataset.set_ids(value);
|
||||
var self = this;
|
||||
$.when(this.is_started).then(function() {
|
||||
self.list_view.reload_content();
|
||||
});
|
||||
},
|
||||
get_value: function() {
|
||||
return [[6,false,this.dataset.ids]];
|
||||
@@ -1459,12 +1543,13 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
|
||||
* - initial_view: form or search (default search)
|
||||
* - disable_multiple_selection
|
||||
* - alternative_form_view
|
||||
* - auto_create (default true)
|
||||
*/
|
||||
select_element: function(model, options, domain, context) {
|
||||
this.model = model;
|
||||
this.domain = domain || [];
|
||||
this.context = context || {};
|
||||
this.options = options || {};
|
||||
this.options = _.defaults(options || {}, {"initial_view": "search", "auto_create": true});
|
||||
this.initial_ids = this.options.initial_ids;
|
||||
jQuery(this.render()).dialog({title: '',
|
||||
modal: true,
|
||||
@@ -1473,9 +1558,9 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
this.dataset = new openerp.base.DataSetSearch(this.session, this.model,
|
||||
this.dataset = new openerp.base.ReadOnlyDataSetSearch(this.session, this.model,
|
||||
this.context, this.domain);
|
||||
if ((this.options.initial_view || "search") == "search") {
|
||||
if (this.options.initial_view == "search") {
|
||||
this.setup_search_view();
|
||||
} else { // "form"
|
||||
this.new_object();
|
||||
@@ -1514,7 +1599,7 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
|
||||
$sbutton.click(function() {
|
||||
self.on_select_elements(self.selected_ids);
|
||||
});
|
||||
self.view_list = new openerp.base.form.Many2XPopupListView( null, self.session,
|
||||
self.view_list = new openerp.base.form.SelectCreateListView( null, self.session,
|
||||
self.element_id + "_view_list", self.dataset, false,
|
||||
{'deletable': false});
|
||||
self.view_list.popup = self;
|
||||
@@ -1525,6 +1610,15 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
|
||||
});
|
||||
this.searchview.start();
|
||||
},
|
||||
on_create: function(data) {
|
||||
if (!this.options.auto_create)
|
||||
return;
|
||||
var self = this;
|
||||
var wdataset = new openerp.base.DataSetSearch(this.session, this.model, this.context, this.domain);
|
||||
wdataset.create(data, function(r) {
|
||||
self.on_select_elements([r.result]);
|
||||
});
|
||||
},
|
||||
on_select_elements: function(element_ids) {
|
||||
},
|
||||
on_click_element: function(ids) {
|
||||
@@ -1562,17 +1656,12 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
|
||||
self.stop();
|
||||
});
|
||||
});
|
||||
this.view_form.on_created.add_last(function(r, success) {
|
||||
if (r.result) {
|
||||
var id = arguments[0].result;
|
||||
self.on_select_elements([id]);
|
||||
}
|
||||
});
|
||||
this.dataset.on_create.add(this.on_create);
|
||||
this.view_form.do_show();
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.form.Many2XPopupListView = openerp.base.ListView.extend({
|
||||
openerp.base.form.SelectCreateListView = openerp.base.ListView.extend({
|
||||
do_add_record: function () {
|
||||
this.popup.new_object();
|
||||
},
|
||||
|
||||
@@ -125,6 +125,15 @@ openerp.base.list.editable = function (openerp) {
|
||||
'class': $(row).attr('class'),
|
||||
click: function (e) {e.stopPropagation();}
|
||||
})
|
||||
.delegate('button.oe-edit-row-save', 'click', function () {
|
||||
self.save_row();
|
||||
})
|
||||
.delegate('button.oe-edit-row-cancel', 'click', function () {
|
||||
self.cancel_edition();
|
||||
})
|
||||
.delegate('button', 'keyup', function (e) {
|
||||
e.stopImmediatePropagation();
|
||||
})
|
||||
.keyup(function (e) {
|
||||
switch (e.which) {
|
||||
case KEY_RETURN:
|
||||
@@ -136,12 +145,6 @@ openerp.base.list.editable = function (openerp) {
|
||||
default:
|
||||
return;
|
||||
}
|
||||
})
|
||||
.delegate('button.oe-edit-row-save', 'click', function () {
|
||||
self.save_row();
|
||||
})
|
||||
.delegate('button.oe-edit-row-cancel', 'click', function () {
|
||||
self.cancel_edition();
|
||||
});
|
||||
if (row) {
|
||||
$new_row.replaceAll(row);
|
||||
|
||||
@@ -336,25 +336,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
}
|
||||
var self = this;
|
||||
return $.when(this.dataset.unlink(ids)).then(function () {
|
||||
_(self.rows).chain()
|
||||
.map(function (row, index) {
|
||||
return {
|
||||
index: index,
|
||||
id: row.data.id.value
|
||||
};})
|
||||
.filter(function (record) {
|
||||
return _.contains(ids, record.id);
|
||||
})
|
||||
.sort(function (a, b) {
|
||||
// sort in reverse index order, so we delete from the end
|
||||
// and don't blow up the following indexes (leading to
|
||||
// removing the wrong records from the visible list)
|
||||
return b.index - a.index;
|
||||
})
|
||||
.each(function (record) {
|
||||
self.rows.splice(record.index, 1);
|
||||
});
|
||||
// TODO only refresh modified rows
|
||||
self.reload_content();
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -895,7 +877,7 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
|
||||
|
||||
var d = new $.Deferred();
|
||||
dataset.read_slice(
|
||||
_.filter(_.pluck(this.columns, 'name'), _.identity),
|
||||
_.filter(_.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name'), _.identity),
|
||||
0, false,
|
||||
function (records) {
|
||||
var form_records = _(records).map(
|
||||
|
||||
@@ -377,6 +377,7 @@ openerp.base.search.FilterGroup = openerp.base.search.Widget.extend({
|
||||
init: function (filters, view) {
|
||||
this._super(view);
|
||||
this.filters = filters;
|
||||
this.length = filters.length;
|
||||
},
|
||||
start: function () {
|
||||
this._super();
|
||||
|
||||
@@ -113,7 +113,8 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
|
||||
* @returns {jQuery.Deferred} new view loading promise
|
||||
*/
|
||||
on_mode_switch: function(view_type) {
|
||||
var view_promise;
|
||||
var self = this,
|
||||
view_promise;
|
||||
this.active_view = view_type;
|
||||
var view = this.views[view_type];
|
||||
if (!view.controller) {
|
||||
@@ -124,6 +125,16 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
|
||||
if (view.embedded_view) {
|
||||
controller.set_embedded_view(view.embedded_view);
|
||||
}
|
||||
if (view_type === 'list' && this.flags.search_view === false && this.action && this.action['auto_search']) {
|
||||
// In case the search view is not instanciated: manually call ListView#search
|
||||
controller.on_loaded.add({
|
||||
callback: function () {
|
||||
controller.do_search([self.action.domain], [self.action.context], []);
|
||||
},
|
||||
position: 'last',
|
||||
unique: true
|
||||
});
|
||||
}
|
||||
view_promise = controller.start();
|
||||
var self = this;
|
||||
$.when(view_promise).then(function() {
|
||||
@@ -132,6 +143,7 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
|
||||
this.views[view_type].controller = controller;
|
||||
}
|
||||
|
||||
|
||||
if (this.searchview) {
|
||||
if (view.controller.searchable === false) {
|
||||
this.searchview.hide();
|
||||
@@ -261,16 +273,18 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// init search view
|
||||
var searchview_id = this.action.search_view_id && this.action.search_view_id[0];
|
||||
if (this.flags.search_view !== false) {
|
||||
// init search view
|
||||
var searchview_id = this.action.search_view_id && this.action.search_view_id[0];
|
||||
|
||||
var searchview_loaded = this.setup_search_view(
|
||||
searchview_id || false, search_defaults);
|
||||
var searchview_loaded = this.setup_search_view(
|
||||
searchview_id || false, search_defaults);
|
||||
|
||||
// schedule auto_search
|
||||
if (searchview_loaded != null && this.action['auto_search']) {
|
||||
$.when(searchview_loaded, inital_view_loaded)
|
||||
.then(this.searchview.do_search);
|
||||
// schedule auto_search
|
||||
if (searchview_loaded != null && this.action['auto_search']) {
|
||||
$.when(searchview_loaded, inital_view_loaded)
|
||||
.then(this.searchview.do_search);
|
||||
}
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
@@ -455,6 +469,41 @@ openerp.base.ProcessView = openerp.base.Controller.extend({
|
||||
openerp.base.HelpView = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
openerp.base.json_node_to_xml = function(node, single_quote, indent) {
|
||||
// For debugging purpose, this function will convert a json node back to xml
|
||||
// Maybe usefull for xml view editor
|
||||
if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
|
||||
throw("Node a json node");
|
||||
}
|
||||
indent = indent || 0;
|
||||
var sindent = Array(indent + 1).join('\t'),
|
||||
r = sindent + '<' + node.tag;
|
||||
for (var attr in node.attrs) {
|
||||
var vattr = node.attrs[attr];
|
||||
if (typeof(vattr) !== 'string') {
|
||||
// domains, ...
|
||||
vattr = JSON.stringify(vattr);
|
||||
}
|
||||
vattr = vattr.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
if (single_quote) {
|
||||
vattr = vattr.replace(/"/g, "'");
|
||||
}
|
||||
r += ' ' + attr + '="' + vattr + '"';
|
||||
}
|
||||
if (node.children.length) {
|
||||
r += '>\n';
|
||||
var childs = [];
|
||||
for (var i = 0, ii = node.children.length; i < ii; i++) {
|
||||
childs.push(openerp.base.json_node_to_xml(node.children[i], single_quote, indent + 1));
|
||||
}
|
||||
r += childs.join('\n');
|
||||
r += '\n' + sindent + '</' + node.tag + '>';
|
||||
return r;
|
||||
} else {
|
||||
return r + '/>';
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
||||
|
||||
@@ -360,8 +360,14 @@
|
||||
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
|
||||
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
|
||||
<div class="oe_form_buttons" t-if="view.flags.action_buttons !== false">
|
||||
<!--<button type="button" class="oe_form_button_save">Save</button>-->
|
||||
<button type="button" class="oe_form_button_save_edit">Save & Edit</button>
|
||||
<!--<button type="button" class="oe_form_button_save">
|
||||
<span class="oe_form_on_update">Save</span>
|
||||
<span class="oe_form_on_create">Create</span>
|
||||
</button>-->
|
||||
<button type="button" class="oe_form_button_save_edit">
|
||||
<span class="oe_form_on_update">Save & Edit</span>
|
||||
<span class="oe_form_on_create">Create & Edit</span>
|
||||
</button>
|
||||
<!--<button type="button" class="oe_form_button_cancel">Cancel</button>-->
|
||||
<button type="button" class="oe_form_button_new">New</button>
|
||||
</div>
|
||||
@@ -871,10 +877,19 @@
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="DialogWarning">
|
||||
<p class="oe-dialog-warning">
|
||||
<img src="/base/static/src/img/warning.png" class="oe-dialog-icon"/>
|
||||
<t t-esc="error.data.fault_code.substr(18)"/>
|
||||
</p>
|
||||
<table cellspacing="0" cellpadding="0" border="0" class="oe-dialog-warning">
|
||||
<tr>
|
||||
<td><img src="/base/static/src/img/warning.png" class="oe-dialog-icon"/></td>
|
||||
<td>
|
||||
<p>
|
||||
<t t-js="d">
|
||||
d.html_error = context.engine.tools.html_escape(d.error.data.fault_code).replace(/\n/g, '<br/>');
|
||||
</t>
|
||||
<t t-raw="html_error"/>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="DialogTraceback">
|
||||
<pre><t t-esc="error.message"/></pre>
|
||||
|
||||
Reference in New Issue
Block a user