summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorDivyesh Makwana (Open ERP) <mdi@tinyerp.com>2012-11-02 16:16:28 +0530
committerDivyesh Makwana (Open ERP) <mdi@tinyerp.com>2012-11-02 16:16:28 +0530
commitede1da0a6437ec6cef0958033be1973d3e1dff60 (patch)
treee2b3b38d299529796232d31452913e7a7cd482a1 /addons/web/static/src
parentabd1258be69748805a6d9d2715392b2ea767e20f (diff)
parent378f8fb1e8edb1e85a52c1c3c30af0fd28e64241 (diff)
[Merge] Merge with trunk.
bzr revid: mdi@tinyerp.com-20121102104628-qcf3cgpqgecbqml1
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css125
-rw-r--r--addons/web/static/src/css/base.sass108
-rw-r--r--addons/web/static/src/js/coresetup.js3
-rw-r--r--addons/web/static/src/js/data.js14
-rw-r--r--addons/web/static/src/js/search.js1
-rw-r--r--addons/web/static/src/js/view_form.js273
-rw-r--r--addons/web/static/src/js/view_list.js5
-rw-r--r--addons/web/static/src/js/view_list_editable.js20
-rw-r--r--addons/web/static/src/js/views.js6
-rw-r--r--addons/web/static/src/xml/base.xml46
10 files changed, 471 insertions, 130 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 64b782835f2..d6fce64ca10 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -217,7 +217,7 @@
background-clip: padding-box;
}
.openerp.ui-dialog .ui-dialog-content {
- padding: 0px;
+ padding: 0;
}
.openerp.ui-dialog .ui-dialog-titlebar, .openerp.ui-dialog .ui-dialog-content, .openerp.ui-dialog .ui-dialog-buttonpane {
padding: 16px;
@@ -2060,10 +2060,11 @@
padding-bottom: 0;
}
.openerp .oe_form div.oe_chatter {
- min-width: 650px;
- max-width: 860px;
+ box-sizing: border-box;
+ min-width: 682px;
+ max-width: 892px;
margin: 0 auto;
- padding: 16px 0 48px;
+ padding: 16px 16px 48px;
}
.openerp .oe_form div.oe_form_configuration p, .openerp .oe_form div.oe_form_configuration ul, .openerp .oe_form div.oe_form_configuration ol {
color: #aaaaaa;
@@ -2518,6 +2519,9 @@
.openerp .oe_form_field_one2many > .oe_view_manager .oe_list_pager_single_page, .openerp .oe_form_field_many2many > .oe_view_manager .oe_list_pager_single_page {
display: none !important;
}
+.openerp .oe_form_field_one2many > .oe_view_manager .oe_view_manager_view_list, .openerp .oe_form_field_many2many > .oe_view_manager .oe_view_manager_view_list {
+ min-height: 132px;
+}
.openerp .oe_form_field_one2many .oe_form_field_one2many_list_row_add, .openerp .oe_form_field_many2many .oe_form_field_one2many_list_row_add {
font-weight: bold;
}
@@ -2563,9 +2567,6 @@
.openerp .oe_list_editable .oe_list_content td.oe_list_field_cell {
padding: 4px 6px 3px 6px;
}
-.openerp .oe_list.oe_list_editable td.oe_list_record_delete {
- position: absolute;
-}
.openerp .oe_list.oe_list_editable.oe_editing .oe_edition .oe_list_field_cell:not(.oe_readonly) {
color: transparent;
}
@@ -2874,6 +2875,78 @@
color: #333333;
}
+.openerp .oe_fileupload {
+ display: inline-block;
+ clear: both;
+ width: 100%;
+}
+.openerp .oe_fileupload .oe_add {
+ float: left;
+ position: relative;
+ width: 100%;
+ left: 2px;
+ top: 7px;
+}
+.openerp .oe_fileupload .oe_add button {
+ display: inline;
+ height: 24px;
+ font-size: 12px;
+ line-height: 12px;
+ vertical-align: middle;
+}
+.openerp .oe_fileupload .oe_add button.oe_attach {
+ width: 24px;
+ overflow: hidden;
+ width: 24px;
+ overflow: hidden;
+ background: transparent;
+ color: #7c7bad;
+ box-shadow: none;
+ border: none;
+ text-shadow: none;
+}
+.openerp .oe_fileupload .oe_add button.oe_attach .oe_e {
+ position: relative;
+ top: -1px;
+ left: -9px;
+}
+.openerp .oe_fileupload .oe_add input.oe_form_binary_file {
+ display: inline-block;
+ margin-left: -5px;
+ height: 28px;
+ width: 52px;
+ margin-top: -26px;
+}
+.openerp .oe_fileupload .oe_add .oe_attach_label {
+ color: #7c7bad;
+ margin-left: -3px;
+}
+.openerp .oe_fileupload .oe_attachments {
+ margin-bottom: 4px;
+ margin-right: 0px;
+ font-size: 12px;
+ border-radius: 2px;
+ border: solid 1px rgba(124, 123, 173, 0.14);
+}
+.openerp .oe_fileupload .oe_attachments .oe_attachment {
+ padding: 2px;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+.openerp .oe_fileupload .oe_attachments .oe_attachment .oe_e {
+ font-size: 23px;
+ margin-top: -5px;
+}
+.openerp .oe_fileupload .oe_attachments .oe_attachment .oe_e:hover {
+ text-decoration: none;
+}
+.openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(odd) {
+ background: white;
+}
+.openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(even) {
+ background: #f4f5fa;
+}
+
.kitten-mode-activated {
background-image: url(http://placekitten.com/g/1365/769);
background-size: cover;
@@ -2927,3 +3000,41 @@ div.ui-widget-overlay {
-webkit-border-radius: 3px;
border-radius: 3px;
}
+
+@media print {
+ .openerp {
+ text-shadow: none;
+ }
+ .openerp .oe_header_row, .openerp ul.oe_header, .openerp div.oe_mail_thread_action, .openerp .oe_mail_recthread_actions, .openerp .oe_button_box, .openerp .oe_form button, .openerp button.oe_invite, .openerp .oe_form header, .openerp .openerp .oe_notebook > li.ui-state-default {
+ display: none;
+ }
+ .openerp .oe_list_content button, .openerp .oe_list_content input[type=checkbox] {
+ visibility: hidden;
+ }
+ .openerp .tree_header button, .openerp .oe_mail .oe_mail_thread_msg .oe_mail_unread, .openerp .oe_mail_fetch_more, .openerp .oe_m2o_drop_down_button img, .openerp .oe_form_field_one2many_list_row_add {
+ visibility: hidden;
+ }
+ .openerp a.oe_m2o_cm_button, .openerp a.oe_e {
+ visibility: hidden;
+ }
+ .openerp .oe_form .oe_form_field_date img, .openerp .oe_form .oe_form_field_datetime img {
+ visibility: hidden;
+ }
+ .openerp .oe_notebook > li.ui-tabs-selected {
+ display: block;
+ }
+ .openerp .oe_application .oe_form_sheet, .openerp .oe_application .oe_form_sheetbg {
+ border: 0px !important;
+ box-shadow: 0px 0px 0px;
+ }
+ .openerp .oe_view_manager_current > .oe_view_manager_header {
+ border: 0px !important;
+ box-shadow: 0px 0px 0px;
+ }
+ .openerp .text-core .text-wrap .text-arrow {
+ background: none;
+ }
+ .openerp .openerp div.oe_mail_wall {
+ overflow: hidden !important;
+ }
+}
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index f84d30a93ea..1719a863549 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -10,6 +10,8 @@ $tag-border-selected: #a6a6fe
$hover-background: #f0f0fa
$link-color: #7C7BAD
$sheet-max-width: 860px
+$sheet-min-width: 650px
+$sheet-padding: 16px
// }}}
// Mixins {{{
@font-face
@@ -256,6 +258,7 @@ $sheet-max-width: 860px
// so remove position:relative
.ui-tabs
position: static
+
// Modal box
&.ui-dialog
display: none
@@ -269,7 +272,7 @@ $sheet-max-width: 860px
@include box-shadow(0 1px 12px rgba(0, 0, 0, 0.6))
@include background-clip()
.ui-dialog-content
- padding: 0px
+ padding: 0
.ui-dialog-titlebar, .ui-dialog-content, .ui-dialog-buttonpane
padding: 16px
.ui-dialog-titlebar
@@ -1634,10 +1637,11 @@ $sheet-max-width: 860px
width: 400px
padding-bottom: 0
div.oe_chatter
- min-width: 650px
- max-width: $sheet-max-width
+ box-sizing: border-box
+ min-width: $sheet-min-width + 2* $sheet-padding
+ max-width: $sheet-max-width + 2* $sheet-padding
margin: 0 auto
- padding: 16px 0 48px
+ padding: 16px 16px 48px
div.oe_form_configuration
p, ul, ol
color: #aaa
@@ -1983,6 +1987,9 @@ $sheet-max-width: 860px
> .oe_view_manager
.oe_list_pager_single_page
display: none !important
+ .oe_view_manager_view_list
+ min-height: 132px
+
.oe_form_field_one2many_list_row_add
font-weight: bold
.oe_list_content
@@ -2027,9 +2034,6 @@ $sheet-max-width: 860px
.oe_list_content
td.oe_list_field_cell
padding: 4px 6px 3px 6px
- .oe_list.oe_list_editable
- td.oe_list_record_delete
- position: absolute
.oe_list.oe_list_editable.oe_editing
.oe_edition .oe_list_field_cell:not(.oe_readonly)
*
@@ -2273,6 +2277,67 @@ $sheet-max-width: 860px
float: right
color: #333
// }}}
+
+.openerp
+ .oe_fileupload
+ display: inline-block
+ clear: both
+ width: 100%
+ .oe_add
+ float: left
+ position: relative
+ width: 100%
+ left: +2px
+ top: +7px
+ button
+ display: inline
+ height: 24px
+ font-size: 12px
+ line-height: 12px
+ vertical-align: middle
+ button.oe_attach
+ width: 24px
+ overflow: hidden
+ width: 24px
+ overflow: hidden
+ background: transparent
+ color: #7C7BAD
+ box-shadow: none
+ border: none
+ text-shadow: none
+ .oe_e
+ position: relative
+ top: -1px
+ left: -9px
+ input.oe_form_binary_file
+ display: inline-block
+ margin-left: -5px
+ height: 28px
+ width: 52px
+ margin-top: -26px
+ .oe_attach_label
+ color: #7C7BAD
+ margin-left: -3px
+ .oe_attachments
+ margin-bottom: 4px
+ margin-right: 0px
+ font-size: 12px
+ border-radius: 2px
+ border: solid 1px rgba(124,123,173,0.14)
+ .oe_attachment
+ padding: 2px
+ padding-left: 4px
+ padding-right: 4px
+ .oe_e
+ font-size: 23px
+ margin-top: -5px
+ .oe_e:hover
+ text-decoration: none
+ .oe_attachment:nth-child(odd)
+ background: white
+ .oe_attachment:nth-child(even)
+ background: #F4F5FA
+
// Kitten Mode {{{
.kitten-mode-activated
background-image: url(http://placekitten.com/g/1365/769)
@@ -2314,5 +2379,34 @@ div.ui-widget-overlay
.ui-corner-all
@include radius(3px)
+@media print
+ .openerp
+ .oe_header_row, ul.oe_header, div.oe_mail_thread_action, .oe_mail_recthread_actions, .oe_button_box, .oe_form button, button.oe_invite, .oe_form header, .openerp .oe_notebook > li.ui-state-default
+ display: none
+ .oe_list_content
+ button, input[type=checkbox]
+ visibility: hidden
+ .tree_header button, .oe_mail .oe_mail_thread_msg .oe_mail_unread, .oe_mail_fetch_more, .oe_m2o_drop_down_button img, .oe_form_field_one2many_list_row_add
+ visibility: hidden
+ a
+ &.oe_m2o_cm_button, &.oe_e
+ visibility: hidden
+ .oe_form
+ .oe_form_field_date img, .oe_form_field_datetime img
+ visibility: hidden
+ .oe_notebook > li.ui-tabs-selected
+ display: block
+ .oe_application
+ .oe_form_sheet, .oe_form_sheetbg
+ border: 0px !important
+ box-shadow: 0px 0px 0px
+ .oe_view_manager_current > .oe_view_manager_header
+ border: 0px !important
+ box-shadow: 0px 0px 0px
+ text-shadow: none
+ .text-core .text-wrap .text-arrow
+ background: none
+ .openerp div.oe_mail_wall
+ overflow: hidden !important
// au BufWritePost,FileWritePost *.sass :!sass --style expanded --line-numbers <afile> > "%:p:r.css"
// vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker:
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index 1f1112df2f2..220b9b63d5c 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -530,7 +530,8 @@ instance.web.qweb.default_dict['__debug__'] = instance.session.debug; // Which o
instance.web.qweb.debug = instance.session.debug;
instance.web.qweb.default_dict = {
'_' : _,
- '_t' : instance.web._t
+ '_t' : instance.web._t,
+ 'JSON': JSON,
};
instance.web.qweb.preprocess_node = function() {
// Note that 'this' is the Qweb Node
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index e279ade6fb3..63c90f53758 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -471,7 +471,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
default_get: function(fields, options) {
options = options || {};
return this._model.call('default_get',
- [fields], {context: this._model.context(options.context)});
+ [fields], {context: this.get_context(options.context)});
},
/**
* Creates a new record in db
@@ -480,7 +480,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
* @returns {$.Deferred}
*/
create: function(data) {
- return this._model.call('create', [data], {context: this._model.context()});
+ return this._model.call('create', [data], {context: this.get_context()});
},
/**
* Saves the provided data in an existing db record
@@ -493,7 +493,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
*/
write: function (id, data, options) {
options = options || {};
- return this._model.call('write', [[id], data], {context: this._model.context(options.context)}).then(this.trigger('dataset_changed', id, data, options));
+ return this._model.call('write', [[id], data], {context: this.get_context(options.context)}).then(this.trigger('dataset_changed', id, data, options));
},
/**
* Deletes an existing record from the database
@@ -501,7 +501,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
* @param {Number|String} ids identifier of the record to delete
*/
unlink: function(ids) {
- return this._model.call('unlink', [ids], {context: this._model.context()}).then(this.trigger('dataset_changed', ids));
+ return this._model.call('unlink', [ids], {context: this.get_context()}).then(this.trigger('dataset_changed', ids));
},
/**
* Calls an arbitrary RPC method
@@ -532,7 +532,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
* @returns {$.Deferred}
*/
name_get: function(ids) {
- return this._model.call('name_get', [ids], {context: this._model.context()});
+ return this._model.call('name_get', [ids], {context: this.get_context()});
},
/**
*
@@ -556,7 +556,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
* @param name
*/
name_create: function(name) {
- return this._model.call('name_create', [name], {context: this._model.context()});
+ return this._model.call('name_create', [name], {context: this.get_context()});
},
exec_workflow: function (id, signal) {
return this._model.exec_workflow(id, signal);
@@ -606,7 +606,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
return instance.session.rpc('/web/dataset/resequence', {
model: this.model,
ids: ids,
- context: this._model.context(options.context),
+ context: this.get_context(options.context),
}).pipe(function (results) {
return results;
});
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 9351f621324..520dcd9169f 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -788,6 +788,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
instance.web.search.fields = new instance.web.Registry({
'char': 'instance.web.search.CharField',
'text': 'instance.web.search.CharField',
+ 'html': 'instance.web.search.CharField',
'boolean': 'instance.web.search.BooleanField',
'integer': 'instance.web.search.IntegerField',
'id': 'instance.web.search.IntegerField',
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 72d9725e105..e0727b99259 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -427,7 +427,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var onchange = _.str.trim(on_change);
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
if (!call) {
- return null;
+ throw new Error("Wrong on change format: " + onchange);
}
var method = call[1];
@@ -494,71 +494,59 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var self = this;
return this.on_change_mutex.exec(function() {
try {
- var response = {}, can_process_onchange = $.Deferred();
+ var def;
processed = processed || [];
processed.push(widget.name);
var on_change = widget.node.attrs.on_change;
if (on_change) {
var change_spec = self.parse_on_change(on_change, widget);
- if (change_spec) {
- var ajax = {
- url: '/web/dataset/onchange',
- async: false
- };
- can_process_onchange = self.rpc(ajax, {
- model: self.dataset.model,
- method: change_spec.method,
- args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(change_spec.args),
- context_id: change_spec.context_index == undefined ? null : change_spec.context_index + 1
- }).then(function(r) {
- _.extend(response, r);
- });
- } else {
- console.warn("Wrong on_change format", on_change);
- }
- }
- // fail if onchange failed
- if (can_process_onchange.isRejected()) {
- return can_process_onchange;
+ def = self.rpc('/web/dataset/onchange', {
+ model: self.dataset.model,
+ method: change_spec.method,
+ args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(change_spec.args),
+ context_id: change_spec.context_index == undefined ? null : change_spec.context_index + 1
+ });
+ } else {
+ def = $.when({});
}
-
- if (widget.field['change_default']) {
- var fieldname = widget.name, value_;
- if (response.value && (fieldname in response.value)) {
- // Use value from onchange if onchange executed
- value_ = response.value[fieldname];
- } else {
- // otherwise get form value for field
- value_ = self.fields[fieldname].get_value();
- }
- var condition = fieldname + '=' + value_;
-
- if (value_) {
- can_process_onchange = self.rpc({
- url: '/web/dataset/call',
- async: false
- }, {
- model: 'ir.values',
- method: 'get_defaults',
- args: [self.model, condition]
- }).then(function (results) {
- if (!results.length) { return; }
- if (!response.value) {
- response.value = {};
- }
- for(var i=0; i<results.length; ++i) {
- // [whatever, key, value]
- var triplet = results[i];
- response.value[triplet[1]] = triplet[2];
- }
- });
+ return def.pipe(function(response) {
+ if (widget.field['change_default']) {
+ var fieldname = widget.name
+ var value_;
+ if (response.value && (fieldname in response.value)) {
+ // Use value from onchange if onchange executed
+ value_ = response.value[fieldname];
+ } else {
+ // otherwise get form value for field
+ value_ = self.fields[fieldname].get_value();
+ }
+ var condition = fieldname + '=' + value_;
+
+ if (value_) {
+ return self.rpc('/web/dataset/call', {
+ model: 'ir.values',
+ method: 'get_defaults',
+ args: [self.model, condition]
+ }).pipe(function (results) {
+ if (!results.length) {
+ return response;
+ }
+ if (!response.value) {
+ response.value = {};
+ }
+ for(var i=0; i<results.length; ++i) {
+ // [whatever, key, value]
+ var triplet = results[i];
+ response.value[triplet[1]] = triplet[2];
+ }
+ return response;
+ });
+ }
}
- }
- if (can_process_onchange.isRejected()) {
- return can_process_onchange;
- }
-
- return self.on_processed_onchange(response, processed);
+ return response;
+ }).pipe(function(response) {
+ return self.on_processed_onchange(response, processed);
+ });
} catch(e) {
console.error(e);
instance.webclient.crashmanager.show_message(e);
@@ -1590,37 +1578,6 @@ instance.web.form.DefaultFieldManager = instance.web.Widget.extend({
},
});
-instance.web.form.FormDialog = instance.web.Dialog.extend({
- init: function(parent, options, view_id, dataset) {
- this._super(parent, options);
- this.dataset = dataset;
- this.view_id = view_id;
- return this;
- },
- start: function() {
- var self = this;
- this._super();
- this.form = new instance.web.FormView(this, this.dataset, this.view_id, {
- pager: false
- });
- this.form.appendTo(this.$el);
- this.form.on('record_created', self, this.on_form_dialog_saved);
- this.form.on('record_saved', this, this.on_form_dialog_saved);
- return this;
- },
- select_id: function(id) {
- if (this.form.dataset.select_id(id)) {
- return this.form.do_show();
- } else {
- this.do_warn("Could not find id in dataset");
- return $.Deferred().reject();
- }
- },
- on_form_dialog_saved: function(r) {
- this.close();
- }
-});
-
instance.web.form.compute_domain = function(expr, fields) {
if (! (expr instanceof Array))
return !! expr;
@@ -2570,7 +2527,7 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc
if (! this.get("effective_readonly")) {
self._updating_editor = false;
this.$textarea = this.$el.find('textarea');
- var width = ((this.node.attrs || {}).editor_width || 468);
+ var width = ((this.node.attrs || {}).editor_width || '100%');
var height = ((this.node.attrs || {}).editor_height || 250);
this.$textarea.cleditor({
width: width, // width not including margins, borders or padding
@@ -3141,7 +3098,6 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
type: 'ir.actions.act_window',
res_model: self.field.relation,
res_id: self.get("value"),
- context: self.build_context(),
views: [[false, 'form']],
target: 'current'
});
@@ -3353,7 +3309,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
e.cancel = true;
});
_(controller.columns).find(function (column) {
- if (!column instanceof instance.web.list.Handle) {
+ if (!(column instanceof instance.web.list.Handle)) {
return false;
}
column.modifiers.invisible = true;
@@ -4567,6 +4523,10 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
self.select_elements(self.selected_ids);
self.destroy();
});
+ var $cbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-create");
+ $cbutton.click(function() {
+ self.new_object();
+ });
});
});
this.searchview.appendTo($(".oe_popup_search", self.$el));
@@ -4902,6 +4862,132 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
}
});
+/**
+ * Widget for (one2many field) to upload one or more file in same time and display in list.
+ * The user can delete his files.
+ * Options on attribute ; "blockui" {Boolean} block the UI or not
+ * during the file is uploading
+ */
+instance.web.form.FieldOne2ManyBinaryMultiFiles = instance.web.form.AbstractField.extend({
+ template: "FieldBinaryFileUploader",
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
+ this.field_manager = field_manager;
+ this.node = node;
+ if(this.field.type != "one2many" || this.field.relation != 'ir.attachment') {
+ throw "The type of the field '"+this.field.string+"' must be a one2many field with a relation to 'ir.attachment' model.";
+ }
+ this.ds_file = new instance.web.DataSetSearch(this, 'ir.attachment');
+ this.fileupload_id = _.uniqueId('oe_fileupload_temp');
+ $(window).on(this.fileupload_id, _.bind(this.on_file_loaded, this));
+ },
+ start: function() {
+ this._super(this);
+ this.$el.on('change', 'input.oe_form_binary_file', this.on_file_change );
+ },
+ get_value: function() {
+ return _.map(this.get('value'), function (value) { return commands.link_to( value.id ); });
+ },
+ get_file_url: function (attachment) {
+ return instance.origin + '/web/binary/saveas?session_id=' + this.session.session_id + '&model=ir.attachment&field=datas&filename_field=datas_fname&id=' + attachment['id'];
+ },
+ render_value: function () {
+ var render = $(instance.web.qweb.render('FieldBinaryFileUploader.files', {'widget': this}));
+ render.on('click', '.oe_delete', _.bind(this.on_file_delete, this));
+ this.$('.oe_placeholder_files, .oe_attachments').replaceWith( render );
+
+ // reinit input type file
+ var $input = this.$('input.oe_form_binary_file');
+ $input.after($input.clone(true)).remove();
+ this.$(".oe_fileupload").show();
+ },
+ on_file_change: function (event) {
+ event.stopPropagation();
+ var self = this;
+ var $target = $(event.target);
+ if ($target.val() !== '') {
+
+ var filename = $target.val().replace(/.*[\\\/]/,'');
+
+ // if the files is currently uploded, don't send again
+ if( !isNaN(_.find(this.get('value'), function (file) { return (file.filename || file.name) == filename && file.upload; } )) ) {
+ return false;
+ }
+
+ // block UI or not
+ if(this.node.attrs.blockui) {
+ instance.web.blockUI();
+ }
+
+ // if the files exits for this answer, delete the file before upload
+ var files = _.filter(this.get('value'), function (file) {
+ if((file.filename || file.name) == filename) {
+ self.ds_file.unlink([file.id]);
+ return false;
+ } else {
+ return true;
+ }
+ });
+
+ // TODO : unactivate send on wizard and form
+
+ // submit file
+ this.$('form.oe_form_binary_form').submit();
+ this.$(".oe_fileupload").hide();
+
+ // add file on result
+ files.push({
+ 'id': 0,
+ 'name': filename,
+ 'filename': filename,
+ 'url': '',
+ 'upload': true
+ });
+
+ this.set({'value': files});
+ }
+ },
+ on_file_loaded: function (event, result) {
+ // unblock UI
+ if(this.node.attrs.blockui) {
+ instance.web.unblockUI();
+ }
+
+ // TODO : activate send on wizard and form
+
+ var files = this.get('value');
+ for(var i in files){
+ if(files[i].filename == result.filename && files[i].upload) {
+ files[i] = {
+ 'id': result.id,
+ 'name': result.name,
+ 'filename': result.filename,
+ 'url': this.get_file_url(result)
+ };
+ }
+ }
+
+ this.set({'value': files});
+ this.render_value()
+ },
+ on_file_delete: function (event) {
+ event.stopPropagation();
+ var file_id=$(event.target).data("id");
+ if (file_id) {
+ var files=[];
+ for(var i in this.get('value')){
+ if(file_id != this.get('value')[i].id){
+ files.push(this.get('value')[i]);
+ }
+ else {
+ this.ds_file.unlink([file_id]);
+ }
+ }
+ this.set({'value': files});
+ }
+ },
+});
+
instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
template: "FieldStatus",
init: function(field_manager, node) {
@@ -5054,6 +5140,7 @@ instance.web.form.widgets = new instance.web.Registry({
'progressbar': 'instance.web.form.FieldProgressBar',
'image': 'instance.web.form.FieldBinaryImage',
'binary': 'instance.web.form.FieldBinaryFile',
+ 'one2many_binary': 'instance.web.form.FieldOne2ManyBinaryMultiFiles',
'statusbar': 'instance.web.form.FieldStatus',
'monetary': 'instance.web.form.FieldMonetary',
});
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index f04a58621e2..fd74fd8922b 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -374,7 +374,10 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
var total = dataset.size();
var limit = this.limit() || total;
- this.$pager.toggle(total !== 0);
+ if (total == 0)
+ this.$pager.hide();
+ else
+ this.$pager.css("display", "");
this.$pager.toggleClass('oe_list_pager_single_page', (total <= limit));
var spager = '-';
if (total) {
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index acc1d781976..021e5549c18 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -252,9 +252,10 @@ openerp.web.list_editable = function (instance) {
var position = $cell.position();
field.set_dimensions($cell.outerHeight(), $cell.outerWidth());
- field.$el.css({
- top: position.top,
- left: position.left,
+ field.$el.position({
+ my: 'left top',
+ at: 'left top',
+ of: $cell
});
},
/**
@@ -410,15 +411,15 @@ openerp.web.list_editable = function (instance) {
});
this.editor.$el.on('keyup keydown', function (e) {
- if (!self.editor.is_editing()) { return; }
+ if (!self.editor.is_editing()) { return true; }
var key = _($.ui.keyCode).chain()
.map(function (v, k) { return {name: k, code: v}; })
.find(function (o) { return o.code === e.which; })
.value();
- if (!key) { return; }
+ if (!key) { return true; }
var method = e.type + '_' + key.name;
- if (!(method in self)) { return; }
- self[method](e);
+ if (!(method in self)) { return true; }
+ return self[method](e);
});
},
/**
@@ -446,7 +447,10 @@ openerp.web.list_editable = function (instance) {
keyup_ENTER: function () {
return this._next();
},
- keyup_ESCAPE: function () {
+ keydown_ESCAPE: function (e) {
+ return false;
+ },
+ keyup_ESCAPE: function (e) {
return this.cancel_edition();
},
/**
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index c6b150a4d77..ebc7c326724 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -1281,11 +1281,9 @@ instance.web.View = instance.web.Widget.extend({
},
/**
* Switches to a specific view type
- *
- * @param {String} view view type to switch to
*/
- do_switch_view: function(view) {
- this.trigger('switch_mode',view);
+ do_switch_view: function() {
+ this.trigger.apply(this, ['switch_mode'].concat(_.toArray(arguments)));
},
/**
* Cancels the switch to the current view, switches to the previous one
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 5a5a8a491ca..275d31a9fde 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1175,6 +1175,48 @@
<iframe t-att-id="fileupload_id" t-att-name="fileupload_id" style="display: none"/>
</div>
</t>
+<t t-name="FieldBinaryFileUploader.files">
+ <div class="oe_attachments">
+ <t t-if="!widget.get('effective_readonly')" t-foreach="widget.get('value')" t-as="file">
+ <div class="oe_attachment">
+ <span t-if="(file.upload or file.percent_loaded&lt;100)" t-attf-title="{(file.name || file.filename) + (file.date?' \n('+file.date+')':'' )}" t-attf-name="{file.name || file.filename}">
+ <span class="oe_fileuploader_in_process">...Upload in progress...</span>
+ <t t-raw="file.name || file.filename"/>
+ </span>
+ <a t-if="(!file.upload or file.percent_loaded&gt;=100)" t-att-href="file.url" t-attf-title="{(file.name || file.filename) + (file.date?' \n('+file.date+')':'' )}">
+ <t t-raw="file.name || file.filename"/>
+ </a>
+ <t t-if="(!file.upload or file.percent_loaded&gt;=100)">
+ <a class="oe_right oe_delete oe_e" title="Delete this file" t-attf-data-id="{file.id}">[</a>
+ </t>
+ </div>
+ </t>
+ <t t-if="widget.get('effective_readonly')" t-foreach="widget.get('value')" t-as="file">
+ <div>
+ <a t-att-href="file.url" t-attf-title="{(file.name || file.filename) + (file.date?' \n('+file.date+')':'' )}">
+ <t t-raw="file.name || file.filename"/>
+ </a>
+ </div>
+ </t>
+ </div>
+</t>
+<t t-name="FieldBinaryFileUploader">
+ <div t-att-style="widget.node.attrs.style" t-attf-class="oe_fileupload #{widget.node.attrs.class ? widget.node.attrs.class :''}">
+ <div class="oe_placeholder_files"/>
+ <div class="oe_add" t-if="!widget.get('effective_readonly')">
+ <!-- uploader of file -->
+ <button class="oe_attach"><span class="oe_e">'</span></button>
+ <span class='oe_attach_label'>File</span>
+ <t t-call="HiddenInputFile">
+ <t t-set="fileupload_id" t-value="widget.fileupload_id"/>
+ <t t-set="fileupload_action">/web/binary/upload_attachment</t>
+ <input type="hidden" name="model" t-att-value="widget.view.model"/>
+ <input type="hidden" name="id" value="0"/>
+ <input type="hidden" name="session_id" t-att-value="widget.session.session_id"/>
+ </t>
+ </div>
+ </div>
+</t>
<t t-name="WidgetButton">
<button type="button" class="oe_button oe_form_button"
t-att-style="widget.node.attrs.style"
@@ -1237,9 +1279,9 @@
<t t-name="SelectCreatePopup.search.buttons">
<t t-if="! widget.options.disable_multiple_selection">
<button type="button" class="oe_button oe_selectcreatepopup-search-select" disabled="disabled">Select</button>
- or
</t>
- <a class="oe_button oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
+ <button type="button" class="oe_button oe_selectcreatepopup-search-create">Create</button>
+ or <a class="oe_button oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
</t>
<t t-name="AbstractFormPopup.buttons">
<t t-if="! readonly">