2 openerp.web.formats = function(instance) {
3 var _t = instance.web._t;
6 * Intersperses ``separator`` in ``str`` at the positions indicated by
9 * ``indices`` is an array of relative offsets (from the previous insertion
10 * position, starting from the end of the string) at which to insert
13 * There are two special values:
16 * indicates the insertion should end now
18 * indicates that the previous section pattern should be repeated (until all
19 * of ``str`` is consumed)
22 * @param {Array<Number>} indices
23 * @param {String} separator
26 instance.web.intersperse = function (str, indices, separator) {
27 separator = separator || '';
28 var result = [], last = str.length;
30 for(var i=0; i<indices.length; ++i) {
31 var section = indices[i];
32 if (section === -1 || last <= 0) {
33 // Done with string, or -1 (stops formatting string)
35 } else if(section === 0 && i === 0) {
36 // repeats previous section, which there is none => stop
38 } else if (section === 0) {
39 // repeat previous section forever
40 //noinspection AssignmentToForLoopParameterJS
41 section = indices[--i];
43 result.push(str.substring(last-section, last));
47 var s = str.substring(0, last);
48 if (s) { result.push(s); }
49 return result.reverse().join(separator);
52 * Insert "thousands" separators in the provided number (which is actually
58 instance.web.insert_thousand_seps = function (num) {
59 var negative = num[0] === '-';
60 num = (negative ? num.slice(1) : num);
61 return (negative ? '-' : '') + instance.web.intersperse(
62 num, _t.database.parameters.grouping, _t.database.parameters.thousands_sep);
66 * removes literal (non-format) text from a date or time pattern, as datejs can
67 * not deal with literal text in format strings (whatever the format), whereas
68 * strftime allows for literal characters
70 * @param {String} value original format
72 instance.web.strip_raw_chars = function (value) {
73 var isletter = /[a-zA-Z]/, output = [];
74 for(var index=0; index < value.length; ++index) {
75 var character = value[index];
76 if(isletter.test(character) && (index === 0 || value[index-1] !== '%')) {
79 output.push(character);
81 return output.join('');
83 var normalize_format = function (format) {
84 return Date.normalizeFormat(instance.web.strip_raw_chars(format));
88 * Check with a scary heuristic if the value is a bin_size or not.
89 * If not, compute an approximate size out of the base64 encoded string.
91 * @param {String} value original format
93 instance.web.binary_to_binsize = function (value) {
95 return instance.web.human_size(0);
97 if (value.substr(0, 10).indexOf(' ') == -1) {
98 // Computing approximate size out of base64 encoded string
99 // http://en.wikipedia.org/wiki/Base64#MIME
100 return instance.web.human_size(value.length / 1.37);
108 * Returns a human readable size
110 * @param {Number} numner of bytes
112 instance.web.human_size = function(size) {
113 var units = _t("Bytes,Kb,Mb,Gb,Tb,Pb,Eb,Zb,Yb").split(',');
115 while (size >= 1024) {
119 return size.toFixed(2) + ' ' + units[i];
123 * Formats a single atomic value based on a field descriptor
125 * @param {Object} value read from OpenERP
126 * @param {Object} descriptor union of orm field and view field
127 * @param {Object} [descriptor.widget] widget to use to display the value
128 * @param {Object} descriptor.type fallback if no widget is provided, or if the provided widget is unknown
129 * @param {Object} [descriptor.digits] used for the formatting of floats
130 * @param {String} [value_if_empty=''] returned if the ``value`` argument is considered empty
132 instance.web.format_value = function (value, descriptor, value_if_empty) {
133 // If NaN value, display as with a `false` (empty cell)
134 if (typeof value === 'number' && isNaN(value)) {
137 //noinspection FallthroughInSwitchStatementJS
140 if (descriptor.type === 'char') {
143 console.warn('Field', descriptor, 'had an empty string as value, treating as false...');
147 return value_if_empty === undefined ? '' : value_if_empty;
149 var l10n = _t.database.parameters;
150 switch (descriptor.widget || descriptor.type || (descriptor.field && descriptor.field.type)) {
152 return value.toString();
154 return instance.web.insert_thousand_seps(
155 _.str.sprintf('%d', value));
157 var digits = descriptor.digits ? descriptor.digits : [69,2];
158 digits = typeof digits === "string" ? py.eval(digits) : digits;
159 var precision = digits[1];
160 var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
161 formatted[0] = instance.web.insert_thousand_seps(formatted[0]);
162 return formatted.join(l10n.decimal_point);
164 var pattern = '%02d:%02d';
166 value = Math.abs(value);
167 pattern = '-' + pattern;
169 var hour = Math.floor(value);
170 var min = Math.round((value % 1) * 60);
175 return _.str.sprintf(pattern, hour, min);
177 // name_get value format
178 return value[1] ? value[1].split("\n")[0] : value[1];
181 if (typeof value === 'string') {
184 return _.str.sprintf(_t("(%d records)"), value.length);
186 if (typeof(value) == "string")
187 value = instance.web.auto_str_to_date(value);
189 return value.toString(normalize_format(l10n.date_format)
190 + ' ' + normalize_format(l10n.time_format));
192 if (typeof(value) == "string")
193 value = instance.web.auto_str_to_date(value);
194 return value.toString(normalize_format(l10n.date_format));
196 if (typeof(value) == "string")
197 value = instance.web.auto_str_to_date(value);
198 return value.toString(normalize_format(l10n.time_format));
199 case 'selection': case 'statusbar':
200 // Each choice is [value, label]
201 if(_.isArray(value)) {
204 var result = _(descriptor.selection).detect(function (choice) {
205 return choice[0] === value;
207 if (result) { return result[1]; }
214 instance.web.parse_value = function (value, descriptor, value_if_empty) {
215 var date_pattern = normalize_format(_t.database.parameters.date_format),
216 time_pattern = normalize_format(_t.database.parameters.time_format);
220 return value_if_empty === undefined ? false : value_if_empty;
222 switch (descriptor.widget || descriptor.type || (descriptor.field && descriptor.field.type)) {
227 value = value.replace(instance.web._t.database.parameters.thousands_sep, "");
228 } while(tmp !== value);
231 throw new Error(_.str.sprintf(_t("'%s' is not a correct integer"), value));
234 var tmp = Number(value);
241 tmp2 = tmp.replace(instance.web._t.database.parameters.thousands_sep, "");
242 } while(tmp !== tmp2);
243 var reformatted_value = tmp.replace(instance.web._t.database.parameters.decimal_point, ".");
244 var parsed = Number(reformatted_value);
246 throw new Error(_.str.sprintf(_t("'%s' is not a correct float"), value));
250 if (value[0] === '-') {
251 value = value.slice(1);
254 var float_time_pair = value.split(":");
255 if (float_time_pair.length != 2)
256 return factor * instance.web.parse_value(value, {type: "float"});
257 var hours = instance.web.parse_value(float_time_pair[0], {type: "integer"});
258 var minutes = instance.web.parse_value(float_time_pair[1], {type: "integer"});
259 return factor * (hours + (minutes / 60));
261 return instance.web.parse_value(value, {type: "float"});
263 var datetime = Date.parseExact(
264 value, (date_pattern + ' ' + time_pattern));
265 if (datetime !== null)
266 return instance.web.datetime_to_str(datetime);
267 datetime = Date.parse(value);
268 if (datetime !== null)
269 return instance.web.datetime_to_str(datetime);
270 throw new Error(_.str.sprintf(_t("'%s' is not a correct datetime"), value));
272 var date = Date.parseExact(value, date_pattern);
274 return instance.web.date_to_str(date);
275 date = Date.parse(value);
277 return instance.web.date_to_str(date);
278 throw new Error(_.str.sprintf(_t("'%s' is not a correct date"), value));
280 var time = Date.parseExact(value, time_pattern);
282 return instance.web.time_to_str(time);
283 time = Date.parse(value);
285 return instance.web.time_to_str(time);
286 throw new Error(_.str.sprintf(_t("'%s' is not a correct time"), value));
291 instance.web.auto_str_to_date = function(value, type) {
293 return instance.web.str_to_datetime(value);
296 return instance.web.str_to_date(value);
299 return instance.web.str_to_time(value);
301 throw new Error(_.str.sprintf(_t("'%s' is not a correct date, datetime nor time"), value));
304 instance.web.auto_date_to_str = function(value, type) {
307 return instance.web.datetime_to_str(value);
309 return instance.web.date_to_str(value);
311 return instance.web.time_to_str(value);
313 throw new Error(_.str.sprintf(_t("'%s' is not convertible to date, datetime nor time"), type));