Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBeat Schwarzentrub2016-11-14 16:06:27 +0000
committerBeat Schwarzentrub2016-11-14 16:06:27 +0000
commit475c19a7e38fa9363dd64fabfa1968444832bea9 (patch)
tree6e856149b6430e02b6826b8bc3a5eec03b6217df
parent814b75ea28dab352b7f0c84c8b7f91da3e6983d0 (diff)
downloadorg.eclipse.scout.rt-features/bschwarzent/decimalformat.tar.gz
org.eclipse.scout.rt-features/bschwarzent/decimalformat.tar.xz
org.eclipse.scout.rt-features/bschwarzent/decimalformat.zip
*** TMP *** Fix decimalformatfeatures/bschwarzent/decimalformat
-rw-r--r--org.eclipse.scout.rt.ui.html.test/src/test/js/scout/text/DecimalFormatSpec.js1
-rw-r--r--org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/numberfield/NumberField.js17
-rw-r--r--org.eclipse.scout.rt.ui.html/src/main/js/scout/text/DecimalFormat.js195
3 files changed, 152 insertions, 61 deletions
diff --git a/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/text/DecimalFormatSpec.js b/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/text/DecimalFormatSpec.js
index 70e0dc65f4..1535a46644 100644
--- a/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/text/DecimalFormatSpec.js
+++ b/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/text/DecimalFormatSpec.js
@@ -278,7 +278,6 @@ describe("DecimalFormat", function() {
expect(decimalFormat.format(-12345.6789)).toBe('M12~345!67');
decimalFormat.allAfter = 0;
- decimalFormat.pattern = '#,##0';
expect(decimalFormat.format(-1000.1234)).toBe('M1~000');
expect(decimalFormat.format(1000.1234)).toBe('1~001');
});
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/numberfield/NumberField.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/numberfield/NumberField.js
index a3b5ea13ac..5350660ffa 100644
--- a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/numberfield/NumberField.js
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/numberfield/NumberField.js
@@ -61,10 +61,10 @@ scout.NumberField.prototype.acceptInput = function(whileTyping) {
scout.NumberField.parent.prototype.acceptInput.call(this, whileTyping);
};
-scout.NumberField.prototype.parse = function() {
+scout.NumberField.prototype.parse = function(displayText) {
var number = null;
try {
- number = this.decimalFormat.parse(this.displayText);
+ number = this.decimalFormat.parse(scout.nvl(displayText, this.displayText));
} catch(e) {
// catch Error thrown when number isNaN
}
@@ -75,10 +75,7 @@ scout.NumberField.prototype._parse = function() {
var input = this.$field.val();
if (input) {
// Convert to JS number format (remove groupingChar, replace decimalSeparatorChar with '.')
- input = input
- .replace(new RegExp('[' + this.decimalFormat.groupingChar + ']', 'g'), '')
- .replace(new RegExp('[' + this.decimalFormat.decimalSeparatorChar + ']', 'g'), '.')
- .replace(/\s/g, '');
+ input = this.decimalFormat.normalizeString(input);
// if only math symbols are in the input string...
if (this.calc.isFormula(input)) {
@@ -94,3 +91,11 @@ scout.NumberField.prototype._parse = function() {
}
}
};
+
+scout.NumberField.prototype._parseValue = function(displayText) {
+ return this.parse(displayText);
+};
+
+scout.NumberField.prototype._formatValue = function(value) {
+ return this.decimalFormat.format(value, false);
+};
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/text/DecimalFormat.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout/text/DecimalFormat.js
index d685fcabf4..0d515a0812 100644
--- a/org.eclipse.scout.rt.ui.html/src/main/js/scout/text/DecimalFormat.js
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/text/DecimalFormat.js
@@ -20,10 +20,11 @@
*/
scout.DecimalFormat = function(locale, decimalFormatConfiguration) {
// format function will use these (defaults)
- this.positivePrefix = '';
- this.positiveSuffix = '';
- this.negativePrefix = locale.decimalFormatSymbols.minusSign;
- this.negativeSuffix = '';
+ this.positivePrefix;
+ this.positiveSuffix;
+ this.negativePrefix;
+ this.negativeSuffix;
+ this.minusSign = locale.decimalFormatSymbols.minusSign;
this.groupingChar = locale.decimalFormatSymbols.groupingSeparator;
this.groupLength = 0;
this.decimalSeparatorChar = locale.decimalFormatSymbols.decimalSeparator;
@@ -40,45 +41,67 @@ scout.DecimalFormat = function(locale, decimalFormatConfiguration) {
// Check if there are separate subpatterns for positive and negative numbers ("PositivePattern;NegativePattern")
var split = this.pattern.split(SYMBOLS.patternSeparator);
// Use the first subpattern as positive prefix/suffix
- var positivePrefixAndSuffix = findPrefixAndSuffix(split[0]);
- this.positivePrefix = positivePrefixAndSuffix.prefix;
- this.positiveSuffix = positivePrefixAndSuffix.suffix;
+ var positivePatternParts = scout.DecimalFormat.findPatternParts(split[0]);
+ this.positivePrefix = positivePatternParts.prefix;
+ this.positiveSuffix = positivePatternParts.suffix;
+ this.numberPattern = positivePatternParts.number;
if (split.length > 1) {
// Yes, there is a negative subpattern
- var negativePrefixAndSuffix = findPrefixAndSuffix(split[1]);
- this.negativePrefix = negativePrefixAndSuffix.prefix;
- this.negativeSuffix = negativePrefixAndSuffix.suffix;
- // from now on, only look at the positive subpattern
- this.pattern = split[0];
+ var negativePatternParts = scout.DecimalFormat.findPatternParts(split[1]);
+ this.negativePrefix = negativePatternParts.prefix;
+ this.negativeSuffix = negativePatternParts.suffix;
+ if (negativePatternParts.prefixMinusMask.indexOf(SYMBOLS.minusSign) !== -1) {
+ this.minusSignInNegativePrefix = true;
+ }
+ if (negativePatternParts.suffixMinusMask.indexOf(SYMBOLS.minusSign) !== -1) {
+ this.minusSignInNegativeSuffix = true;
+ }
+ // "number" part is ignored, positive and negative number pattern are the same
} else {
// No, there is no negative subpattern, so the positive prefix/suffix are used for both positive and negative numbers.
+ this.negativePrefix = this.positivePrefix;
+ this.negativeSuffix = this.positiveSuffix;
// Check if there is a minus sign in the prefix/suffix.
- if (this.positivePrefix.indexOf(SYMBOLS.minusSign) !== -1 || this.positiveSuffix.indexOf(SYMBOLS.minusSign) !== -1) {
- // Yes, there is a minus sign in the prefix/suffix. Use this a negativePrefix/Suffix and remove the minus sign from the posistivePrefix/Suffix.
- this.negativePrefix = this.positivePrefix.replace(SYMBOLS.minusSign, locale.decimalFormatSymbols.minusSign);
- this.negativeSuffix = this.positiveSuffix.replace(SYMBOLS.minusSign, locale.decimalFormatSymbols.minusSign);
- this.positivePrefix = this.positivePrefix.replace(SYMBOLS.minusSign, '');
- this.positiveSuffix = this.positiveSuffix.replace(SYMBOLS.minusSign, '');
- } else {
- // No, there is no minus sign in the prefix/suffix. Therefore, use the default negativePrefix/Suffix, but append the positivePrefix/Suffix
- this.negativePrefix = this.positivePrefix + this.negativePrefix;
- this.negativeSuffix = this.negativeSuffix + this.positiveSuffix;
+ var prefixMinusSignIndex = positivePatternParts.prefixMinusMask.indexOf(SYMBOLS.minusSign);
+ if (prefixMinusSignIndex !== -1) {
+ // Yes, there is a minus sign in the prefix. Use this a negativePrefix and remove the minus sign from the posistivePrefix.
+ while (prefixMinusSignIndex !== -1) {
+ this.positivePrefix = replaceCharAt(this.positivePrefix, prefixMinusSignIndex, '');
+ this.negativePrefix = replaceCharAt(this.negativePrefix, prefixMinusSignIndex, this.minusSign);
+ prefixMinusSignIndex = positivePatternParts.prefixMinusMask.indexOf(SYMBOLS.minusSign, prefixMinusSignIndex + 1);
+ }
+ this.minusSignInNegativePrefix = true;
+ }
+ var suffixMinusSignIndex = positivePatternParts.suffixMinusMask.indexOf(SYMBOLS.minusSign);
+ if (suffixMinusSignIndex !== -1) {
+ // Yes, there is a minus sign in the suffix. Use this a negativeSuffix and remove the minus sign from the posistiveSuffix.
+ while (suffixMinusSignIndex !== -1) {
+ this.positiveSuffix = replaceCharAt(this.positiveSuffix, suffixMinusSignIndex, '');
+ this.negativeSuffix = replaceCharAt(this.negativePrefix, suffixMinusSignIndex, this.minusSign);
+ suffixMinusSignIndex = positivePatternParts.suffixMinusMask.indexOf(SYMBOLS.minusSign, suffixMinusSignIndex + 1);
+ }
+ this.minusSignInNegativeSuffix = true;
+ }
+ if (!this.minusSignInNegativePrefix && !this.minusSignInNegativeSuffix) {
+ // No, there is no minus sign in the prefix/suffix. Therefore, automatically prepend the minus sign to the prefix.
+ this.negativePrefix = this.minusSign + this.positivePrefix;
+ this.minusSignInNegativePrefix = true;
}
}
// find group length
- var posDecimalSeparator = this.pattern.indexOf(SYMBOLS.decimalSeparator);
+ var posDecimalSeparator = this.numberPattern.indexOf(SYMBOLS.decimalSeparator);
if (posDecimalSeparator === -1) {
- posDecimalSeparator = this.pattern.length; // assume decimal separator at end
+ posDecimalSeparator = this.numberPattern.length; // assume decimal separator at end
}
- var posGroupingSeparator = this.pattern.lastIndexOf(SYMBOLS.groupingSeparator, posDecimalSeparator); // only search before decimal separator
+ var posGroupingSeparator = this.numberPattern.lastIndexOf(SYMBOLS.groupingSeparator, posDecimalSeparator); // only search before decimal separator
if (posGroupingSeparator > 0) {
this.groupLength = posDecimalSeparator - posGroupingSeparator - 1;
}
- this.pattern = this.pattern.replace(new RegExp('[' + SYMBOLS.groupingSeparator + ']', 'g'), '');
+ this.numberPattern = this.numberPattern.replace(new RegExp('[' + SYMBOLS.groupingSeparator + ']', 'g'), '');
// split on decimal point
- split = this.pattern.split(SYMBOLS.decimalSeparator);
+ split = this.numberPattern.split(SYMBOLS.decimalSeparator);
// find digits before and after decimal point
this.zeroBefore = scout.strings.count(split[0], SYMBOLS.zeroDigit);
@@ -87,29 +110,10 @@ scout.DecimalFormat = function(locale, decimalFormatConfiguration) {
this.allAfter = this.zeroAfter + scout.strings.count(split[1], SYMBOLS.digit);
}
- // Returns an object with the properties 'prefix' and 'suffix', which contain all characters
- // before or after any 'digit-like' character in the given pattern string.
- function findPrefixAndSuffix(pattern) {
- var result = {
- prefix: '',
- suffix: ''
- };
- // Find prefix (anything before the first 'digit-like' character)
- var digitLikeCharacters = SYMBOLS.digit + SYMBOLS.zeroDigit + SYMBOLS.decimalSeparator + SYMBOLS.groupingSeparator;
- var r = new RegExp('^(.*?)[' + digitLikeCharacters + '].*$');
- var matches = r.exec(pattern);
- if (matches !== null) {
- // Ignore single quotes (for special, quoted characters - e.g. Java quotes percentage sign like '%')
- result.prefix = matches[1].replace(new RegExp('\'([^\']+)\'', 'g'), '$1');
- }
- // Find suffix (anything before the first 'digit-like' character)
- r = new RegExp('^.*[' + digitLikeCharacters + '](.*?)$');
- matches = r.exec(pattern);
- if (matches !== null) {
- // Ignore single quotes (for special, quoted characters - e.g. Java quotes percentage sign like '%')
- result.suffix = matches[1].replace(new RegExp('\'([^\']+)\'', 'g'), '$1');
- }
- return result;
+ // ----- Helper functions -----
+
+ function replaceCharAt(s, pos, replacement) {
+ return s.substring(0, pos) + replacement + s.substring(pos + 1);
}
};
@@ -121,10 +125,7 @@ scout.DecimalFormat.prototype.parse = function(numberString) {
if (scout.strings.empty(numberString)) {
return null;
}
- var pureNumber = numberString
- .replace(new RegExp('[' + this.groupingChar + ']', 'g'), '')
- .replace(new RegExp('[' + this.decimalSeparatorChar + ']', 'g'), '.')
- .replace(/\s/g, '');
+ var pureNumber = this.normalizeString(numberString);
var number = Number(pureNumber);
if (isNaN(number)) {
throw new Error(numberString + ' is not a number (NaN)');
@@ -132,6 +133,27 @@ scout.DecimalFormat.prototype.parse = function(numberString) {
return number;
};
+scout.DecimalFormat.prototype.normalizeString = function(numberString) {
+ if (scout.strings.empty(numberString)) {
+ return '';
+ }
+ var negativePrefixRegEx = new RegExp('^' + scout.strings.quote(this.negativePrefix));
+ var negativeSuffixRegEx = new RegExp(scout.strings.quote(this.negativeSuffix) + '$');
+ var minus = '';
+ if ((this.minusSignInNegativePrefix && negativePrefixRegEx.test(numberString)) ||
+ (this.minusSignInNegativeSuffix && negativeSuffixRegEx.test(numberString))) {
+ minus = '-';
+ }
+ return minus + numberString
+ .replace(new RegExp('^' + scout.strings.quote(this.positivePrefix)), '')
+ .replace(new RegExp(scout.strings.quote(this.positiveSuffix) + '$'), '')
+ .replace(negativePrefixRegEx, '')
+ .replace(negativeSuffixRegEx, '')
+ .replace(new RegExp('[' + this.groupingChar + ']', 'g'), '')
+ .replace(new RegExp('[' + this.decimalSeparatorChar + ']', 'g'), '.')
+ .replace(/\s/g, '');
+};
+
scout.DecimalFormat.prototype.format = function(number, applyMultiplier) {
applyMultiplier = scout.nvl(applyMultiplier, true);
if (number === null || number === undefined) {
@@ -217,3 +239,68 @@ scout.DecimalFormat.ensure = function(locale, format) {
}
return new scout.DecimalFormat(locale, format);
};
+
+/**
+ * Returns an object with the properties 'prefix', 'number' and 'suffix'. Number contains
+ * the part of the pattern that consists of 'digit-like' characters. Prefix and suffix
+ * contain the literal part before and after the number part, respectively. Single quotes
+ * that can be used to escape characters are removed from the result.
+ */
+scout.DecimalFormat.findPatternParts = function(pattern) {
+ var result = {
+ prefix: '',
+ prefixMinusMask: '',
+ number: '',
+ suffix: '',
+ suffixMinusMask: ''
+ };
+ var SYMBOLS = scout.DecimalFormat.PATTERN_SYMBOLS;
+ // Pattern that matches digit-like characters
+ var r = new RegExp('[' + SYMBOLS.digit + SYMBOLS.zeroDigit + SYMBOLS.decimalSeparator + SYMBOLS.groupingSeparator + ']');
+ var escape = false;
+ var scope = 'PREFIX';
+ for (var i = 0; i < pattern.length; i++) {
+ var ch = pattern.charAt(i);
+ if (scope === 'PREFIX') {
+ // prefix
+ if (ch === '\'') { // toggle escape
+ if (escape && pattern.charAt(i - 1) === '\'') { // two consecutive ' are equal to one literal '
+ result.prefix += '\'';
+ result.prefixMinusMask += ' ';
+ }
+ escape = !escape;
+ continue;
+ } else if (!escape && r.test(ch)) { // digit-like character, belongs to 'number' part
+ scope = 'NUMBER';
+ } else { // part of prefix
+ result.prefix += ch;
+ result.prefixMinusMask += (ch === SYMBOLS.minusSign && !escape ? '-' : ' ');
+ continue;
+ }
+ }
+ if (scope === 'NUMBER') {
+ // number
+ if (r.test(ch)) { // digit-like character
+ result.number += ch;
+ continue;
+ } else { // number is finished, belongs to suffix
+ scope = 'SUFFIX';
+ }
+ }
+ if (scope === 'SUFFIX') {
+ // suffix
+ if (ch === '\'') { // toggle escape
+ if (escape && pattern.charAt(i - 1) === '\'') { // two consecutive ' are equal to one literal '
+ result.suffix += '\'';
+ result.suffixMinusMask += ' ';
+ }
+ escape = !escape;
+ continue;
+ } else { // part of suffix
+ result.suffix += ch;
+ result.suffixMinusMask += (ch === SYMBOLS.minusSign && !escape ? '-' : ' ');
+ }
+ }
+ }
+ return result;
+};

Back to the top