summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorYogesh (OpenERP) <ysa@tinyerp.com>2011-11-17 10:27:31 +0530
committerYogesh (OpenERP) <ysa@tinyerp.com>2011-11-17 10:27:31 +0530
commitae931e7a9d29e65271fbc3151f7db35cfd4655d3 (patch)
tree597806878d54a302d180db9060f524813dc60a16 /addons/web/static/src
parentbc3a1f52940ec65db7b72141490711aacb6703a5 (diff)
parent811c58e69737d61b42b953cffb95f857b22700de (diff)
[MERGE] Merge with trunk upto revision no 1493.
bzr revid: ysa@tinyerp.com-20111117045731-9zjfsdrt7j590yx1
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css16
-rw-r--r--addons/web/static/src/js/chrome.js55
-rw-r--r--addons/web/static/src/js/core.js4
-rw-r--r--addons/web/static/src/js/data.js9
-rw-r--r--addons/web/static/src/js/formats.js14
-rw-r--r--addons/web/static/src/js/search.js10
-rw-r--r--addons/web/static/src/js/view_form.js80
-rw-r--r--addons/web/static/src/js/view_list.js18
-rw-r--r--addons/web/static/src/js/views.js6
-rw-r--r--addons/web/static/src/xml/base.xml20
10 files changed, 140 insertions, 92 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index c061353d113..2db16ff04b2 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -973,9 +973,6 @@ label.error {
.openerp .oe_forms input.field_datetime {
min-width: 11em;
}
-.openerp .oe_forms.oe_frame .oe_datepicker_root {
- width: 100%;
-}
.openerp .oe_forms .button {
color: #4c4c4c;
white-space: nowrap;
@@ -989,13 +986,20 @@ label.error {
cursor: pointer;
right: 5px;
top: 3px;
+ z-index: 2;
+}
+.openerp .oe_datepicker_container {
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: none;
}
.openerp .oe_datepicker_root {
position: relative;
display: inline-block;
}
-.openerp .oe_datepicker_root input[type="text"] {
- min-width: 160px;
+.openerp .oe_forms.oe_frame .oe_datepicker_root {
+ width: 100%;
}
.openerp .oe_input_icon_disabled {
position: absolute;
@@ -1003,7 +1007,7 @@ label.error {
opacity: 0.5;
filter:alpha(opacity=50);
right: 5px;
- top: 5px;
+ top: 3px;
}
.openerp img.oe_field_translate {
margin-left: -21px;
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 25b73ee59d5..2b838ee3743 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -158,7 +158,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
},
on_managed_error: function(error) {
$('<div>' + QWeb.render('DialogWarning', {error: error}) + '</div>').dialog({
- title: "OpenERP " + _.capitalize(error.type),
+ title: "OpenERP " + _.str.capitalize(error.type),
buttons: {
Ok: function() {
$(this).dialog("close");
@@ -168,7 +168,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
},
on_traceback: function(error) {
var dialog = new openerp.web.Dialog(this, {
- title: "OpenERP " + _.capitalize(error.type),
+ title: "OpenERP " + _.str.capitalize(error.type),
autoOpen: true,
width: '90%',
height: '90%',
@@ -184,7 +184,8 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
}
});
-openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
+openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
+ template: 'Loading',
/**
* @constructs openerp.web.Loading
* @extends openerp.web.Widget
@@ -192,8 +193,8 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
* @param parent
* @param element_id
*/
- init: function(parent, element_id) {
- this._super(parent, element_id);
+ init: function(parent) {
+ this._super(parent);
this.count = 0;
this.blocked_ui = false;
this.session.on_rpc_request.add_first(this.on_rpc_event, 1);
@@ -210,12 +211,13 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
}
this.count += increment;
- if (this.count) {
+ if (this.count > 0) {
//this.$element.html(QWeb.render("Loading", {}));
this.$element.html("Loading ("+this.count+")");
this.$element.show();
this.widget_parent.$element.addClass('loading');
} else {
+ this.count = 0;
clearTimeout(this.long_running_timer);
// Don't unblock if blocked by somebody else
if (self.blocked_ui) {
@@ -242,10 +244,8 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
this.$option_id = $('#' + option_id);
},
start: function() {
+ this._super();
this.$element.html(QWeb.render("Database", this));
- this.$element.closest(".openerp")
- .removeClass("login-mode")
- .addClass("database_block");
var self = this;
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
@@ -266,23 +266,30 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
this.$element.find('#db-restore').click(this.do_restore);
this.$element.find('#db-change-password').click(this.do_change_password);
this.$element.find('#back-to-login').click(function() {
- self.stop();
+ self.hide();
});
},
stop: function () {
+ this.hide();
this.$option_id.empty();
this.$element
.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login')
.unbind('click')
.end()
- .closest(".openerp")
- .addClass("login-mode")
- .removeClass("database_block")
- .end()
.empty();
this._super();
},
+ show: function () {
+ this.$element.closest(".openerp")
+ .removeClass("login-mode")
+ .addClass("database_block");
+ },
+ hide: function () {
+ this.$element.closest(".openerp")
+ .addClass("login-mode")
+ .removeClass("database_block")
+ },
/**
* Converts a .serializeArray() result into a dict. Does not bother folding
* multiple identical keys into an array, last key wins.
@@ -368,6 +375,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
}
self.db_list.push(self.to_object(fields)['db_name']);
self.db_list.sort();
+ self.widget_parent.set_db_list(self.db_list);
var form_obj = self.to_object(fields);
self.wait_for_newdb(result, {
password: form_obj['super_admin_pwd'],
@@ -397,6 +405,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
}
$db_list.find(':selected').remove();
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
+ self.widget_parent.set_db_list(self.db_list);
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
});
}
@@ -529,16 +538,16 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
var self = this;
this.database = new openerp.web.Database(
this, "oe_database", "oe_db_options");
+ this.database.start();
this.$element.find('#oe-db-config').click(function() {
- self.database.start();
+ self.database.show();
});
this.$element.find("form").submit(this.on_submit);
this.rpc("/web/database/get_list", {}, function(result) {
- var tpl = openerp.web.qweb.render('Login_dblist', {db_list: result.db_list, selected_db: self.selected_db});
- self.$element.find("input[name=db]").replaceWith(tpl)
+ self.set_db_list(result.db_list);
},
function(error, event) {
if (error.data.fault_code === 'AccessDenied') {
@@ -547,6 +556,15 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
});
},
+ stop: function () {
+ this.database.stop();
+ this._super();
+ },
+ set_db_list: function (list) {
+ this.$element.find("[name=db]").replaceWith(
+ openerp.web.qweb.render('Login_dblist', {
+ db_list: list, selected_db: this.selected_db}))
+ },
on_login_invalid: function() {
this.$element.closest(".openerp").addClass("login-mode");
},
@@ -966,7 +984,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this.$element.html(QWeb.render("Interface", params));
this.notification = new openerp.web.Notification(this);
- this.loading = new openerp.web.Loading(this,"oe_loading");
+ this.loading = new openerp.web.Loading(this);
this.crashmanager = new openerp.web.CrashManager();
this.header = new openerp.web.Header(this);
@@ -990,6 +1008,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
start: function() {
this._super.apply(this, arguments);
this.notification.prependTo(this.$element);
+ this.loading.appendTo($('#oe_loading'));
this.header.appendTo($("#oe_header"));
this.session.start();
this.login.appendTo($('#oe_login'));
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index 369e1191665..f77f9bf1041 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -716,7 +716,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
if (parseInt(cookie_val, 10) !== token) { continue; }
// clear cookie
- document.cookie = _.sprintf("%s=;expires=%s;path=/",
+ document.cookie = _.str.sprintf("%s=;expires=%s;path=/",
cookie_name, new Date().toGMTString());
if (options.success) { options.success(); }
complete();
@@ -1055,7 +1055,7 @@ openerp.web.qweb.format_text_node = function(s) {
if (translation && translation.value === 'off') {
return s;
}
- var ts = _.trim(s);
+ var ts = _.str.trim(s);
if (ts.length === 0) {
return s;
}
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index f4509c82a81..e783f374dce 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -119,17 +119,18 @@ openerp.web.ContainerDataGroup = openerp.web.DataGroup.extend( /** @lends opener
aggregates[key] = value || 0;
});
+ var group_size = fixed_group[field_name + '_count'] || fixed_group.__count || 0;
+ var leaf_group = fixed_group.__context.group_by.length === 0;
return {
__context: fixed_group.__context,
__domain: fixed_group.__domain,
grouped_on: field_name,
// if terminal group (or no group) and group_by_no_leaf => use group.__count
- length: fixed_group[field_name + '_count'] || fixed_group.__count,
+ length: group_size,
value: fixed_group[field_name],
-
- openable: !(this.context['group_by_no_leaf']
- && fixed_group.__context.group_by.length === 0),
+ // A group is openable if it's not a leaf in group_by_no_leaf mode
+ openable: !(leaf_group && this.context['group_by_no_leaf']),
aggregates: aggregates
};
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index c4af2d0cf6b..3151b34636b 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -76,7 +76,13 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
if (typeof value === 'number' && isNaN(value)) {
value = false;
}
+ //noinspection FallthroughInSwitchStatementJS
switch (value) {
+ case '':
+ if (descriptor.type === 'char') {
+ return '';
+ }
+ console.warn('Field', descriptor, 'had an empty string as value, treating as false...');
case false:
case Infinity:
case -Infinity:
@@ -86,18 +92,18 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
switch (descriptor.widget || descriptor.type) {
case 'integer':
return openerp.web.insert_thousand_seps(
- _.sprintf('%d', value));
+ _.str.sprintf('%d', value));
case 'float':
var precision = descriptor.digits ? descriptor.digits[1] : 2;
- var formatted = _.sprintf('%.' + precision + 'f', value).split('.');
+ var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
return formatted.join(l10n.decimal_point);
case 'float_time':
- return _.sprintf("%02d:%02d",
+ return _.str.sprintf("%02d:%02d",
Math.floor(value),
Math.round((value % 1) * 60));
case 'progressbar':
- return _.sprintf(
+ return _.str.sprintf(
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
value, value);
case 'many2one':
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 4fb5f02c690..f95801975b5 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -41,7 +41,11 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
if (this.headless) {
this.ready.resolve();
} else {
- this.rpc("/web/searchview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
+ this.rpc("/web/searchview/load", {
+ model: this.model,
+ view_id: this.view_id,
+ context: this.dataset.get_context()
+ }, this.on_loaded);
}
return this.ready.promise();
},
@@ -137,7 +141,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
on_loaded: function(data) {
if (data.fields_view.type !== 'search' ||
data.fields_view.arch.tag !== 'search') {
- throw new Error(_.sprintf(
+ throw new Error(_.str.sprintf(
"Got non-search view after asking for a search view: type %s, arch root %s",
data.fields_view.type, data.fields_view.arch.tag));
}
@@ -425,7 +429,7 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
this.message = message;
},
toString: function () {
- return _.sprintf(
+ return _.str.sprintf(
_t("Incorrect value for field %(fieldname)s: [%(value)s] is %(message)s"),
{fieldname: this.field, value: this.value, message: this.message}
);
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 84041ef8b60..fea577512a0 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -35,7 +35,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.fields = {};
this.datarecord = {};
this.show_invalid = true;
- this.dirty_for_user = false;
this.default_focus_field = null;
this.default_focus_button = null;
this.registry = this.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
@@ -172,7 +171,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
this.$form_header.find('.oe_form_on_readonly').toggle(this.readonly);
this.$form_header.find('.oe_form_on_editable').toggle(!this.readonly);
- this.dirty_for_user = false;
this.datarecord = record;
for (var f in this.fields) {
var field = this.fields[f];
@@ -240,7 +238,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
try {
processed = processed || [];
if (widget.node.attrs.on_change) {
- var onchange = _.trim(widget.node.attrs.on_change);
+ var onchange = _.str.trim(widget.node.attrs.on_change);
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
if (call) {
var method = call[1], args = [];
@@ -257,7 +255,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
};
var parent_fields = null;
_.each(call[2].split(','), function(a, i) {
- var field = _.trim(a);
+ var field = _.str.trim(a);
if (field in argument_replacement) {
args.push(argument_replacement[field](i));
return;
@@ -267,11 +265,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return;
} else {
var splitted = field.split('.');
- if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
+ if (splitted.length > 1 && _.str.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
if (parent_fields === null) {
parent_fields = self.dataset.parent_view.get_fields_values();
}
- var p_val = parent_fields[_.trim(splitted[1])];
+ var p_val = parent_fields[_.str.trim(splitted[1])];
if (p_val !== undefined) {
args.push(p_val == null ? false : p_val);
return;
@@ -317,7 +315,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
processed.push(field.name);
if (field.get_value() != value) {
field.set_value(value);
- field.dirty = this.dirty_for_user = true;
+ field.dirty = true;
if (_.indexOf(processed, field.name) < 0) {
this.do_onchange(field, processed);
}
@@ -402,7 +400,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return def.promise();
},
can_be_discarded: function() {
- return !this.dirty_for_user || confirm(_t("Warning, the record has been modified, your changes will be discarded."));
+ return !this.is_dirty() || confirm(_t("Warning, the record has been modified, your changes will be discarded."));
},
/**
* Triggers saving the form's record. Chooses between creating a new
@@ -418,8 +416,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
try {
if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected())
return;
- var form_dirty = false,
- form_invalid = false,
+ var form_invalid = false,
values = {},
first_invalid_field = null;
for (var f in self.fields) {
@@ -431,7 +428,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
first_invalid_field = f;
}
} else if (f.is_dirty()) {
- form_dirty = true;
values[f.name] = f.get_value();
}
}
@@ -553,6 +549,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return self.dataset.parent_view.recursive_save();
});
},
+ is_dirty: function() {
+ return _.any(this.fields, function (value) {
+ return value.is_dirty();
+ });
+ },
is_interactible_record: function() {
var id = this.datarecord.id;
if (!id) {
@@ -638,7 +639,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
},
on_attachment_delete: function(e) {
var self = this, $e = $(e.currentTarget);
- var name = _.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
+ var name = _.str.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
if (confirm("Do you really want to delete the attachment " + name + " ?")) {
this.rpc('/web/dataset/unlink', {
model: 'ir.attachment',
@@ -798,8 +799,13 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
_build_view_fields_values: function() {
var a_dataset = this.view.dataset;
var fields_values = this.view.get_fields_values();
- var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
- fields_values.parent = parent_values;
+ var active_id = a_dataset.ids[a_dataset.index];
+ _.extend(fields_values, {
+ active_id: active_id || false,
+ active_ids: active_id ? [active_id] : [],
+ active_model: a_dataset.model,
+ parent: a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {}
+ });
return fields_values;
},
_build_eval_context: function() {
@@ -1231,7 +1237,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
}
},
on_ui_change: function() {
- this.dirty = this.view.dirty_for_user = true;
+ this.dirty = true;
this.validate();
if (this.is_valid()) {
this.set_value_from_ui();
@@ -1344,54 +1350,58 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({
template: "web.datetimepicker",
jqueryui_object: 'datetimepicker',
type_of_date: "datetime",
+ init: function(parent) {
+ this._super(parent);
+ this.name = parent.name;
+ },
start: function() {
var self = this;
- this.$element.find('input').change(this.on_change);
+ this.$input = this.$element.find('input.oe_datepicker_master');
+ this.$input_picker = this.$element.find('input.oe_datepicker_container');
+ this.$input.change(this.on_change);
this.picker({
onSelect: this.on_picker_select,
changeMonth: true,
changeYear: true,
showWeek: true,
- showButtonPanel: false
+ showButtonPanel: true
});
this.$element.find('img.oe_datepicker_trigger').click(function() {
if (!self.readonly) {
self.picker('setDate', self.value ? openerp.web.auto_str_to_date(self.value) : new Date());
- self.$element.find('.oe_datepicker').toggle();
+ self.$input_picker.show();
+ self.picker('show');
+ self.$input_picker.hide();
}
});
- this.$element.find('.ui-datepicker-inline').removeClass('ui-widget-content ui-corner-all');
- this.$element.find('button.oe_datepicker_close').click(function() {
- self.$element.find('.oe_datepicker').hide();
- });
this.set_readonly(false);
this.value = false;
},
picker: function() {
- return $.fn[this.jqueryui_object].apply(this.$element.find('.oe_datepicker_container'), arguments);
+ return $.fn[this.jqueryui_object].apply(this.$input_picker, arguments);
},
on_picker_select: function(text, instance) {
var date = this.picker('getDate');
- this.$element.find('input').val(date ? this.format_client(date) : '').change();
+ this.$input.val(date ? this.format_client(date) : '').change();
},
set_value: function(value) {
this.value = value;
- this.$element.find('input').val(value ? this.format_client(value) : '');
+ this.$input.val(value ? this.format_client(value) : '');
},
get_value: function() {
return this.value;
},
set_value_from_ui: function() {
- var value = this.$element.find('input').val() || false;
+ var value = this.$input.val() || false;
this.value = this.parse_client(value);
},
set_readonly: function(readonly) {
this.readonly = readonly;
- this.$element.find('input').attr('disabled', this.readonly);
+ this.$input.attr('disabled', this.readonly);
this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly);
},
is_valid: function(required) {
- var value = this.$element.find('input').val();
+ var value = this.$input.val();
if (value === "") {
return !required;
} else {
@@ -1404,7 +1414,7 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({
}
},
focus: function() {
- this.$element.find('input').focus();
+ this.$input.focus();
},
parse_client: function(v) {
return openerp.web.parse_value(v, {"widget": this.type_of_date});
@@ -1421,11 +1431,7 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({
openerp.web.DateWidget = openerp.web.DateTimeWidget.extend({
jqueryui_object: 'datepicker',
- type_of_date: "date",
- on_picker_select: function(text, instance) {
- this._super(text, instance);
- this.$element.find('.oe_datepicker').hide();
- }
+ type_of_date: "date"
});
openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({
@@ -1437,7 +1443,7 @@ openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({
var self = this;
this._super.apply(this, arguments);
this.datewidget = this.build_widget();
- this.datewidget.on_change.add(this.on_ui_change);
+ this.datewidget.on_change.add_last(this.on_ui_change);
this.datewidget.appendTo(this.$element);
},
set_value: function(value) {
@@ -1825,7 +1831,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
if (search_val.length > 0 &&
!_.include(raw_result, search_val) &&
(!self.value || search_val !== self.value[1])) {
- values.push({label: _.sprintf(_t('<em>   Create "<strong>%s</strong>"</em>'),
+ values.push({label: _.str.sprintf(_t('<em>   Create "<strong>%s</strong>"</em>'),
$('<span />').text(search_val).html()), action: function() {
self._quick_create(search_val);
}});
@@ -2955,7 +2961,7 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
render_list: function() {
var self = this;
var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","),
- function(x) { return _.trim(x); });
+ function(x) { return _.str.trim(x); });
shown = _.select(shown, function(x) { return x.length > 0; });
if (shown.length == 0) {
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 77f04d4c864..728b090d679 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -295,7 +295,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
} else {
last = first + limit;
}
- this.$element.find('span.oe-pager-state').empty().text(_.sprintf(
+ this.$element.find('span.oe-pager-state').empty().text(_.str.sprintf(
"[%d to %d] of %d", first + 1, last, total));
this.$element
@@ -647,7 +647,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return;
}
- $footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
+ $footer_cells.filter(_.str.sprintf('[data-field=%s]', column.id))
.html(openerp.web.format_cell(aggregation, column, undefined, false));
});
},
@@ -1127,7 +1127,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
child.datagroup = group;
var $row = child.$row = $('<tr>');
- if (group.openable) {
+ if (group.openable && group.length) {
$row.click(function (e) {
if (!$row.data('open')) {
$row.data('open', true)
@@ -1159,7 +1159,13 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
} catch (e) {
$group_column.html(row_data[group_column.id].value);
}
- if (group.openable) {
+ if (!group.length) {
+ // Kinda-ugly hack: jquery-ui has no "empty" icon, so set
+ // wonky background position to ensure nothing is displayed
+ // there but the rest of the behavior is ui-icon's
+ $group_column.prepend(
+ '<span class="ui-icon" style="float: left; background-position: 150px 150px">');
+ } else if (group.openable) {
// Make openable if not terminal group & group_by_no_leaf
$group_column
.prepend('<span class="ui-icon ui-icon-triangle-1-e" style="float: left;">');
@@ -1186,7 +1192,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
format = "%.2f";
}
$('<td>')
- .text(_.sprintf(format, value))
+ .text(_.str.sprintf(format, value))
.appendTo($row);
} else {
$row.append('<td>');
@@ -1245,7 +1251,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var pages = Math.ceil(dataset.ids.length / limit);
self.$row
.find('.oe-pager-state')
- .text(_.sprintf('%d/%d', page + 1, pages))
+ .text(_.str.sprintf('%d/%d', page + 1, pages))
.end()
.find('button[data-pager-action=previous]')
.attr('disabled', page === 0)
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index efa5ac5b2a8..d348b2d7240 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -534,7 +534,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
$logs_list = $logs.find('ul').empty();
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
_(log_records.reverse()).each(function (record) {
- $(_.sprintf('<li><a href="#">%s</a></li>', record.name))
+ $(_.str.sprintf('<li><a href="#">%s</a></li>', record.name))
.appendTo($logs_list)
.delegate('a', 'click', function (e) {
self.do_action({
@@ -628,7 +628,7 @@ session.web.Sidebar = session.web.Widget.extend({
},
add_section: function(name, code) {
- if(!code) code = _.underscored(name);
+ if(!code) code = _.str.underscored(name);
var $section = this.sections[code];
if(!$section) {
@@ -656,7 +656,7 @@ session.web.Sidebar = session.web.Widget.extend({
//
var self = this,
- $section = this.add_section(_.titleize(section_code.replace('_', ' ')), section_code),
+ $section = this.add_section(_.str.titleize(section_code.replace('_', ' ')), section_code),
section_id = $section.attr('id');
if (items) {
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 9b1c5175571..ab1429b931f 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -18,7 +18,7 @@
</div>
</t>
<t t-name="Interface">
- <div id="oe_loading" class="loading"></div>
+ <div id="oe_loading"></div>
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
<tr>
<td colspan="2" valign="top">
@@ -63,7 +63,9 @@
</table>
</t>
<t t-name="Loading">
+ <div class="loading">
Loading...
+ </div>
</t>
<t t-name="Database">
<ul class="db_options" style="padding: 0px; display: inline;">
@@ -703,7 +705,7 @@
</t>
<t t-name="Widget">
Unhandled widget
- <t t-raw="console.log('Unhandled widget', widget)"/>
+ <t t-js="dict">console.warn('Unhandled widget', dict.widget);</t>
</t>
<t t-name="WidgetFrame">
<table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
@@ -896,13 +898,13 @@
</t>
<t t-name="web.datetimepicker">
<div class="oe_datepicker_root">
- <input type="text" size="1" style="width: 100%"/>
+ <input type="text" size="1" style="width: 100%"
+ t-att-name="widget.name"
+ t-attf-class="oe_datepicker_master field_#{widget.type_of_date}"
+ />
<img class="oe_input_icon oe_datepicker_trigger" src="/web/static/src/img/ui/field_calendar.png"
title="Select date" width="16" height="16" border="0"/>
- <div class="oe_datepicker ui-widget-content ui-corner-all" style="display: none; position: absolute; z-index: 1;">
- <div class="oe_datepicker_container"/>
- <button type="button" class="oe_datepicker_close ui-state-default ui-priority-primary ui-corner-all" style="float: right;">Done</button>
- </div>
+ <input type="text" size="1" class="oe_datepicker_container" disabled="disabled"/>
</div>
</t>
<t t-name="FieldSelection">
@@ -1152,8 +1154,8 @@
t-att-title="attrs.help"
t-att-class="classes.join(' ')"
t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined">
- <img t-if="attrs.icon" t-att-src="'/web/static/src/img/icons/' + attrs.icon + '.png'" width="16" height="16"/>
- <br t-if="attrs.icon and attrs.string"/>
+ <img t-att-src="'/web/static/src/img/icons/' + (attrs.icon || 'gtk-home') + '.png'" width="16" height="16"/>
+ <br t-if="attrs.string"/>
<t t-esc="attrs.string"/>
</button>
<span t-name="SearchView.filters" class="filter_label_group"