[MERGE] from mainline branch, hook in new record handling

bzr revid: xmo@openerp.com-20110412132120-ii3mosez9kguvcjb
This commit is contained in:
Xavier Morel 2011-04-12 15:21:20 +02:00
commit d7da740264
15 changed files with 1633 additions and 149 deletions

View File

@ -385,6 +385,12 @@ class DataSet(openerpweb.Controller):
value = r[0]
return {'value': value}
@openerpweb.jsonrequest
def create(self, req, model, data, context={}):
m = req.session.model(model)
r = m.create(data, context)
return {'result': r}
@openerpweb.jsonrequest
def save(self, req, model, id, data, context={}):
m = req.session.model(model)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
/*
* jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
* http://benalman.com/projects/jquery-bbq-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
/*
* jQuery hashchange event - v1.2 - 2/11/2010
* http://benalman.com/projects/jquery-hashchange-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this);

View File

@ -166,7 +166,9 @@ var QWeb = {
for (var an in g_att) {
att += " " + an + '="' + this.escape_att(g_att[an]) + '"';
}
return inner.length ? "<" + e.tagName + att + ">" + inner + "</" + e.tagName + ">" : "<" + e.tagName + att + "/>";
// Some IE versions have problems with closed tags
var opentag = !!t_att['opentag'] && this.eval_bool(t_att["opentag"], v);
return inner.length || opentag ? "<" + e.tagName + att + ">" + inner + "</" + e.tagName + ">" : "<" + e.tagName + att + "/>";
},
render_att_att:function(e, t_att, g_att, v, ext, av) {
if (ext) {

View File

@ -15,6 +15,7 @@
<script type="text/javascript" src="/base/static/lib/jquery.ui.notify/js/jquery.notify.js"></script>
<script type="text/javascript" src="/base/static/lib/jquery.superfish/js/hoverIntent.js"></script>
<script type="text/javascript" src="/base/static/lib/jquery.superfish/js/superfish.js"></script>
<script type="text/javascript" src="/base/static/lib/jquery.ba-bbq/jquery.ba-bbq.js"></script>
<script type="text/javascript" src="/base/static/src/js/base.js"></script>
<script type="text/javascript" src="/base/static/src/js/chrome.js"></script>
<script type="text/javascript" src="/base/static/src/js/data.js"></script>

View File

@ -172,7 +172,10 @@ body.openerp {
padding: 0 0 2px;
border: none;
background: none;
padding-left: 20px;
padding-left: 10px;
}
.openerp .secondary_menu h3 span, .openerp .secondary_menu h4 span {
left: 0 !important;
}
.openerp .secondary_menu a {
display: block;
@ -201,6 +204,9 @@ body.openerp {
text-shadow: #fff 0 1px 0;
border: none !important;
}
.openerp div.submenu_accordion div.menu_content a span {
padding-left: 20px;
}
/* Header */
.openerp .header {
@ -305,16 +311,39 @@ body.openerp {
}
/* Footer */
.openerp .footer {
.openerp div.oe_footer {
background: none repeat scroll 0 0 #CCCCCC;
overflow: hidden;
padding: 5px 0;
position: relative;
-moz-box-shadow: inset 0px 3px 5px rgba(0, 0, 0, 0.4);
-webkit-box-shadow: inset 0px 3px 5px rgba(0, 0, 0, 0.4);
box-shadow: inset 0px 3px 5px rgba(0, 0, 0, 0.4);
}
.openerp div.oe_footer p.oe_footer_powered {
left: 50%;
margin: 0;
padding: 0 15px;
color: #666666;
font-weight: bold;
font-size: 0.8em;
font-family: Ubuntu, Helvetica, sans-serif;
text-align: center;
}
.openerp div.oe_footer p.oe_footer_powered a {
text-decoration: none;
color: #666666;
}
/* Main Application */
.openerp .application {
padding: 6px;
padding: 0px;
}
.openerp h2.oe_view_title {
font-size: 175%;
font-weight: normal;
font-family: Ubuntu, Helvetica, sans-serif;
margin: 2px 0;
color: #252424;
text-shadow: white 0 1px 0;
@ -479,8 +508,37 @@ body.openerp {
border-bottom-right-radius: 7px;
}
/* Notebook */
.openerp .oe_form_notebook {
padding: 0px;
background: none;
border-width: 0px;
}
.openerp .oe_form_notebook ul.ui-tabs-nav {
padding-left: 0px;
background: transparent;
border-width: 0px 0px 1px 0px;
border-radius: 0px;
-moz-border-radius: 0px;
-webkit-border-radius: 0px;
line-height: 0.5em;
}
.openerp .oe_form_notebook ul.ui-tabs-nav li {
font-weight: bold;
}
.openerp .oe_form_notebook .ui-tabs-panel {
background: #f9f9f9;
border-width: 0px 1px 1px 1px;
}
.openerp .oe_form_notebook .ui-tabs-selected {
background: #f9f9f9;
}
/* Form */
.openerp table.oe_frame td {
color: #4c4c4c;
font-weight: 80%;
}
.openerp .required.error {
border: 1px solid #900;
}
@ -491,6 +549,22 @@ body.openerp {
float: right;
}
.openerp label.oe_form_label_help {
cursor: help;
}
.openerp label.oe_form_label, .openerp label.oe_form_label_help {
display: block;
text-align: right;
}
.openerp label.oe_form_label_help span {
font-size: 80%;
color: darkgreen;
vertical-align:top;
position: relative;
top: -4px;
padding: 0 2px;
}
/* Inputs */
.openerp input[type="text"], .openerp input[type="password"], .openerp select, .openerp textarea {
-moz-box-sizing: border-box;
@ -503,11 +577,14 @@ body.openerp {
-webkit-border-radius: 3px;
border-radius: 3px;
background: white;
min-width: 90px;
color: #1f1f1f;
}
.openerp input[type="text"], .openerp input[type="password"], .openerp select, .openerp .button {
height: 22px;
}
.openerp .button {
color: #4c4c4c;
white-space: nowrap;
}
.openerp .button span {
@ -543,37 +620,119 @@ body.openerp {
.openerp .ui-widget {
font-size: 1em;
}
.openerp .oe_form_field_progressbar .ui-progressbar {
height: 22px;
font-size: 10px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #999;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
background: white;
min-width: 90px;
}
/* Sidebar */
.openerp .view-manager-main-table {
margin: 0;
width:100%;
border-collapse:collapse;
height:100%;
}
.openerp .view-manager-main-sidebar {
.openerp .view-manager-main-table tbody {
vertical-align: top;
}
.openerp .view-manager-main-content {
padding: 6px;
}
.openerp .view-manager-main-sidebar {
width:0;
padding:0;
margin:0;
}
.openerp .view-manager-main-sidebar .sidebar-main-div {
padding:0;
margin:0;
.openerp .sidebar-main-div {
height:100%;
}
.openerp .view-manager-main-sidebar .sidebar-sub-div {
border: solid 1px #1F1F1F;
border-bottom-width: 0;
.openerp .sidebar-sub-div {
padding:0;
margin:0;
width:180px;
border-left-color: #D2CFCF;
border-left-style: solid;
border-left-width: 1px;
height:100%;
font-family: Ubuntu, Helvetica, sans-serif;
font-size: 0.9em;
}
.openerp .closed-sidebar .sidebar-sub-div {
width:22px;
}
.openerp .closed-sidebar .sidebar-displaying-div {
display:none;
}
.openerp .sidebar-main-div a {
color: #555;
text-decoration: none;
}
.openerp .sidebar-main-div a:hover {
color: black;
}
.openerp .view-manager-main-sidebar h2 {
margin:0;
font-family: Ubuntu, Helvetica, sans-serif;
font-size: 1.15em;
color: #8E8E8E;
text-shadow: white 0px 1px 0px;
padding-left: 10px;
padding-right: 21px;
height: 21px;
background: url(../img/sideheader-a-bg.png) repeat-x;
border-color: #D2CFCF;
border-style: solid;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-width: 0;
border-right-width: 0;
}
.openerp .view-manager-main-sidebar ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 120px;
border-bottom: solid 1px #1F1F1F;
display: block;
}
.openerp .view-manager-main-sidebar li {
padding: 3px;
display: block;
padding: 3px 3px 3px 10px;
}
.openerp .toggle-sidebar {
border-color: #D2CFCF;
border-style: solid;
border-width: 1px;
display: block;
background: url(../img/toggle-a-bg.png);
width: 21px;
height: 21px;
position: absolute;
z-index: 10;
}
.openerp .open-sidebar .toggle-sidebar {
margin-left: 158px;
background-position: 21px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

View File

@ -245,12 +245,7 @@ openerp.base.Notification = openerp.base.BasicController.extend({
text: text
});
},
// TODO remove to avoid default as attribute
'default': function(title, text) {
this.notify(title,text);
},
// TODO change into warn to avoid alert
alert: function(title, text) {
warn: function(title, text) {
this.$element.notify('create', 'oe_notification_alert', {
title: title,
text: text
@ -478,8 +473,10 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
continue;
openerp[mod] = {};
// init module mod
openerp._openerp[mod](openerp);
self.module_loaded[mod] = true;
if(openerp._openerp[mod] != undefined) {
openerp._openerp[mod](openerp);
self.module_loaded[mod] = true;
}
}
}
});
@ -783,6 +780,10 @@ openerp.base.Header = openerp.base.Controller.extend({
this.do_update();
},
do_update: function() {
if(jQuery.param != undefined &&
jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
this.kitten = 1;
}
this.$element.html(QWeb.render("Header", this));
}
});
@ -907,11 +908,21 @@ openerp.base.WebClient = openerp.base.Controller.extend({
this.header.start();
this.login.start();
this.menu.start();
this.notification['default']("OpenERP Client", "The openerp client has been initialized.");
this.notification.notify("OpenERP Client", "The openerp client has been initialized.");
},
on_logged: function() {
this.action = new openerp.base.ActionManager(this.session, "oe_app");
this.action.start();
// if using saved actions, load the action and give it to action manager
var parameters = jQuery.deparam(jQuery.param.querystring());
if(parameters["s_action"] != undefined) {
var key = parseInt(parameters["s_action"]);
var self = this;
this.rpc("/base/session/get_session_action", {key:key}, function(action) {
self.action.do_action(action);
});
}
},
on_menu_action: function(action) {
this.action.do_action(action);

View File

@ -89,7 +89,12 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
context: this.context
}, callback);
},
create: function() {
create: function(data, callback) {
return this.rpc('/base/dataset/create', {
model: this.model,
data: data,
context: this.context
}, callback);
},
write: function (id, data, callback) {
return this.rpc('/base/dataset/save', {
@ -100,7 +105,7 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
}, callback);
},
unlink: function(ids) {
this.notification['default']("Unlink", ids);
this.notification.notify("Unlink", ids);
},
call: function (method, ids, args, callback) {
ids = ids || [];

View File

@ -27,6 +27,7 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
this.fields = {};
this.datarecord = {};
this.ready = false;
this.show_invalid = true;
},
start: function() {
//this.log('Starting FormView '+this.model+this.view_id)
@ -48,10 +49,10 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
self.on_pager_action(action);
});
this.$element.find('div.oe_form_buttons button.oe_form_button_save').click(this.do_save);
this.$element.find('div.oe_form_buttons button.oe_form_button_save_edit').click(this.do_save_edit);
this.$element.find('div.oe_form_buttons button.oe_form_button_cancel').click(this.do_cancel);
this.$element.find('div.oe_form_buttons button.oe_form_button_new').click(this.on_button_new);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_save').click(this.do_save);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_save_edit').click(this.do_save_edit);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_cancel').click(this.do_cancel);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_new').click(this.on_button_new);
// sidebar stuff
if (this.view_manager.sidebar) {
@ -59,8 +60,19 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
}
},
do_show: function () {
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
this.$element.show();
var self = this;
this.do_update_pager.add({
unique: true,
callback: function() {
self.$element.show();
}
});
if (this.dataset.index === null) {
// null index means we should start a new record
this.on_button_new();
} else {
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
}
},
do_hide: function () {
this.$element.hide();
@ -69,20 +81,22 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
if (record) {
this.datarecord = record;
for (var f in this.fields) {
this.fields[f].set_value(this.datarecord[f]);
this.fields[f].set_value(this.datarecord[f] || false);
this.fields[f].validate();
}
if (!record.id) {
this.show_invalid = false;
// Second pass in order to trigger the onchanges in case of new record
for (var f in record) {
this.fields[f].on_ui_change();
this.on_form_changed(this.fields[f]);
}
}
this.on_form_changed();
this.ready = true;
this.show_invalid = this.ready = true;
} else {
this.log("No record received");
}
this.do_update_pager();
this.do_update_pager(record.id == null);
},
on_form_changed: function(widget) {
if (widget && widget.node.attrs.on_change) {
@ -110,14 +124,13 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
this.dataset.index = this.dataset.ids.length - 1;
break;
}
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
this.reload();
},
do_update_pager: function() {
var $pager = this.$element.find('div.oe_form_pager');
$pager.find("button[data-pager-action='first'], button[data-pager-action='previous']").attr('disabled', this.dataset.index == 0);
$pager.find("button[data-pager-action='next'], button[data-pager-action='last']").attr('disabled', this.dataset.index == this.dataset.ids.length - 1);
this.$element.find('span.oe_pager_index').html(this.dataset.index + 1);
this.$element.find('span.oe_pager_count').html(this.dataset.count);
do_update_pager: function(hide_index) {
var $pager = this.$element.find('#' + this.element_id + '_header div.oe_form_pager').eq(0);
var index = hide_index ? '-' : this.dataset.index + 1;
$pager.find('span.oe_pager_index').html(index);
$pager.find('span.oe_pager_count').html(this.dataset.count);
},
do_onchange: function(widget, processed) {
processed = processed || [];
@ -196,7 +209,8 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
self.on_record_loaded(result.result);
});
},
do_save: function() {
do_save: function(success) {
var self = this;
if (!this.ready) {
return false;
}
@ -206,21 +220,31 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
f = this.fields[f];
if (f.invalid) {
invalid = true;
f.update_dom();
} else if (f.touched) {
values[f.name] = f.get_value();
}
}
if (invalid) {
this.on_invalid();
return false;
} else {
this.log("About to save", values);
this.dataset.write(this.datarecord.id, values, this.on_saved);
if (!this.datarecord.id) {
this.dataset.create(values, function(r) {
self.on_created(r, success);
});
} else {
this.dataset.write(this.datarecord.id, values, function(r) {
self.on_saved(r, success);
});
}
return true;
}
},
do_save_edit: function() {
if (this.do_save()) {
this.switch_readonly();
}
this.do_save();
//this.switch_readonly(); Use promises
},
switch_readonly: function() {
},
@ -234,24 +258,48 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
}
});
msg += "</ul>";
this.notification.alert("The following fields are invalid :", msg);
this.notification.warn("The following fields are invalid :", msg);
},
on_saved: function(r) {
on_saved: function(r, success) {
if (!r.result) {
this.log("Record was not saved");
this.notification.warn("Record not saved", "Problem while saving record.");
} else {
// Check response for exceptions, display error
this.notification['default']("Record saved", "The record #" + this.datarecord.id + " has been saved.");
this.notification.notify("Record saved", "The record #" + this.datarecord.id + " has been saved.");
if (success) {
success(r);
}
}
},
on_created: function(r, success) {
if (!r.result) {
this.notification.warn("Record not created", "Problem while creating record.");
} else {
this.datarecord.id = arguments[0].result;
this.dataset.ids.push(this.datarecord.id);
this.dataset.index = this.dataset.ids.length - 1;
this.dataset.count++;
this.do_update_pager();
this.notification.notify("Record created", "The record has been created with id #" + this.datarecord.id);
if (success) {
success(r);
}
}
},
do_search: function (domains, contexts, groupbys) {
this.notification['default']("Searching form");
this.notification.notify("Searching form");
},
on_action: function (action) {
this.notification['default']('Executing action ' + action);
this.notification.notify('Executing action ' + action);
},
do_cancel: function () {
this.notification['default']("Cancelling form");
this.notification.notify("Cancelling form");
},
reload: function() {
if (this.datarecord.id) {
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
} else {
this.on_button_new();
}
}
});
@ -396,12 +444,12 @@ openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({
}
}
},
handle_node: function(n) {
var type = this.view.fields_view.fields[n.attrs.name] || {};
var widget_type = n.attrs.widget || type.type || n.tag;
var widget = new (openerp.base.form.widgets.get_object(widget_type)) (this.view, n);
if (n.tag == 'field' && n.attrs.nolabel != '1') {
var label = new (openerp.base.form.widgets.get_object('label')) (this.view, n);
handle_node: function(node) {
var type = this.view.fields_view.fields[node.attrs.name] || {};
var widget_type = node.attrs.widget || type.type || node.tag;
var widget = new (openerp.base.form.widgets.get_object(widget_type)) (this.view, node);
if (node.tag == 'field' && node.attrs.nolabel != '1') {
var label = new (openerp.base.form.widgets.get_object('label')) (this.view, node);
label["for"] = widget;
this.add_widget(label);
}
@ -450,6 +498,61 @@ openerp.base.form.WidgetButton = openerp.base.form.Widget.extend({
init: function(view, node) {
this._super(view, node);
this.template = "WidgetButton";
},
start: function() {
this._super.apply(this, arguments);
this.$element.click(this.on_click);
},
on_click: function(saved) {
var self = this;
if (saved !== true) {
this.view.do_save(function() {
self.on_click(true);
});
} else {
if (this.node.attrs.confirm) {
var dialog = $('<div>' + this.node.attrs.confirm + '</div>').dialog({
title: 'Confirm',
modal: true,
buttons: {
Ok: function() {
self.on_confirmed();
$(this).dialog("close");
},
Cancel: function() {
$(this).dialog("close");
}
}
});
} else {
this.on_confirmed();
}
}
},
on_confirmed: function() {
var attrs = this.node.attrs;
if (attrs.special) {
return this.log("Should close the popup");
} else {
var type = attrs.type || 'workflow';
var context = _.extend({}, this.view.dataset.context, attrs.context || {});
switch(type) {
case 'object':
return this.view.dataset.call(attrs.name, [this.view.datarecord.id], [context], this.on_button_object);
break;
default:
this.log(_.sprintf("Unsupported button type : %s", type));
}
}
},
on_button_object: function(r) {
if (r.result === false) {
this.log("Button object returns false");
} else if (r.result.constructor == Object) {
console.log("TODO: send action to action manager", r.result);
} else {
this.view.reload();
}
}
});
@ -485,12 +588,13 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
if (node.attrs.nolabel != '1' && this.colspan > 1) {
this.colspan--;
}
this.field = view.fields_view.fields[node.attrs.name];
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.invisible = (this.invisible || this.field.invisible == '1');
this.nolabel = (this.field.nolabel || node.attrs.nolabel) == '1';
this.readonly = (this.field.readonly || node.attrs.readonly) == '1';
this.required = (this.field.required || node.attrs.required) == '1';
this.invalid = false;
this.touched = false;
},
@ -499,6 +603,9 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
this.invalid = false;
this.update_dom();
},
set_value_from_ui: function() {
this.value = undefined;
},
get_value: function() {
return this.value;
},
@ -506,10 +613,17 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
this._super.apply(this, arguments);
this.$element.toggleClass('disabled', this.readonly);
this.$element.toggleClass('required', this.required);
this.$element.toggleClass('invalid', this.invalid);
if (this.view.show_invalid) {
this.$element.toggleClass('invalid', this.invalid);
}
},
on_ui_change: function() {
this.touched = true;
this.set_value_from_ui();
this.validate();
this.view.on_form_changed(this);
},
validate: function() {
}
});
@ -531,31 +645,41 @@ openerp.base.form.FieldChar = openerp.base.form.Field.extend({
this._super.apply(this, arguments);
this.$element.find('input').attr('disabled', this.readonly);
},
on_ui_change: function() {
this._super.apply(this, arguments);
set_value_from_ui: function() {
this.value = this.$element.find('input').val();
this.invalid = this.required && this.value == "";
this.view.on_form_changed(this);
},
validate: function() {
this.invalid = false;
if (this.value === false || this.value === "") {
this.invalid = this.required;
} else if (this.validation_regex) {
this.invalid = !this.validation_regex.test(this.value);
}
}
});
openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({
init: function(view, node) {
this._super(view, node);
this.validation_regex = /@/;
}
});
openerp.base.form.FieldUrl = openerp.base.form.FieldChar.extend({
});
openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({
init: function(view, node) {
this._super(view, node);
this.validation_regex = /^\d+(\.\d+)?$/;
},
set_value: function(value) {
this._super.apply(this, arguments);
var show_value = (value != null && value !== false) ? value.toFixed(2) : '';
this.$element.find('input').val(value);
this.$element.find('input').val(show_value);
},
on_ui_change: function() {
this._super.apply(this, arguments);
set_value_from_ui: function() {
this.value = this.$element.find('input').val().replace(/,/g, '.');
this.invalid = (this.required && this.value == "") || !this.value.match(/^\d+(\.\d+)?$/) ;
this.view.on_form_changed(this);
}
});
@ -563,23 +687,13 @@ openerp.base.form.FieldDate = openerp.base.form.FieldChar.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldDate";
this.validation_regex = /^\d+-\d+-\d+$/;
},
start: function() {
this._super.apply(this, arguments);
this.$element.find('input').change(this.on_ui_change).datepicker({
dateFormat: 'yy-mm-dd'
});
},
set_value: function(value) {
this._super.apply(this, arguments);
var show_value = (value != null && value !== false) ? value : '';
this.$element.find('input').val(show_value);
},
on_ui_change: function() {
this._super.apply(this, arguments);
this.value = this.$element.find('input').val();
this.invalid = this.required && this.value == "";
this.view.on_form_changed(this);
}
});
@ -587,6 +701,7 @@ openerp.base.form.FieldDatetime = openerp.base.form.FieldChar.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldDatetime";
this.validation_regex = /^\d+-\d+-\d+( \d+:\d+(:\d+)?)?$/;
},
start: function() {
this._super.apply(this, arguments);
@ -594,17 +709,6 @@ openerp.base.form.FieldDatetime = openerp.base.form.FieldChar.extend({
dateFormat: 'yy-mm-dd',
timeFormat: 'hh:mm:ss'
});
},
set_value: function(value) {
this._super.apply(this, arguments);
var show_value = (value != null && value !== false) ? value : '';
this.$element.find('input').val(show_value);
},
on_ui_change: function() {
this._super.apply(this, arguments);
this.value = this.$element.find('input').val();
this.invalid = this.required && this.value == "";
this.view.on_form_changed(this);
}
});
@ -612,6 +716,7 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldText";
this.validation_regex = null;
},
start: function() {
this._super.apply(this, arguments);
@ -626,11 +731,16 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({
this._super.apply(this, arguments);
this.$element.find('textarea').attr('disabled', this.readonly);
},
on_ui_change: function() {
this._super.apply(this, arguments);
set_value_from_ui: function() {
this.value = this.$element.find('textarea').val();
this.invalid = this.required && this.value == "";
this.view.on_form_changed(this);
},
validate: function() {
this.invalid = false;
if (this.value === false || this.value === "") {
this.invalid = this.required;
} else if (this.validation_regex) {
this.invalid = !this.validation_regex.test(this.value);
}
}
});
@ -652,15 +762,29 @@ openerp.base.form.FieldBoolean = openerp.base.form.Field.extend({
this._super.apply(this, arguments);
this.$element.find('input')[0].checked = value;
},
set_value_from_ui: function() {
this.value = this.$element.find('input').is(':checked');
},
update_dom: function() {
this._super.apply(this, arguments);
this.$element.find('textarea').attr('disabled', this.readonly);
this.$element.find('input').attr('disabled', this.readonly);
},
on_ui_change: function() {
this._super.apply(this, arguments);
this.value = this.$element.find('input').is(':checked');
validate: function() {
this.invalid = this.required && !this.value;
this.view.on_form_changed(this);
}
});
openerp.base.form.FieldProgressBar = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldProgressBar";
},
start: function() {
this._super.apply(this, arguments);
this.$element.find('div').progressbar({
value: this.value,
disabled: this.readonly
});
}
});
@ -685,15 +809,15 @@ openerp.base.form.FieldSelection = openerp.base.form.Field.extend({
this.$element.find('select')[0].selectedIndex = 0;
}
},
set_value_from_ui: function() {
this.value = this.$element.find('select').val();
},
update_dom: function() {
this._super.apply(this, arguments);
this.$element.find('select').attr('disabled', this.readonly);
},
on_ui_change: function() {
this._super.apply(this, arguments);
this.value = this.$element.find('select').val();
this.invalid = this.required && this.value == "";
this.view.on_form_changed(this);
validate: function() {
this.invalid = this.required && this.value === "";
}
});
@ -720,7 +844,7 @@ openerp.base.form.FieldOne2ManyDatasSet = openerp.base.DataSetStatic.extend({
this._super(id, data, callback);
},
unlink: function() {
this.notification['default']('Unlinking o2m ' + this.ids);
this.notification.notify('Unlinking o2m ' + this.ids);
}
});
@ -744,12 +868,14 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
this.viewmanager = new openerp.base.form.FieldOne2ManyViewManager(this.view.session, this.element_id, this.dataset, views);
this.viewmanager.start();
},
set_value_CASSEEEEEEEEEEEEEEEEE: function(value) {
set_value: function(value) {
this.value = value;
this.log("o2m.set_value",value);
this.viewmanager.dataset.ids = value;
this.viewmanager.dataset.ids.count = value.length;
this.viewmanager.views.list.controller.do_update();
if (value != false) {
this.log("o2m.set_value",value);
this.viewmanager.dataset.ids = value;
this.viewmanager.dataset.count = value.length;
this.viewmanager.views.list.controller.do_update();
}
},
get_value: function(value) {
return this.operations;
@ -790,6 +916,7 @@ openerp.base.form.widgets = new openerp.base.Registry({
'email' : 'openerp.base.form.FieldEmail',
'url' : 'openerp.base.form.FieldUrl',
'text' : 'openerp.base.form.FieldText',
'text_wiki' : 'openerp.base.form.FieldText',
'date' : 'openerp.base.form.FieldDate',
'datetime' : 'openerp.base.form.FieldDatetime',
'selection' : 'openerp.base.form.FieldSelection',
@ -801,7 +928,7 @@ openerp.base.form.widgets = new openerp.base.Registry({
'boolean' : 'openerp.base.form.FieldBoolean',
'float' : 'openerp.base.form.FieldFloat',
'integer': 'openerp.base.form.FieldFloat',
'progressbar': 'openerp.base.form.FieldFloat',
'progressbar': 'openerp.base.form.FieldProgressBar',
'float_time': 'openerp.base.form.FieldFloat'
});

View File

@ -245,8 +245,8 @@ openerp.base.ListView = openerp.base.Controller.extend(
* The default implementation is to switch to a new record on the form view
*/
do_add_record: function () {
this.notification['default']('Add', "New record");
// this.switch_to_record(null);
this.notification.notify('Add', "New record");
this.switch_to_record(null);
},
/**
* Handles deletion of all selected lines

View File

@ -215,7 +215,7 @@ openerp.base.SearchView = openerp.base.Controller.extend({
* @param {Array} errors a never-empty array of error objects
*/
on_invalid: function (errors) {
this.notification['default']("Invalid Search", "triggered from search view");
this.notification.notify("Invalid Search", "triggered from search view");
},
do_clear: function (e) {
if (e && e.preventDefault) { e.preventDefault(); }

View File

@ -229,10 +229,10 @@ openerp.base.Sidebar = openerp.base.BaseWidget.extend({
set_toolbar: function(toolbar) {
this.sections = [];
var self = this;
_.each(["print", "action", "relate"], function(type) {
if (toolbar[type].length == 0)
_.each([["print", "Reports"], ["action", "Actions"], ["relate", "Links"]], function(type) {
if (toolbar[type[0]].length == 0)
return;
var section = {elements:toolbar[type]};
var section = {elements:toolbar[type[0]], label:type[1]};
self.sections.push(section);
});
this.refresh();
@ -240,6 +240,11 @@ openerp.base.Sidebar = openerp.base.BaseWidget.extend({
refresh: function() {
this.$element.html(QWeb.render("ViewManager.sidebar.internal", _.extend({_:_}, this)));
var self = this;
this.$element.find(".toggle-sidebar").click(function(e) {
self.$element.toggleClass('open-sidebar closed-sidebar');
e.stopPropagation();
e.preventDefault();
});
this.$element.find("a").click(function(e) {
var $this = jQuery(this);
var i = $this.attr("data-i");
@ -269,8 +274,9 @@ openerp.base.ExternalActionManager = openerp.base.Controller.extend({
viewmanager.start();
} else if (action.target == "current") {
this.rpc("/base/session/save_session_action", {the_action:action}, function(key) {
var url = window.location.href;
//window.open();
var url = window.location.protocol + "//" + window.location.host +
window.location.pathname + "?" + jQuery.param({s_action:""+key});
window.open(url);
});
}
}

View File

@ -40,8 +40,8 @@
</tr>
<tr>
<td colspan="2">
<div id="oe_footer" class="footer">
Powered by OpenERP.
<div id="oe_footer" class="oe_footer">
<p class="oe_footer_powered">Powered by <a href="http://www.openerp.com">openerp.com</a>.</p>
</div>
</td>
</tr>
@ -60,7 +60,8 @@
</t>
<t t-name="Header">
<a href="/" class="company_logo_link">
<img src="/base/static/src/img/logo.png" border="0" class="company_logo"/>
<img t-att-src="typeof kitten == 'undefined' ? '/base/static/src/img/logo.png' :
'http://placekitten.com/180/46'" border="0" class="company_logo"/>
</a>
<h1 class="header_title" t-if="session.session_is_valid()">
<span class="company">$company</span> - (<span class="database">$database</span>)<br/>
@ -232,7 +233,7 @@
</tr>
<t t-name="FormView">
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
<div class="oe_form_header">
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
<div class="oe_form_buttons">
<!--<button type="button" class="oe_form_button_save">Save</button>-->
<button type="button" class="oe_form_button_save_edit">Save &amp; Edit</button>
@ -292,11 +293,13 @@
</div>
</t>
<t t-name="WidgetLabel">
<label t-att-for="widget.element_id + '_field'" t-att-title="widget.help" style="display: block; text-align: right;"
<label t-att-for="widget.element_id + '_field'"
t-att-class="'oe_form_label' + (widget.help ? '_help' : '')"
t-att-title="widget.help"
t-att-ondblclick="'console.log(\'' + widget.element_id + '\', openerp.screen.' + widget.element_id + ')'">
<t t-esc="widget.string"/>
<span t-if="widget.help">?</span>
:
<t t-if="widget.string">:</t>
</label>
</t>
<t t-name="FieldChar">
@ -366,6 +369,9 @@
t-att-id="widget.element_id + '_field'"
t-att-class="'field_' + widget.type"/>
</t>
<t t-name="FieldProgressBar">
<div t-opentag="true"></div>
</t>
<t t-name="WidgetButton">
<button type="button"
t-att-id="widget.element_id + '_button'"
@ -528,27 +534,33 @@
<input t-att-id="element_id"/>
</t>
<t t-name="ViewManager.sidebar">
<div t-att-id="element_id" class="sidebar-main-div">
<div t-att-id="element_id" class="sidebar-main-div open-sidebar">
</div>
</t>
<t t-name="ViewManager.sidebar.internal">
<t t-if="sections.length &gt; 0 &amp;&amp; _.detect(sections, function(x) {return x.elements.length &gt; 0;}) != undefined">
<div t-att-id="element_id" class="sidebar-sub-div">
<t t-set="i" t-value="0"/>
<t t-foreach="sections" t-as="section">
<t t-if="section.elements.length &gt; 0">
<ul>
<t t-set="j" t-value="0"/>
<t t-foreach="section.elements" t-as="element">
<li><a t-att-data-i="i" t-att-data-j="j" href="#"><t t-esc="element.name"/></a></li>
<t t-set="j" t-value="j+1"/>
</t>
</ul>
</t>
<t t-set="i" t-value="i+1"/>
</t>
</div>
<t t-set="the_condition" t-value="sections.length &gt; 0 &amp;&amp; _.detect(sections, function(x)
{return x.elements.length &gt; 0;}) != undefined"/>
<t t-if="the_condition">
<a class="toggle-sidebar"></a>
<div t-att-id="element_id" class="sidebar-sub-div">
<div class="sidebar-displaying-div">
<t t-set="i" t-value="0"/>
<t t-foreach="sections" t-as="section">
<t t-if="section.elements.length &gt; 0">
<h2><t t-esc="section.label"/></h2>
<ul>
<t t-set="j" t-value="0"/>
<t t-foreach="section.elements" t-as="element">
<li><a t-att-data-i="i" t-att-data-j="j" href="#"><t t-esc="element.name"/></a></li>
<t t-set="j" t-value="j+1"/>
</t>
</ul>
</t>
<t t-set="i" t-value="i+1"/>
</t>
</div>
</div>
</t>
</t>
<t t-name="DialogWarning">