2 openerp.web.formats = function(openerp) {
3 var _t = openerp.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 openerp.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 openerp.web.insert_thousand_seps = function (num) {
59 var negative = num[0] === '-';
60 num = (negative ? num.slice(1) : num);
61 return (negative ? '-' : '') + openerp.web.intersperse(
62 num, _t.database.parameters.grouping, _t.database.parameters.thousands_sep);
65 * Formats a single atomic value based on a field descriptor
67 * @param {Object} value read from OpenERP
68 * @param {Object} descriptor union of orm field and view field
69 * @param {Object} [descriptor.widget] widget to use to display the value
70 * @param {Object} descriptor.type fallback if no widget is provided, or if the provided widget is unknown
71 * @param {Object} [descriptor.digits] used for the formatting of floats
72 * @param {String} [value_if_empty=''] returned if the ``value`` argument is considered empty
74 openerp.web.format_value = function (value, descriptor, value_if_empty) {
75 // If NaN value, display as with a `false` (empty cell)
76 if (typeof value === 'number' && isNaN(value)) {
79 //noinspection FallthroughInSwitchStatementJS
82 if (descriptor.type === 'char') {
85 console.warn('Field', descriptor, 'had an empty string as value, treating as false...');
89 return value_if_empty === undefined ? '' : value_if_empty;
91 var l10n = _t.database.parameters;
92 switch (descriptor.widget || descriptor.type) {
94 return openerp.web.insert_thousand_seps(
95 _.str.sprintf('%d', value));
97 var precision = descriptor.digits ? descriptor.digits[1] : 2;
98 var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
99 formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
100 return formatted.join(l10n.decimal_point);
102 return _.str.sprintf("%02d:%02d",
104 Math.round((value % 1) * 60));
106 return _.str.sprintf(
107 '<progress value="%.2f" max="100.0">%.2f%%</progress>',
110 // name_get value format
113 if (typeof(value) == "string")
114 value = openerp.web.auto_str_to_date(value);
116 return value.format(l10n.date_format
117 + ' ' + l10n.time_format);
119 if (typeof(value) == "string")
120 value = openerp.web.auto_str_to_date(value);
121 return value.format(l10n.date_format);
123 if (typeof(value) == "string")
124 value = openerp.web.auto_str_to_date(value);
125 return value.format(l10n.time_format);
127 // Each choice is [value, label]
128 var result = _(descriptor.selection).detect(function (choice) {
129 return choice[0] === value;
131 if (result) { return result[1]; }
138 openerp.web.parse_value = function (value, descriptor, value_if_empty) {
139 var date_pattern = Date.normalizeFormat(_t.database.parameters.date_format),
140 time_pattern = Date.normalizeFormat(_t.database.parameters.time_format);
144 return value_if_empty === undefined ? false : value_if_empty;
146 switch (descriptor.widget || descriptor.type) {
151 value = value.replace(openerp.web._t.database.parameters.thousands_sep, "");
152 } while(tmp !== value);
155 throw new Error(value + " is not a correct integer");
158 var tmp = Number(value);
165 tmp2 = tmp.replace(openerp.web._t.database.parameters.thousands_sep, "");
166 } while(tmp !== tmp2);
167 var reformatted_value = tmp.replace(openerp.web._t.database.parameters.decimal_point, ".");
168 var parsed = Number(reformatted_value);
170 throw new Error(value + " is not a correct float");
173 var float_time_pair = value.split(":");
174 if (float_time_pair.length != 2)
175 return openerp.web.parse_value(value, {type: "float"});
176 var hours = openerp.web.parse_value(float_time_pair[0], {type: "integer"});
177 var minutes = openerp.web.parse_value(float_time_pair[1], {type: "integer"});
178 return hours + (minutes / 60);
180 return openerp.web.parse_value(value, {type: "float"});
182 var datetime = Date.parseExact(
183 value, (date_pattern + ' ' + time_pattern));
184 if (datetime !== null)
185 return openerp.web.datetime_to_str(datetime);
186 datetime = Date.parse(value);
187 if (datetime !== null)
188 return openerp.web.datetime_to_str(datetime);
189 throw new Error(value + " is not a valid datetime");
191 var date = Date.parseExact(value, date_pattern);
193 return openerp.web.date_to_str(date);
194 date = Date.parse(value);
196 return openerp.web.date_to_str(date);
197 throw new Error(value + " is not a valid date");
199 var time = Date.parseExact(value, time_pattern);
201 return openerp.web.time_to_str(time);
202 time = Date.parse(value);
204 return openerp.web.time_to_str(time);
205 throw new Error(value + " is not a valid time");
210 openerp.web.auto_str_to_date = function(value, type) {
212 return openerp.web.str_to_datetime(value);
215 return openerp.web.str_to_date(value);
218 return openerp.web.str_to_time(value);
220 throw new Error("'" + value + "' is not a valid date, datetime nor time");
223 openerp.web.auto_date_to_str = function(value, type) {
226 return openerp.web.datetime_to_str(value);
228 return openerp.web.date_to_str(value);
230 return openerp.web.time_to_str(value);
232 throw new Error(type + " is not convertible to date, datetime nor time");
237 * Formats a provided cell based on its field type
239 * @param {Object} row_data record whose values should be displayed in the cell
240 * @param {Object} column column descriptor
241 * @param {"button"|"field"} column.tag base control type
242 * @param {String} column.type widget type for a field control
243 * @param {String} [column.string] button label
244 * @param {String} [column.icon] button icon
245 * @param {String} [value_if_empty=''] what to display if the field's value is ``false``
246 * @param {Boolean} [process_modifiers=true] should the modifiers be computed ?
248 openerp.web.format_cell = function (row_data, column, value_if_empty, process_modifiers) {
250 if (process_modifiers !== false) {
251 attrs = column.modifiers_for(row_data);
253 if (attrs.invisible) { return ''; }
254 if (column.tag === 'button') {
256 '<button type="button" title="', column.string || '', '">',
257 '<img src="/web/static/src/img/icons/', column.icon, '.png"',
258 ' alt="', column.string || '', '"/>',
263 if (!row_data[column.id]) {
264 return value_if_empty === undefined ? '' : value_if_empty;
266 return openerp.web.format_value(
267 row_data[column.id].value, column, value_if_empty);