-openerp.web.list = function (instance) {
+(function() {
+
+var instance = openerp;
+openerp.web.list = {};
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
this.groups = groups;
$(this.groups).bind({
- 'selected': function (e, ids, records) {
- self.do_select(ids, records);
+ 'selected': function (e, ids, records, deselected) {
+ self.do_select(ids, records, deselected);
},
'deleted': function (e, ids) {
self.do_delete(ids);
current_date: new Date().toString('yyyy-MM-dd')
// TODO: time, datetime, relativedelta
});
-
+ var i;
+ var pair;
+ var expression;
if (this.fonts) {
- for(var i=0, len=this.fonts.length; i<len; ++i) {
- var pair = this.fonts[i],
- font = pair[0],
+ for(i=0, len=this.fonts.length; i<len; ++i) {
+ pair = this.fonts[i];
+ var font = pair[0];
expression = pair[1];
if (py.evaluate(expression, context).toJSON()) {
switch(font) {
}
if (!this.colors) { return style; }
- for(var i=0, len=this.colors.length; i<len; ++i) {
- var pair = this.colors[i],
- color = pair[0],
- expression = pair[1];
+ for(i=0, len=this.colors.length; i<len; ++i) {
+ pair = this.colors[i];
+ var color = pair[0];
+ expression = pair[1];
if (py.evaluate(expression, context).toJSON()) {
return style += 'color: ' + color + ';';
}
sort_by_column: function (e) {
e.stopPropagation();
var $column = $(e.currentTarget);
- var col_name = $column.data('id')
+ var col_name = $column.data('id');
var field = this.fields_view.fields[col_name];
// test if the field is a function field with store=false, since it's impossible
// for the server to sort those fields we desactivate the feature
var total = dataset.size();
var limit = this.limit() || total;
- if (total == 0)
+ if (total === 0)
this.$pager.hide();
else
this.$pager.css("display", "");
* @param {String} [view="page"] the view type to switch to
*/
select_record:function (index, view) {
- view = view || index == null ? 'form' : 'form';
+ view = view || index === null || index === undefined ? 'form' : 'form';
this.dataset.index = index;
_.delay(_.bind(function () {
this.do_switch_view(view);
var reloaded = $.Deferred();
this.$el.find('.oe_list_content').append(
this.groups.render(function () {
+ // Keep '=='. This is not a mistake, this is a wanted behaviour to match null & undefined
if (self.dataset.index == null) {
if (self.records.length) {
self.dataset.index = 0;
* @param {Array} ids selected record ids
* @param {Array} records selected record values
*/
- do_select: function (ids, records) {
+ do_select: function (ids, records, deselected) {
+ // uncheck header hook if at least one row has been deselected
+ if (deselected) {
+ this.$('.oe_list_record_selector').prop('checked', false);
+ }
+
if (!ids.length) {
this.dataset.index = 0;
if (this.sidebar) {
return ids;
},
/**
+ * Calculate the active domain of the list view. This should be done only
+ * if the header checkbox has been checked. This is done by evaluating the
+ * search results, and then adding the dataset domain (i.e. action domain).
+ */
+ get_active_domain: function () {
+ var self = this;
+ if (this.$('.oe_list_record_selector').prop('checked')) {
+ var search_view = this.getParent().searchview;
+ var search_data = search_view.build_search_data();
+ return instance.web.pyeval.eval_domains_and_contexts({
+ domains: search_data.domains,
+ contexts: search_data.contexts,
+ group_by_seq: search_data.groupbys || []
+ }).then(function (results) {
+ var domain = self.dataset.domain.concat(results.domain || []);
+ return domain
+ });
+ }
+ else {
+ return $.Deferred().resolve();
+ }
+ },
+ /**
* Adds padding columns at the start or end of all table rows (including
* field names row)
*
.delegate('th.oe_list_record_selector', 'click', function (e) {
e.stopPropagation();
var selection = self.get_selection();
+ var checked = $(e.currentTarget).find('input').prop('checked');
$(self).trigger(
- 'selected', [selection.ids, selection.records]);
+ 'selected', [selection.ids, selection.records, ! checked]);
})
.delegate('td.oe_list_record_delete button', 'click', function (e) {
e.stopPropagation();
bind_child_events: function (child) {
var $this = $(this),
self = this;
- $(child).bind('selected', function (e) {
+ $(child).bind('selected', function (e, _0, _1, deselected) {
// can have selections spanning multiple links
var selection = self.get_selection();
- $this.trigger(e, [selection.ids, selection.records]);
+ $this.trigger(e, [selection.ids, selection.records, deselected]);
}).bind(this.passthrough_events, function (e) {
// additional positional parameters are provided to trigger as an
// Array, following the event type or event object, but are
limit = view.limit(),
page = this.datagroup.openable ? this.page : view.page;
- var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
+ var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name');
var options = { offset: page * limit, limit: limit, context: {bin_size: true} };
//TODO xmo: investigate why we need to put the setTimeout
return $.async_when().then(function() {
// if drag to 1st row (to = 0), start sequencing from 0
// (exclusive lower bound)
seq = to ? list.records.at(to - 1).get(seqname) : 0;
- while (++seq, record = list.records.at(index++)) {
+ var fct = function (dataset, id, seq) {
+ $.async_when().done(function () {
+ var attrs = {};
+ attrs[seqname] = seq;
+ dataset.write(id, attrs);
+ });
+ };
+ while (++seq, (record = list.records.at(index++))) {
// write are independent from one another, so we can just
// launch them all at the same time and we don't really
// give a fig about when they're done
// FIXME: breaks on o2ms (e.g. Accounting > Financial
// Accounting > Taxes > Taxes, child tax accounts)
// when synchronous (without setTimeout)
- (function (dataset, id, seq) {
- $.async_when().done(function () {
- var attrs = {};
- attrs[seqname] = seq;
- dataset.write(id, attrs);
- });
- }(dataset, record.get('id'), seq));
+ fct(dataset, record.get('id'), seq);
record.set(seqname, seq);
}
}
this.datagroup.list(
_(this.view.visible_columns).chain()
- .filter(function (column) { return column.tag === 'field' })
+ .filter(function (column) { return column.tag === 'field';})
.pluck('name').value(),
function (groups) {
$el[0].appendChild(
return {
count: this.datagroup.length,
values: this.datagroup.aggregates
- }
+ };
}
return _(this.children).chain()
.map(function (child) {
var instance_ = (records[i] instanceof Record) ? records[i] : new Record(records[i]);
instance_.bind(null, this._onRecordEvent);
this._byId[instance_.get('id')] = instance_;
- if (options.at == undefined) {
+ if (options.at === undefined || options.at === null) {
this.records.push(instance_);
if (!options.silent) {
this.trigger('add', this, instance_, this.records.length-1);
if (!_(this._proxies).isEmpty()) {
var record = null;
_(this._proxies).detect(function (proxy) {
- return record = proxy.get(id);
+ record = proxy.get(id);
+ return record;
});
return record;
}
* @returns {Collection}
*/
proxy: function (section) {
- return this._proxies[section] = new Collection(null, {
+ this._proxies[section] = new Collection(null, {
parent: this,
key: section
}).bind(null, this._onRecordEvent);
+ return this._proxies[section];
},
/**
* @param {Array} [records]
var record;
for(var section in this._proxies) {
if (!this._proxies.hasOwnProperty(section)) {
- continue
+ continue;
}
if ((record = this._proxies[section].find(callback))) {
return record;
'field': 'instance.web.list.Column',
'field.boolean': 'instance.web.list.Boolean',
'field.binary': 'instance.web.list.Binary',
+ 'field.char': 'instance.web.list.Char',
'field.progressbar': 'instance.web.list.ProgressBar',
'field.handle': 'instance.web.list.Handle',
'button': 'instance.web.list.Button',
tag + '.'+ description.type,
tag
]);
- return new Type(id, node.tag, description)
+ return new Type(id, node.tag, description);
};
instance.web.list.Column = instance.web.Class.extend({
});
}
});
+instance.web.list.Char = instance.web.list.Column.extend({
+ replacement: '*',
+ /**
+ * If password field, only display replacement characters (if value is
+ * non-empty)
+ */
+ _format: function (row_data, options) {
+ var value = row_data[this.id].value;
+ if (value && this.password === 'True') {
+ return value.replace(/[\s\S]/g, _.escape(this.replacement));
+ }
+ return this._super(row_data, options);
+ }
+});
instance.web.list.ProgressBar = instance.web.list.Column.extend({
/**
* Return a formatted progress bar display
return this._super(row_data, options);
}
});
-};
+})();
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: