// parseFloat() but now locale aware and trying to be locale agnostic // // put in closure to cache intel which you don't want to calc each time // you convert a string --> float function StrToFloat() { var decimal_point = (1.1).toLocaleString().substr(1,1); var K_separator = (5000).toLocaleString().substr(1,1); if (K_separator === '0') K_separator = (decimal_point === '.' ? ',' : '.'); return function(str) { switch (typeof(str)) { case 'float': case 'integer': return str; default: str = '' + str; // force str to be string type str = str.match(/[0-9.,eE-]+/); if (str) str = str[0]; else return Number.NaN; // VERY illegal number format var kp = str.indexOf(','); var dp = str.indexOf('.'); var kpl = str.lastIndexOf(','); var dpl = str.lastIndexOf('.'); // can we be 'locale agnostic'? We can if both markers are in the input: if (kp > 0 && dp > 0) { if (kp < dp) { // e.g.: 1,000.00 if (kpl > dpl || dpl > dp) return Number.NaN; // VERY illegal number format str = str.replace(/,/g, ''); } else { // e.g.: 1.000,00 if (kpl < dpl || kpl > kp) return Number.NaN; // VERY illegal number format str = str.replace(/\./g, '').replace(',', '.'); } } else { // only one of 'em in there: must we use the detected 'current' locale // or can we 'heuristically determine' what's right here? // We can do the latter if we have either: // - only up to 2 digits following the only separator // - more than 3 digits following the only separator // - one separator only and the number starts with it, e.g. '.45' // // When we have only 3 digits following the last and only sep, we assume the separator // to be a 'thousands marker'. // We COULD fall back to the current locale, but than the ambiguous items receive // different treatment on a possibly incorrect locale setting (e.g. my machines are all // US/metric configured while I live in the Netherlands, but I /despise/ Dutch MS Excel, // for example. Riding the 'locale aware' ticket would definitely screw up my [ambiguous] // numbers. I believe it's better to be consistently wrong than semi-randomly correct. // // examples: 1.000 : 5,00 : 2,999.95 : 2,998 : 7.50 : 0,1791634 : 0.1791634 : .45 : ,32 if (dp >= 0 && kp < 0) { // .45, .... if (dp !== 0 && (dpl > dp || str.substr(dp + 1).match(/^[0-9]{3}\b/))) str = str.replace(/\./g, ''); } else if (kp >= 0 && dp < 0) { // ,32; .... if (kp !== 0 && (kpl > kp || str.substr(kp + 1).match(/^[0-9]{3}\b/))) str = str.replace(/,/g, ''); else str = str.replace(',', '.'); } else if (kp < 0 && dp < 0) { // integer value } else { // VERY illegal format, such as '.456,678' return Number.NaN; } } // now str has parseFloat() compliant format with US decimal point // only (iff it has a decimal fraction at all). return parseFloat(str); } }; } $$('.chooseout a').addEvent('click', function(e) { e.stop(); var cvt = StrToFloat(); console.log('examples: 1.000 : ', cvt('1.000')); console.log('examples: 1.000.000 : ', cvt('1.000.000')); console.log('examples (India/US): 1.00.000 : ', cvt('1.00.000')); console.log('examples: 5,00 : ', cvt('5,00')); console.log('examples: 2,999.95 : ', cvt('2,999.95')); console.log('examples: 2,999.995 : ', cvt('2,999.995')); console.log('examples: 2.999,95 : ', cvt('2.999,95')); console.log('examples: 2.999,995 : ', cvt('2.999,995')); console.log('examples: 2,998 : ', cvt('2,998')); console.log('examples: 2,999,998 : ', cvt('2,999,998')); console.log('examples (India): 2,99,998 : ', cvt('2,99,998')); console.log('examples: 7.50 : ', cvt('7.50')); console.log('examples: 0,1791634 : ', cvt('0,1791634')); console.log('examples: 0.1791634 : ', cvt('0.1791634')); console.log('examples: .45 : ', cvt('.45')); console.log('examples: ,32 : ', cvt(',32')); console.log('examples: .450 : ', cvt('.450')); console.log('examples: ,320 : ', cvt(',320')); console.log('examples FLOAT: 3.1415 : ', cvt(3.1415)); console.log('examples INT: 1234 : ', cvt(1234)); console.log('examples: 1 EUR : ', cvt('1 EUR')); console.log('examples BAD: bla : ', cvt('bla')); console.log('examples BAD: .456,678 : ', cvt('.456,678')); console.log('examples BAD: ,456.678 : ', cvt(',456.678')); console.log('examples BAD: .123.456,678 : ', cvt('.123.456,678')); console.log('examples BAD: ,123,456.678 : ', cvt(',123,456.678')); console.log('examples BAD: .456,678.456 : ', cvt('.456,678.456')); console.log('examples BAD: ,456.678,456 : ', cvt(',456.678,456')); console.log('examples BAD: 1.456,678.456 : ', cvt('1.456,678.456')); console.log('examples BAD: 1,456.678,456 : ', cvt('1,456.678,456')); var preis_str = $('getContent').getElement('.article_price b').get('text'); // BTW: NEVER do a toInt() as you'll lose the fractional part in the price. var preis = cvt(preis_str); var spreis_set = $$(".gespreis"); var summe = spreis_set[0].get('text'); summe = cvt(summe); summe += preis; console.log('summe: ', summe); spreis_set.each(function(el) { el.set('text', summe.toFixed(2)); }); });