renames part4
bzr revid: al@openerp.com-20110330140048-qm5m28ns44hkqzvn
This commit is contained in:
parent
4dd20612ad
commit
dcb9634cea
|
@ -2,7 +2,7 @@
|
|||
* OpenERP base library
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.base$chrome = function(openerp) {
|
||||
openerp.addons.base.chrome = function(openerp) {
|
||||
|
||||
openerp.base.callback = function(obj, method) {
|
||||
// openerp.base.callback( obj, methods, [arg1, arg2, ... ] )
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
|
||||
openerp.addons.base.data = function(openerp) {
|
||||
/**
|
||||
* Management interface between views and the collection of selected OpenERP
|
||||
* records (represents the view's state?)
|
||||
*/
|
||||
openerp.base.DataGroup = openerp.base.Controller.extend({
|
||||
init: function(session) {
|
||||
this._super(session, null);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Management interface between views and the collection of selected OpenERP
|
||||
* records (represents the view's state?)
|
||||
*/
|
||||
openerp.base.DataSet = openerp.base.Controller.extend({
|
||||
init: function(session, model) {
|
||||
this._super(session);
|
||||
this.model = model;
|
||||
|
||||
this._fields = null;
|
||||
|
||||
this._ids = [];
|
||||
this._active_ids = null;
|
||||
this._active_id_index = 0;
|
||||
|
||||
this._sort = [];
|
||||
this._domain = [];
|
||||
this._context = {};
|
||||
},
|
||||
start: function() {
|
||||
// TODO: fields_view_get fields selection?
|
||||
this.rpc("/base/dataset/fields", {"model":this.model}, this.on_fields);
|
||||
},
|
||||
on_fields: function(result) {
|
||||
this._fields = result._fields;
|
||||
this.on_ready();
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch all the records selected by this DataSet, based on its domain
|
||||
* and context.
|
||||
*
|
||||
* Fires the on_ids event.
|
||||
*
|
||||
* @param {Number} [offset=0] The index from which selected records should be returned
|
||||
* @param {Number} [limit=null] The maximum number of records to return
|
||||
* @returns itself
|
||||
*/
|
||||
// ADD CALLBACK
|
||||
fetch: function (offset, limit) {
|
||||
offset = offset || 0;
|
||||
limit = limit || null;
|
||||
this.rpc('/base/dataset/find', {
|
||||
model: this.model,
|
||||
fields: this._fields,
|
||||
domain: this._domain,
|
||||
context: this._context,
|
||||
sort: this._sort,
|
||||
offset: offset,
|
||||
limit: limit
|
||||
}, _.bind(function (records) {
|
||||
var data_records = _.map(
|
||||
records, function (record) {
|
||||
return new openerp.base.DataRecord(
|
||||
this.session, this.model,
|
||||
this._fields, record);
|
||||
}, this);
|
||||
|
||||
this.on_fetch(data_records, {
|
||||
offset: offset,
|
||||
limit: limit,
|
||||
domain: this._domain,
|
||||
context: this._context,
|
||||
sort: this._sort
|
||||
});
|
||||
}, this));
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
/** REMOVE
|
||||
* @event
|
||||
*
|
||||
* Fires after the DataSet fetched the records matching its internal ids selection
|
||||
*
|
||||
* @param {Array} records An array of the DataRecord fetched
|
||||
* @param event The on_fetch event object
|
||||
* @param {Number} event.offset the offset with which the original DataSet#fetch call was performed
|
||||
* @param {Number} event.limit the limit set on the original DataSet#fetch call
|
||||
* @param {Array} event.domain the domain set on the DataSet before DataSet#fetch was called
|
||||
* @param {Object} event.context the context set on the DataSet before DataSet#fetch was called
|
||||
* @param {Array} event.sort the sorting criteria used to get the ids
|
||||
*/
|
||||
on_fetch: function (records, event) { },
|
||||
|
||||
/**
|
||||
* Fetch all the currently active records for this DataSet (records selected via DataSet#select)
|
||||
*
|
||||
* @returns itself
|
||||
*/
|
||||
// ADD fields and callback
|
||||
active_ids: function () {
|
||||
this.rpc('/base/dataset/get', {
|
||||
ids: this.get_active_ids(),
|
||||
model: this.model
|
||||
}, _.bind(function (records) {
|
||||
this.on_active_ids(_.map(
|
||||
records, function (record) {
|
||||
return new openerp.base.DataRecord(
|
||||
this.session, this.model,
|
||||
this._fields, record);
|
||||
}, this));
|
||||
}, this));
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
/** REMIVE
|
||||
* @event
|
||||
*
|
||||
* Fires after the DataSet fetched the records matching its internal active ids selection
|
||||
*
|
||||
* @param {Array} records An array of the DataRecord fetched
|
||||
*/
|
||||
on_active_ids: function (records) { },
|
||||
|
||||
/**
|
||||
* Fetches the current active record for this DataSet
|
||||
*
|
||||
* @returns itself
|
||||
*/
|
||||
// ADD fields and callback
|
||||
active_id: function () {
|
||||
this.rpc('/base/dataset/get', {
|
||||
ids: [this.get_active_id()],
|
||||
model: this.model
|
||||
}, _.bind(function (records) {
|
||||
var record = records[0];
|
||||
this.on_active_id(
|
||||
record && new openerp.base.DataRecord(
|
||||
this.session, this.model,
|
||||
this._fields, record));
|
||||
}, this));
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
/** REMOVE
|
||||
* Fires after the DataSet fetched the record matching the current active record
|
||||
*
|
||||
* @param record the record matching the provided id, or null if there is no record for this id
|
||||
*/
|
||||
on_active_id: function (record) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures the DataSet
|
||||
*
|
||||
* @param options DataSet options
|
||||
* @param {Array} options.domain the domain to assign to this DataSet for filtering
|
||||
* @param {Object} options.context the context this DataSet should use during its calls
|
||||
* @param {Array} options.sort the sorting criteria for this DataSet
|
||||
* @returns itself
|
||||
*/
|
||||
set: function (options) {
|
||||
if (options.domain) {
|
||||
this._domain = _.clone(options.domain);
|
||||
}
|
||||
if (options.context) {
|
||||
this._context = _.clone(options.context);
|
||||
}
|
||||
if (options.sort) {
|
||||
this._sort = _.clone(options.sort);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Activates the previous id in the active sequence. If there is no previous id, wraps around to the last one
|
||||
* @returns itself
|
||||
*/
|
||||
prev: function () {
|
||||
this._active_id_index -= 1;
|
||||
if (this._active_id_index < 0) {
|
||||
this._active_id_index = this._active_ids.length - 1;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Activates the next id in the active sequence. If there is no next id, wraps around to the first one
|
||||
* @returns itself
|
||||
*/
|
||||
next: function () {
|
||||
this._active_id_index += 1;
|
||||
if (this._active_id_index >= this._active_ids.length) {
|
||||
this._active_id_index = 0;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets active_ids by value:
|
||||
*
|
||||
* * Activates all ids part of the current selection
|
||||
* * Sets active_id to be the first id of the selection
|
||||
*
|
||||
* @param {Array} ids the list of ids to activate
|
||||
* @returns itself
|
||||
*/
|
||||
select: function (ids) {
|
||||
this._active_ids = ids;
|
||||
this._active_id_index = 0;
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Fetches the ids of the currently selected records, if any.
|
||||
*/
|
||||
get_active_ids: function () {
|
||||
return this._active_ids;
|
||||
},
|
||||
/**
|
||||
* Sets the current active_id by value
|
||||
*
|
||||
* If there are no active_ids selected, selects the provided id as the sole active_id
|
||||
*
|
||||
* If there are ids selected and the provided id is not in them, raise an error
|
||||
*
|
||||
* @param {Object} id the id to activate
|
||||
* @returns itself
|
||||
*/
|
||||
activate: function (id) {
|
||||
if(!this._active_ids) {
|
||||
this._active_ids = [id];
|
||||
this._active_id_index = 0;
|
||||
} else {
|
||||
var index = _.indexOf(this._active_ids, id);
|
||||
if (index == -1) {
|
||||
throw new Error(
|
||||
"Could not find id " + id +
|
||||
" in array [" + this._active_ids.join(', ') + "]");
|
||||
}
|
||||
this._active_id_index = index;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Fetches the id of the current active record, if any.
|
||||
*
|
||||
* @returns record? record id or <code>null</code>
|
||||
*/
|
||||
get_active_id: function () {
|
||||
if (!this._active_ids) {
|
||||
return null;
|
||||
}
|
||||
return this._active_ids[this._active_id_index];
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.DataRecord = openerp.base.Controller.extend({
|
||||
init: function(session, model, fields, values) {
|
||||
this._super(session, null);
|
||||
this.model = model;
|
||||
this.id = values.id || null;
|
||||
this.fields = fields;
|
||||
this.values = values;
|
||||
},
|
||||
on_change: function() {
|
||||
},
|
||||
on_reload: function() {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
|
@ -0,0 +1,539 @@
|
|||
|
||||
openerp.addons.base.form = function (openerp) {
|
||||
|
||||
openerp.base.FormView = openerp.base.Controller.extend({
|
||||
init: function(session, element_id, dataset, view_id) {
|
||||
this._super(session, element_id);
|
||||
this.dataset = dataset;
|
||||
this.model = dataset.model;
|
||||
this.view_id = view_id;
|
||||
this.fields_views = {};
|
||||
this.widgets = {};
|
||||
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 }));
|
||||
_.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);
|
||||
// this.dataset.active_id(fields of the form, this.on_record_loaded);
|
||||
},
|
||||
on_next: function() {
|
||||
// this.dataset.next();
|
||||
// this.dataset.active_id(fields of the form, this.on_record_loaded);
|
||||
},
|
||||
on_prev: function() {
|
||||
|
||||
// this.dataset.prev();
|
||||
// this.dataset.active_id(fields of the form, this.on_record_loaded);
|
||||
},
|
||||
on_record_loaded: function(record) {
|
||||
this.datarecord = record;
|
||||
for (var f in this.fields) {
|
||||
this.fields[f].set_value(this.datarecord.values[f]);
|
||||
}
|
||||
this.on_form_changed();
|
||||
this.ready = true;
|
||||
},
|
||||
on_form_changed: function(widget) {
|
||||
for (var w in this.widgets) {
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.Widget = openerp.base.Controller.extend({
|
||||
// TODO Change this to init: function(view, node) { and use view.session and a new element_id for the super
|
||||
// it means that widgets are special controllers
|
||||
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("_");
|
||||
|
||||
this._super(this.view.session, this.element_id);
|
||||
|
||||
this.view.widgets[this.element_id] = this;
|
||||
this.children = node.children;
|
||||
this.colspan = parseInt(node.attrs.colspan || 1);
|
||||
this.template = "Widget";
|
||||
|
||||
this.string = this.string || node.attrs.string;
|
||||
this.help = this.help || node.attrs.help;
|
||||
this.invisible = (node.attrs.invisible == '1');
|
||||
},
|
||||
start: function() {
|
||||
this.$element = $('#' + this.element_id);
|
||||
},
|
||||
process_attrs: function() {
|
||||
for (var a in this.attrs) {
|
||||
this[a] = this.eval_attrs(this.attrs[a]);
|
||||
}
|
||||
},
|
||||
eval_attrs: function(expr) {
|
||||
var stack = [];
|
||||
for (var i = 0; i < expr.length; i++) {
|
||||
var ex = expr[i];
|
||||
if (ex.length == 1) {
|
||||
stack.push(ex[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
var field = this.view.fields[ex[0]].value;
|
||||
var op = ex[1];
|
||||
var val = ex[2];
|
||||
|
||||
switch (op.toLowerCase()) {
|
||||
case '=':
|
||||
case '==':
|
||||
stack.push(field == val);
|
||||
break;
|
||||
case '!=':
|
||||
case '<>':
|
||||
stack.push(field != val);
|
||||
break;
|
||||
case '<':
|
||||
stack.push(field < val);
|
||||
break;
|
||||
case '>':
|
||||
stack.push(field > val);
|
||||
break;
|
||||
case '<=':
|
||||
stack.push(field <= val);
|
||||
break;
|
||||
case '>=':
|
||||
stack.push(field >= val);
|
||||
break;
|
||||
case 'in':
|
||||
stack.push(_.indexOf(val, field) > -1);
|
||||
break;
|
||||
case 'not in':
|
||||
stack.push(_.indexOf(val, field) == -1);
|
||||
break;
|
||||
default:
|
||||
this.log("Unsupported operator in attrs :", op);
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = stack.length-1; j >- 1; j--) {
|
||||
switch (stack[j]) {
|
||||
case '|':
|
||||
var result = stack[j + 1] || stack[j + 2];
|
||||
stack.splice(j, 3, result);
|
||||
break;
|
||||
case '&':
|
||||
var result = stack[j + 1] && stack[j + 2];
|
||||
stack.splice(j, 3, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return _.indexOf(stack, false) == -1;
|
||||
},
|
||||
update_dom: function() {
|
||||
this.$element.toggle(!this.invisible);
|
||||
},
|
||||
render: function() {
|
||||
var template = this.template;
|
||||
return QWeb.render(template, { "widget": this });
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.WidgetFrame = openerp.base.Widget.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "WidgetFrame";
|
||||
this.columns = node.attrs.col || 4;
|
||||
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]);
|
||||
},
|
||||
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) {
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
var w = row[i];
|
||||
if (w.is_field_label) {
|
||||
w.width = "1%";
|
||||
if (row[i + 1]) {
|
||||
row[i + 1].width = Math.round((100 / this.columns) * (w.colspan + 1) - 1) + '%';
|
||||
}
|
||||
} else if (w.width === undefined) {
|
||||
w.width = Math.round((100 / this.columns) * w.colspan) + '%';
|
||||
}
|
||||
}
|
||||
},
|
||||
handle_node: function(n) {
|
||||
var type = this.view.fields_view.fields[n.attrs.name] || {};
|
||||
var widget_type = n.attrs.widget || type.type || n.tag;
|
||||
if (openerp.base.widgets[widget_type]) {
|
||||
var widget = new openerp.base.widgets[widget_type](this.view, n);
|
||||
if (n.tag == 'field' && n.attrs.nolabel != '1') {
|
||||
var label = new openerp.base.widgets['label'](this.view, n);
|
||||
label["for"] = widget;
|
||||
this.add_widget(label);
|
||||
}
|
||||
this.add_widget(widget);
|
||||
} else {
|
||||
this.log("Unhandled widget type : " + widget_type, n);
|
||||
}
|
||||
},
|
||||
add_widget: function(w) {
|
||||
if (!w.invisible) {
|
||||
var current_row = this.table[this.table.length - 1];
|
||||
if (current_row.length && (this.x + w.colspan) > this.columns) {
|
||||
current_row = this.add_row();
|
||||
}
|
||||
current_row.push(w);
|
||||
this.x += w.colspan;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.WidgetNotebook = openerp.base.Widget.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "WidgetNotebook";
|
||||
this.pages = [];
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
var n = node.children[i];
|
||||
if (n.tag == "page") {
|
||||
var page = new openerp.base.WidgetFrame(this.view, n);
|
||||
this.pages.push(page);
|
||||
}
|
||||
}
|
||||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.tabs();
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.WidgetSeparator = openerp.base.Widget.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "WidgetSeparator";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.WidgetButton = openerp.base.Widget.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "WidgetButton";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.WidgetLabel = openerp.base.Widget.extend({
|
||||
init: function(view, node) {
|
||||
this.is_field_label = true;
|
||||
this.element_name = 'label_' + node.attrs.name;
|
||||
|
||||
this._super(view, node);
|
||||
|
||||
this.template = "WidgetLabel";
|
||||
this.colspan = 1;
|
||||
},
|
||||
render: function () {
|
||||
if (this['for'] && this.type !== 'label') {
|
||||
return QWeb.render(this.template, {widget: this['for']});
|
||||
}
|
||||
// Actual label widgets should not have a false and have type label
|
||||
return QWeb.render(this.template, {widget: this});
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.Field = openerp.base.Widget.extend({
|
||||
init: function(view, node) {
|
||||
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;
|
||||
|
||||
this._super(view, node);
|
||||
|
||||
if (node.attrs.nolabel != '1' && this.colspan > 1) {
|
||||
this.colspan--;
|
||||
}
|
||||
// this.datarecord = this.view.datarecord ??
|
||||
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 = (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;
|
||||
},
|
||||
get_value: function(value) {
|
||||
return value;
|
||||
},
|
||||
update_dom: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.toggleClass('disabled', this.readonly);
|
||||
this.$element.toggleClass('required', this.required);
|
||||
},
|
||||
on_ui_change: function() {
|
||||
this.view.on_form_changed(this);
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldChar = 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);
|
||||
}
|
||||
},
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldEmail = openerp.base.FieldChar.extend({
|
||||
});
|
||||
|
||||
openerp.base.FieldUrl = openerp.base.FieldChar.extend({
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldText = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldText";
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
if (value != null && value !== false) {
|
||||
this.$element.find('textarea').val(value);
|
||||
}
|
||||
},
|
||||
get_value: function() {
|
||||
return this.$element.find('textarea').val();
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldBoolean = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldBoolean";
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('input')[0].checked = value;
|
||||
},
|
||||
get_value: function() {
|
||||
this.$element.find('input')[0].checked;
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldDate = openerp.base.FieldChar.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldDate";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldDatetime = openerp.base.FieldChar.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldDatetime";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldTextXml = openerp.base.Field.extend({
|
||||
// to replace view editor
|
||||
});
|
||||
|
||||
openerp.base.FieldSelection = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldSelection";
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
if (value != null && value !== false) {
|
||||
this.$element.find('select').val(value);
|
||||
}
|
||||
},
|
||||
get_value: function() {
|
||||
return this.$element.find('select').val();
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldMany2One = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldMany2One";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldOne2Many = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldOne2Many";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldMany2Many = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldMany2Many";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.FieldReference = openerp.base.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldReference";
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.widgets = {
|
||||
'group' : openerp.base.WidgetFrame,
|
||||
'notebook' : openerp.base.WidgetNotebook,
|
||||
'separator' : openerp.base.WidgetSeparator,
|
||||
'label' : openerp.base.WidgetLabel,
|
||||
'char' : openerp.base.FieldChar,
|
||||
'email' : openerp.base.FieldEmail,
|
||||
'url' : openerp.base.FieldUrl,
|
||||
'text' : openerp.base.FieldText,
|
||||
'date' : openerp.base.FieldDate,
|
||||
'datetime' : openerp.base.FieldDatetime,
|
||||
'selection' : openerp.base.FieldSelection,
|
||||
'many2one' : openerp.base.FieldMany2One,
|
||||
'many2many' : openerp.base.FieldMany2Many,
|
||||
'one2many' : openerp.base.FieldOne2Many,
|
||||
'one2many_list' : openerp.base.FieldOne2Many,
|
||||
'reference' : openerp.base.FieldReference,
|
||||
'boolean' : openerp.base.FieldBoolean,
|
||||
'float' : openerp.base.FieldFloat,
|
||||
'button' : openerp.base.WidgetButton
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
openerp.addons.base.form = function (openerp) {
|
||||
|
||||
openerp.base.ListView = openerp.base.Controller.extend({
|
||||
init: function(session, element_id, dataset, view_id) {
|
||||
this._super(session, element_id);
|
||||
this.dataset = dataset;
|
||||
this.model = dataset.model;
|
||||
this.view_id = view_id;
|
||||
this.name = "";
|
||||
|
||||
this.cols = [];
|
||||
|
||||
this.$table = null;
|
||||
this.colnames = [];
|
||||
this.colmodel = [];
|
||||
|
||||
this.event_loading = false; // TODO in the future prevent abusive click by masking
|
||||
},
|
||||
start: function() {
|
||||
//this.log('Starting ListView '+this.model+this.view_id)
|
||||
this.rpc("/base/listview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
this.fields_view = data.fields_view;
|
||||
//this.log(this.fields_view);
|
||||
this.name = "" + this.fields_view.arch.attrs.string;
|
||||
this.$element.html(QWeb.render("ListView", {"fields_view": this.fields_view}));
|
||||
this.$table = this.$element.find("table");
|
||||
this.cols = [];
|
||||
this.colnames = [];
|
||||
this.colmodel = [];
|
||||
// TODO uss a object for each col, fill it with view and fallback to dataset.model_field
|
||||
var tree = this.fields_view.arch.children;
|
||||
for(var i = 0; i < tree.length; i++) {
|
||||
var col = tree[i];
|
||||
if(col.tag == "field") {
|
||||
this.cols.push(col.attrs.name);
|
||||
this.colnames.push(col.attrs.name);
|
||||
this.colmodel.push({ name: col.attrs.name, index: col.attrs.name });
|
||||
}
|
||||
}
|
||||
this.dataset.fields = this.cols;
|
||||
this.dataset.on_fetch.add(this.do_fill_table);
|
||||
|
||||
var width = this.$element.width();
|
||||
this.$table.jqGrid({
|
||||
datatype: "local",
|
||||
height: "100%",
|
||||
rowNum: 100,
|
||||
//rowList: [10,20,30],
|
||||
colNames: this.colnames,
|
||||
colModel: this.colmodel,
|
||||
//pager: "#plist47",
|
||||
viewrecords: true,
|
||||
caption: this.name
|
||||
}).setGridWidth(width);
|
||||
|
||||
var self = this;
|
||||
$(window).bind('resize', function() {
|
||||
self.$element.children().hide();
|
||||
self.$table.setGridWidth(self.$element.width());
|
||||
self.$element.children().show();
|
||||
}).trigger('resize');
|
||||
},
|
||||
do_fill_table: function(records) {
|
||||
this.log("do_fill_table");
|
||||
|
||||
this.$table
|
||||
.clearGridData()
|
||||
.addRowData('id', _.map(records, function (record) {
|
||||
return record.values;
|
||||
}));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.TreeView = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,351 @@
|
|||
/**
|
||||
* @function
|
||||
* Defines a module scope (which lasts until the next call to module).
|
||||
*
|
||||
* This module scopes implies setup and teardown callbacks running for each test.
|
||||
*
|
||||
* @param {String} name the name of the module
|
||||
* @param {Object} [lifecycle] callbacks to run before and after each test of the module
|
||||
* @param {Function} lifecycle.setup function running before each test of this module
|
||||
* @param {Function} lifecycle.teardown function running after each test of this module
|
||||
*/
|
||||
var module;
|
||||
/**
|
||||
* @function
|
||||
* Defines a given test to run. Runs all the assertions present in the test
|
||||
*
|
||||
* @param {String} name the name of the test
|
||||
* @param {Number} [expected] number of assertions expected to run in this test (useful for asynchronous tests)
|
||||
* @param {Function} test the testing code to run, holding a sequence of assertions (at least one)
|
||||
*/
|
||||
var test;
|
||||
/**
|
||||
* @function
|
||||
* Defines an asynchronous test: equivalent to calling stop() at the start of
|
||||
* a normal test().
|
||||
*
|
||||
* The test code needs to restart the test runner via start()
|
||||
*
|
||||
* @param {String} name the name of the test
|
||||
* @param {Number} [expected] number of assertions expected to run in this test (useful for asynchronous tests)
|
||||
* @param {Function} test the testing code to run, holding a sequence of assertions (at least one)
|
||||
*/
|
||||
var asyncTest;
|
||||
/**
|
||||
* @function
|
||||
* The most basic boolean assertion (~assertTrue or assert).
|
||||
*
|
||||
* Passes if its argument is truthy
|
||||
*
|
||||
* @param {Boolean} state an arbitrary expression, evaluated in a boolean context
|
||||
* @param {String} [message] the message to output with the assertion result
|
||||
*/
|
||||
var ok;
|
||||
/**
|
||||
* @function
|
||||
* Equality assertion (~assertEqual)
|
||||
*
|
||||
* Passes if both arguments are equal (via <code>==</code>)
|
||||
*
|
||||
* @param {Object} actual the object to check for correctness (processing result)
|
||||
* @param {Object} expected the object to check against
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var equal;
|
||||
/**
|
||||
* @function
|
||||
* Inequality assertion (~assertNotEqual)
|
||||
*
|
||||
* Passes if the arguments are different (via <code>!=</code>)
|
||||
*
|
||||
* @param {Object} actual the object to check for correctness (processing result)
|
||||
* @param {Object} expected the object to check against
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var notEqual;
|
||||
/**
|
||||
* @function
|
||||
* Recursive equality assertion.
|
||||
*
|
||||
* Works on primitive types using <code>===</code> and traversing through
|
||||
* Objects and Arrays as well checking their components
|
||||
*
|
||||
* @param {Object} actual the object to check for correctness (processing result)
|
||||
* @param {Object} expected the object to check against
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var deepEqual;
|
||||
/**
|
||||
* @function
|
||||
* Recursive inequality assertion.
|
||||
*
|
||||
* Works on primitive types using <code>!==</code> and traversing through
|
||||
* Objects and Arrays as well checking their components
|
||||
*
|
||||
* @param {Object} actual the object to check for correctness (processing result)
|
||||
* @param {Object} expected the object to check against
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var notDeepEqual;
|
||||
/**
|
||||
* @function
|
||||
* Strict equality assertion (~assertEqual)
|
||||
*
|
||||
* Passes if both arguments are identical (via <code>===</code>)
|
||||
*
|
||||
* @param {Object} actual the object to check for correctness (processing result)
|
||||
* @param {Object} expected the object to check against
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var strictEqual;
|
||||
/**
|
||||
* @function
|
||||
* Strict inequality assertion (~assertNotEqual)
|
||||
*
|
||||
* Passes if both arguments are identical (via <code>!==</code>)
|
||||
*
|
||||
* @param {Object} actual the object to check for correctness (processing result)
|
||||
* @param {Object} expected the object to check against
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var notStrictEqual;
|
||||
/**
|
||||
* @function
|
||||
* Passes if the provided block raised an exception.
|
||||
*
|
||||
* The <code>expect</code> argument can be provided to perform further assertion checks on the exception itself:
|
||||
* * If it's a <code>RegExp</code> test the exception against the regexp (message?)
|
||||
* * If it's a constructor, check if the exception is an instance of it
|
||||
* * If it's an other type of function, call it with the exception as first parameter
|
||||
* - If the function returns true, the assertion validates
|
||||
* - Otherwise it fails
|
||||
*
|
||||
* @param {Function} block function which should raise an exception when called
|
||||
* @param {Object} [expect] a RegExp, a constructor or a Function
|
||||
* @param {String} [message] message output with the assertion result
|
||||
*/
|
||||
var raises;
|
||||
/**
|
||||
* @function
|
||||
* Starts running the test runner again from the point where it was
|
||||
* <code>stop</code>ped.
|
||||
*
|
||||
* Used to resume testing after a callback.
|
||||
*/
|
||||
var start;
|
||||
/**
|
||||
* @function
|
||||
* Stops the test runner in order to wait for an asynchronous test to run
|
||||
*
|
||||
* @param {Number} [timeout] fails the test after the timeout triggers, only for debugging tests
|
||||
*/
|
||||
var stop;
|
||||
|
||||
var Session = function () {
|
||||
return {
|
||||
rpc: function (_url, params, on_success) {
|
||||
setTimeout(on_success);
|
||||
}
|
||||
};
|
||||
};
|
||||
$(document).ready(function () {
|
||||
var openerp;
|
||||
module("ids_callback", {
|
||||
setup: function () {
|
||||
openerp = window.openerp.init();
|
||||
}
|
||||
});
|
||||
asyncTest("Baseline event attributes", 6, function () {
|
||||
var dataset = new openerp.base.DataSet(
|
||||
new Session());
|
||||
dataset.on_fetch.add(function (records, event) {
|
||||
deepEqual(records, [], 'No records returned');
|
||||
equal(event.offset, 0, 'No offset set in call');
|
||||
equal(event.limit, null, 'No limit set in call');
|
||||
deepEqual(event.domain, [], 'No domain on the dataset');
|
||||
deepEqual(event.context, {}, 'No context on the dataset');
|
||||
deepEqual(event.sort, [], 'The dataset is not sorted');
|
||||
start();
|
||||
});
|
||||
dataset.fetch();
|
||||
});
|
||||
asyncTest("Offset and limit", 2, function () {
|
||||
var dataset = new openerp.base.DataSet(
|
||||
new Session());
|
||||
dataset.on_fetch.add(function (records, event) {
|
||||
equal(event.offset, 20);
|
||||
equal(event.limit, 42);
|
||||
start();
|
||||
});
|
||||
dataset.fetch(20, 42);
|
||||
});
|
||||
asyncTest("Domain and context propagation", 3, function () {
|
||||
var dataset = new openerp.base.DataSet(
|
||||
new Session());
|
||||
var domain_value = [['foo', '=', 'bar']];
|
||||
var context_value= {active_id:3, active_ids:42};
|
||||
var sort_value = ['foo'];
|
||||
dataset.on_fetch.add(function (records, event) {
|
||||
deepEqual(event.domain, domain_value);
|
||||
deepEqual(event.context, context_value);
|
||||
deepEqual(event.sort, sort_value);
|
||||
start();
|
||||
});
|
||||
dataset.set({
|
||||
domain: domain_value,
|
||||
context: context_value,
|
||||
sort: sort_value
|
||||
});
|
||||
dataset.fetch();
|
||||
});
|
||||
asyncTest("Data records", function () {
|
||||
var dataset = new openerp.base.DataSet({
|
||||
rpc: function (url, _params, on_success) {
|
||||
equal('/base/dataset/find', url);
|
||||
_.delay(on_success, 0, [
|
||||
{id: 1, sequence: 3, name: "dummy", age: 42},
|
||||
{id: 5, sequence: 7, name: "whee", age: 55}
|
||||
]);
|
||||
}
|
||||
});
|
||||
dataset.on_fetch.add(function (records) {
|
||||
equal(records.length, 2, "I loaded two virtual records");
|
||||
var d1 = records[0],
|
||||
d2 = records[1];
|
||||
ok(d1 instanceof openerp.base.DataRecord);
|
||||
ok(d2 instanceof openerp.base.DataRecord);
|
||||
start();
|
||||
});
|
||||
dataset.fetch();
|
||||
});
|
||||
|
||||
var dataset;
|
||||
module("set", {
|
||||
setup: function () {
|
||||
var openerp = window.openerp.init();
|
||||
dataset = new openerp.base.DataSet();
|
||||
}
|
||||
});
|
||||
test('Basic properties setting', function () {
|
||||
var domain_value = [['foo', '=', 'bar']];
|
||||
var result = dataset.set({
|
||||
domain: domain_value
|
||||
});
|
||||
ok(dataset === result);
|
||||
deepEqual(domain_value, dataset._domain);
|
||||
});
|
||||
test("Ensure changes don't stick", function () {
|
||||
var domain = [['foo', '=', 'bar']];
|
||||
dataset.set({
|
||||
domain: domain
|
||||
});
|
||||
domain.pop();
|
||||
deepEqual([['foo', '=', 'bar']], dataset._domain);
|
||||
});
|
||||
|
||||
module('ids_activation', {
|
||||
setup: function () {
|
||||
var openerp = window.openerp.init();
|
||||
dataset = new openerp.base.DataSet();
|
||||
}
|
||||
});
|
||||
test('activate id', function () {
|
||||
dataset.activate(1);
|
||||
deepEqual(dataset.get_active_ids(), [1]);
|
||||
equal(dataset.get_active_id(), 1);
|
||||
});
|
||||
test('set active_ids', function () {
|
||||
dataset.select([1, 2, 3]);
|
||||
deepEqual(dataset.get_active_ids(), [1, 2, 3],
|
||||
"selecting an ids range");
|
||||
equal(dataset.get_active_id(), 1);
|
||||
});
|
||||
test('activate incorrect id', function () {
|
||||
dataset.select([1, 2, 3]);
|
||||
raises(function () { dataset.activate(42); },
|
||||
"Activating an id not present in the selection is an error");
|
||||
});
|
||||
test('reset active id on set active ids', function () {
|
||||
dataset.select([1, 2, 3]).activate(3).select([1, 2, 3]);
|
||||
equal(dataset.get_active_id(), 1,
|
||||
"selecting an ids range resets the active id");
|
||||
});
|
||||
|
||||
module('active_id_iteration', {
|
||||
setup: function () {
|
||||
var openerp = window.openerp.init();
|
||||
dataset = new openerp.base.DataSet();
|
||||
dataset.select([1, 2, 3]);
|
||||
}
|
||||
});
|
||||
test('step forward', function () {
|
||||
dataset.activate(1);
|
||||
dataset.next();
|
||||
equal(dataset.get_active_id(), 2);
|
||||
});
|
||||
test('wraparound forward', function () {
|
||||
dataset.activate(3);
|
||||
dataset.next();
|
||||
equal(dataset.get_active_id(), 1);
|
||||
});
|
||||
test('step back', function () {
|
||||
dataset.activate(3);
|
||||
dataset.prev();
|
||||
equal(dataset.get_active_id(), 2);
|
||||
});
|
||||
test('wraparound back', function () {
|
||||
dataset.activate(1);
|
||||
dataset.prev();
|
||||
equal(dataset.get_active_id(), 3);
|
||||
});
|
||||
|
||||
var ResponseAssertSession = function (response_ids) {
|
||||
return {
|
||||
rpc: function (url, params, on_success) {
|
||||
equal(url, '/base/dataset/get');
|
||||
deepEqual(params.ids, response_ids);
|
||||
_.delay(on_success, 0, _.map(
|
||||
params.ids, function (id) {
|
||||
return {id: id, sequence: id, name: 'foo'+id};
|
||||
}
|
||||
));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module('active_ids', {
|
||||
setup: function () {
|
||||
openerp = window.openerp.init();
|
||||
}
|
||||
});
|
||||
asyncTest('Get pre-set active_ids', 6, function () {
|
||||
var dataset = new openerp.base.DataSet(
|
||||
new ResponseAssertSession([1, 2, 3]));
|
||||
dataset.select([1, 2, 3]);
|
||||
dataset.on_active_ids.add(function (data_records) {
|
||||
equal(data_records.length, 3);
|
||||
equal(data_records[0].values.id, 1);
|
||||
equal(data_records[1].values.id, 2);
|
||||
equal(data_records[2].values.id, 3);
|
||||
start();
|
||||
});
|
||||
dataset.active_ids();
|
||||
});
|
||||
|
||||
module('active_id', {
|
||||
setup: function () {
|
||||
openerp = window.openerp.init();
|
||||
}
|
||||
});
|
||||
test('Get pre-set active_id', 3, function () {
|
||||
var dataset = new openerp.base.DataSet(
|
||||
new ResponseAssertSession([42]));
|
||||
stop(500);
|
||||
dataset.select([1, 2, 3, 42]).activate(42);
|
||||
dataset.on_active_id.add(function (data_record) {
|
||||
equal(data_record.values.id, 42);
|
||||
start();
|
||||
});
|
||||
dataset.active_id();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,257 @@
|
|||
/*---------------------------------------------------------
|
||||
* OpenERP base library
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.addons.base.views = function(openerp) {
|
||||
|
||||
// process all kind of actions
|
||||
openerp.base.ActionManager = openerp.base.Controller.extend({
|
||||
init: function(session, element_id) {
|
||||
this._super(session, element_id);
|
||||
this.action = null;
|
||||
this.viewmanager = null;
|
||||
},
|
||||
/**
|
||||
* Process an action
|
||||
* Supported actions: act_window
|
||||
*/
|
||||
do_action: function(action) {
|
||||
// instantiate the right controllers by understanding the action
|
||||
this.action = action;
|
||||
if(action.type == "ir.actions.act_window") {
|
||||
this.viewmanager = new openerp.base.ViewManager(this.session,this.element_id);
|
||||
this.viewmanager.do_action_window(action);
|
||||
this.viewmanager.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This will be ViewManager Abstract/Common
|
||||
openerp.base.ViewManager = openerp.base.Controller.extend({
|
||||
init: function(session, element_id) {
|
||||
this._super(session, element_id);
|
||||
this.action = null;
|
||||
this.dataset = null;
|
||||
this.searchview_id = false;
|
||||
this.searchview = null;
|
||||
this.search_visible = true;
|
||||
// this.views = { "list": { "view_id":1234, "controller": instance} }
|
||||
this.views = {};
|
||||
},
|
||||
start: function() {
|
||||
},
|
||||
on_mode_switch: function(view_type) {
|
||||
for (var i in this.views) {
|
||||
this.views[i].controller.$element.toggle(i === view_type);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Extract search view defaults from the current action's context.
|
||||
*
|
||||
* These defaults are of the form {search_default_*: value}
|
||||
*
|
||||
* @returns {Object} a clean defaults mapping of {field_name: value}
|
||||
*/
|
||||
search_defaults: function () {
|
||||
var defaults = {};
|
||||
_.each(this.action.context, function (value, key) {
|
||||
var match = /^search_default_(.*)$/.exec(key);
|
||||
if (match) {
|
||||
defaults[match[1]] = value;
|
||||
}
|
||||
});
|
||||
return defaults;
|
||||
},
|
||||
do_action_window: function(action) {
|
||||
var self = this;
|
||||
var prefix_id = "#" + this.element_id;
|
||||
this.action = action;
|
||||
this.dataset = new openerp.base.DataSet(this.session, action.res_model);
|
||||
this.dataset.start();
|
||||
|
||||
this.$element.html(QWeb.render("ViewManager", {"prefix": this.element_id, views: action.views}));
|
||||
|
||||
this.searchview_id = false;
|
||||
if(this.search_visible && action.search_view_id) {
|
||||
this.searchview_id = action.search_view_id[0];
|
||||
var searchview = this.searchview = new openerp.base.SearchView(
|
||||
this.session, this.element_id + "_search",
|
||||
this.dataset, this.searchview_id,
|
||||
this.search_defaults());
|
||||
searchview.on_search.add(this.do_search);
|
||||
searchview.start();
|
||||
|
||||
if (action['auto_search']) {
|
||||
searchview.on_loaded.add_last(
|
||||
searchview.do_search);
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < action.views.length; i++) {
|
||||
var view_id, controller;
|
||||
view_id = action.views[i][0];
|
||||
if(action.views[i][1] == "tree") {
|
||||
controller = new openerp.base.ListView(this.session, this.element_id + "_view_tree", this.dataset, view_id);
|
||||
controller.start();
|
||||
this.views.tree = { view_id: view_id, controller: controller };
|
||||
this.$element.find(prefix_id + "_button_tree").bind('click',function(){
|
||||
self.on_mode_switch("tree");
|
||||
});
|
||||
} else if(action.views[i][1] == "form") {
|
||||
controller = new openerp.base.FormView(this.session, this.element_id + "_view_form", this.dataset, view_id);
|
||||
controller.start();
|
||||
this.views.form = { view_id: view_id, controller: controller };
|
||||
this.$element.find(prefix_id + "_button_form").bind('click',function(){
|
||||
self.on_mode_switch("form");
|
||||
});
|
||||
}
|
||||
}
|
||||
// switch to the first one in sequence
|
||||
this.on_mode_switch("tree");
|
||||
},
|
||||
// create when root, also add to parent when o2m
|
||||
on_create: function() {
|
||||
},
|
||||
on_remove: function() {
|
||||
},
|
||||
on_edit: function() {
|
||||
},
|
||||
do_search: function (domains, contexts, groupbys) {
|
||||
var self = this;
|
||||
this.rpc('/base/session/eval_domain_and_context', {
|
||||
domains: domains,
|
||||
contexts: contexts,
|
||||
group_by_seq: groupbys
|
||||
}, function (results) {
|
||||
// TODO: handle non-empty results.group_by with read_group
|
||||
self.dataset.set({
|
||||
context: results.context,
|
||||
domain: results.domain
|
||||
}).fetch(0, self.action.limit);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Extends view manager
|
||||
openerp.base.ViewManagerRoot = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
// Extends view manager
|
||||
openerp.base.ViewManagerUsedAsAMany2One = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
/**
|
||||
* Base class for widgets. Handle rendering (based on a QWeb template), identifier
|
||||
* generation, parenting and destruction of the widget.
|
||||
*/
|
||||
openerp.base.BaseWidget = openerp.base.Controller.extend({
|
||||
/**
|
||||
* The name of the QWeb template that will be used for rendering. Must be redifined
|
||||
* in subclasses or the render() method can not be used.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
template: null,
|
||||
/**
|
||||
* The prefix used to generate an id automatically. Should be redifined in subclasses.
|
||||
* If it is not defined, a default identifier will be used.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
identifier_prefix: 'generic-identifier',
|
||||
/**
|
||||
* Contructor. Also initialize the identifier.
|
||||
*
|
||||
* @params {openerp.base.search.BaseWidget} parent The parent widget.
|
||||
*/
|
||||
init: function (parent) {
|
||||
this.children = [];
|
||||
this.parent = null;
|
||||
this.set_parent(parent);
|
||||
this.make_id(this.identifier_prefix);
|
||||
},
|
||||
/**
|
||||
* Sets and returns a globally unique identifier for the widget.
|
||||
*
|
||||
* If a prefix is appended, the identifier will be appended to it.
|
||||
*
|
||||
* @params sections prefix sections, empty/falsy sections will be removed
|
||||
*/
|
||||
make_id: function () {
|
||||
this.element_id = _.uniqueId(_.toArray(arguments).join('_'));
|
||||
return this.element_id;
|
||||
},
|
||||
/**
|
||||
* "Starts" the widgets. Called at the end of the rendering, this allows
|
||||
* to get a jQuery object referring to the DOM ($element attribute).
|
||||
*/
|
||||
start: function () {
|
||||
this._super();
|
||||
var tmp = document.getElementById(this.element_id)
|
||||
this.$element = tmp ? $(tmp) : null;
|
||||
},
|
||||
/**
|
||||
* "Stops" the widgets. Called when the view destroys itself, this
|
||||
* lets the widgets clean up after themselves.
|
||||
*/
|
||||
stop: function () {
|
||||
var tmp_children = this.children;
|
||||
this.children = [];
|
||||
_.each(tmp_children, function(x) {
|
||||
x.stop();
|
||||
});
|
||||
if(this.$element != null) {
|
||||
this.$element.remove();
|
||||
}
|
||||
this.set_parent(null);
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Set the parent of this component, also unregister the previous parent if there
|
||||
* was one.
|
||||
*
|
||||
* @param {openerp.base.BaseWidget} parent The new parent.
|
||||
*/
|
||||
set_parent: function(parent) {
|
||||
if(this.parent) {
|
||||
this.parent.children = _.without(this.parent.children, this);
|
||||
}
|
||||
this.parent = parent;
|
||||
if(this.parent) {
|
||||
parent.children.push(this);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Render the widget. This.template must be defined.
|
||||
* The content of the current object is passed as context to the template.
|
||||
*
|
||||
* @param {object} additional Additional context arguments to pass to the template.
|
||||
*/
|
||||
render: function (additional) {
|
||||
return QWeb.render(this.template, _.extend({}, this,
|
||||
additional != null ? additional : {}));
|
||||
}
|
||||
});
|
||||
openerp.base.CalendarView = openerp.base.Controller.extend({
|
||||
// Dhtmlx scheduler ?
|
||||
});
|
||||
|
||||
openerp.base.GanttView = openerp.base.Controller.extend({
|
||||
// Dhtmlx gantt ?
|
||||
});
|
||||
|
||||
openerp.base.DiagramView = openerp.base.Controller.extend({
|
||||
//
|
||||
});
|
||||
|
||||
openerp.base.GraphView = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
openerp.base.ProcessView = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
openerp.base.HelpView = openerp.base.Controller.extend({
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
Loading…
Reference in New Issue