Sylvain LE GAL
11 years ago
4 changed files with 200 additions and 0 deletions
-
4web_field_float_compute/__init__.py
-
64web_field_float_compute/__openerp__.py
-
BINweb_field_float_compute/static/src/img/icon.png
-
132web_field_float_compute/static/src/js/models.js
@ -0,0 +1,4 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# See __openerp__.py file for Copyright and Licence Informations. |
||||
|
################################################################################ |
@ -0,0 +1,64 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# See Copyright and Licence Informations undermentioned. |
||||
|
################################################################################ |
||||
|
{ |
||||
|
'name': 'Mathematic Formulas in Float fields', |
||||
|
'version': '1.0', |
||||
|
'category': 'web', |
||||
|
'description': """ |
||||
|
Allow to write simple mathematic formules in Integer / Float fields |
||||
|
=================================================================== |
||||
|
|
||||
|
Functionnalities : |
||||
|
------------------ |
||||
|
* Possibility to tip a text like "=45 + 4/3 - 5 * (2 +1)" ; |
||||
|
* if the formula is correct, The result will be computed and displayed ; |
||||
|
* if the formula is not correct, the initial text is displayed ; |
||||
|
|
||||
|
Documentations : |
||||
|
------------------ |
||||
|
* Video : http://www.youtube.com/watch?v=jQGdD34WYrA&hd=1 |
||||
|
|
||||
|
Technical informations : |
||||
|
------------------------ |
||||
|
* Overloads "instance.web.form.FieldFloat" ; (so works for fields.integer & fields.float) ; |
||||
|
* To compute, the module simply use the eval() javascript function ; |
||||
|
* Rounding computation is not done by this module (The module has the same behaviour if the user tips "=1/3" or if he tips "0.33[...]") ; |
||||
|
* avoid code injonction by regexpr test : "=alert('security')" is not valid ; |
||||
|
|
||||
|
Limits : |
||||
|
-------- |
||||
|
* Only supports the four operators : "+" "-" "*" "/" and parenthesis ; |
||||
|
|
||||
|
Copyright and Licence : |
||||
|
----------------------- |
||||
|
* 2013, Groupement Régional Alimentaire de Proximité (http://www.grap.coop/) |
||||
|
* Licence : AGPL-3 (http://www.gnu.org/licenses/) |
||||
|
|
||||
|
Contacts : |
||||
|
---------- |
||||
|
* Sylvain LE GAL (https://twitter.com/legalsylvain); |
||||
|
* <informatique@grap.coop> for any help or question about this module. |
||||
|
""", |
||||
|
'author': 'GRAP', |
||||
|
'website': 'http://www.grap.coop', |
||||
|
'license': 'AGPL-3', |
||||
|
'depends': [ |
||||
|
'web', |
||||
|
], |
||||
|
'init_xml': [], |
||||
|
'update_xml': [], |
||||
|
'demo_xml': [], |
||||
|
'js': [ |
||||
|
'static/src/js/models.js', |
||||
|
], |
||||
|
'css': [], |
||||
|
'qweb': [], |
||||
|
'images': [], |
||||
|
'post_load': '', |
||||
|
'application': False, |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'images': [], |
||||
|
} |
After Width: 128 | Height: 128 | Size: 3.2 KiB |
@ -0,0 +1,132 @@ |
|||||
|
/******************************************************************************* |
||||
|
See __openerp__.py file for Copyright and Licence Informations. |
||||
|
*******************************************************************************/ |
||||
|
|
||||
|
openerp.web_field_float_compute = function (instance) { |
||||
|
|
||||
|
instance.web.FormView = instance.web.FormView.extend({ |
||||
|
/*********************************************************************** |
||||
|
Overload section |
||||
|
***********************************************************************/ |
||||
|
|
||||
|
/** |
||||
|
* Overload : '_process_save' function |
||||
|
1: to force computation of formula if the user realize a keydown directly after the formula input in a tree view ; |
||||
|
2: to clean up the '_formula_text' value in all case to avoid bugs in tree view ; |
||||
|
*/ |
||||
|
_process_save: function(save_obj) { |
||||
|
for (var f in this.fields) { |
||||
|
if (!this.fields.hasOwnProperty(f)) { continue; } |
||||
|
f = this.fields[f]; |
||||
|
if (f.hasOwnProperty('_formula_text')){ |
||||
|
currentval = f.$('input').attr('value') |
||||
|
if (typeof currentval != 'undefined'){ |
||||
|
formula = f._get_valid_expression(currentval); |
||||
|
if (formula){ |
||||
|
f._compute_result(); |
||||
|
} |
||||
|
} |
||||
|
f._clean_formula_text(); |
||||
|
} |
||||
|
} |
||||
|
return this._super(save_obj); |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
instance.web.form.FieldFloat = instance.web.form.FieldFloat.extend({ |
||||
|
/*********************************************************************** |
||||
|
Overload section |
||||
|
***********************************************************************/ |
||||
|
|
||||
|
/** |
||||
|
* Overload : 'start' function to catch 'blur' and 'focus' events. |
||||
|
*/ |
||||
|
start: function() { |
||||
|
this.on("blurred", this, this._compute_result); |
||||
|
this.on("focused", this, this._display_formula); |
||||
|
return this._super(); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Overload : 'initialize_content' function to clean '_formula_text' value. |
||||
|
*/ |
||||
|
initialize_content: function() { |
||||
|
this._clean_formula_text(); |
||||
|
return this._super(); |
||||
|
}, |
||||
|
|
||||
|
/*********************************************************************** |
||||
|
Custom section |
||||
|
***********************************************************************/ |
||||
|
|
||||
|
/** |
||||
|
* keep in memory the formula to allow user to edit it again. |
||||
|
The formula has to be keeped in memory until a 'save' action. |
||||
|
*/ |
||||
|
_formula_text: '', |
||||
|
|
||||
|
/** |
||||
|
* Clean '_formula_text' value. |
||||
|
*/ |
||||
|
_clean_formula_text: function() { |
||||
|
this._formula_text = ''; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Return a valid formula from a val, if possible. |
||||
|
Otherwise, return false. |
||||
|
*/ |
||||
|
_get_valid_expression: function(val) { |
||||
|
// Trim the value
|
||||
|
currenttxt = val.toString().replace(/^\s+|\s+$/g, ''); |
||||
|
// Test if the value is a formula
|
||||
|
if (currenttxt[0] == '=') { |
||||
|
// allowed chars : [0-9] .,+-/*() and spaces
|
||||
|
myreg = RegExp('[0-9]|\\s|\\.|,|\\(|\\)|\\+|\\-|\\*|\\/','g') |
||||
|
// Test to avoid code injonction in eval function.
|
||||
|
if (currenttxt.substring(1).replace(myreg, '') == ''){ |
||||
|
try { |
||||
|
// Try to compute
|
||||
|
formula = currenttxt.substring(1).replace(/,/g,'.'); |
||||
|
var floatval = eval(formula); |
||||
|
}catch (e) {} |
||||
|
if (typeof (floatval) != 'undefined'){ |
||||
|
return formula; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* test if the content of the field is a valid formula, |
||||
|
* compute the result, and replace the current value by the final result. |
||||
|
*/ |
||||
|
_compute_result: function() { |
||||
|
var formula |
||||
|
// Erase old formula
|
||||
|
this._formula_text = ''; |
||||
|
|
||||
|
formula = this._get_valid_expression(this.$el.find('input').attr('value')); |
||||
|
if (formula){ |
||||
|
// Store new formula
|
||||
|
this._formula_text = "=" + formula; |
||||
|
// put the result in the field
|
||||
|
this.set_value(eval(formula)); |
||||
|
// Force rendering anyway to avoid format loss if no change
|
||||
|
this.render_value(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Display the stored formula in the field, to allow modification. |
||||
|
*/ |
||||
|
_display_formula: function() { |
||||
|
if (this._formula_text != ''){ |
||||
|
this.$el.find('input').val(this._formula_text); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
}; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue