diff --git a/dev/configure-globalize.js b/dev/configure-globalize.js
index 0fa09260f..50a036755 100644
--- a/dev/configure-globalize.js
+++ b/dev/configure-globalize.js
@@ -2,16 +2,16 @@ var Globalize = require('globalize')
var localizers = require('../src/localizers/globalize')
Globalize.load(
- require('cldr-data/main/en-GB/ca-gregorian.json'),
- require('cldr-data/main/en-GB/currencies.json'),
- require('cldr-data/main/en-GB/dateFields.json'),
- require('cldr-data/main/en-GB/numbers.json'),
+ require('cldr-data/main/sk/ca-gregorian.json'),
+ require('cldr-data/main/sk/currencies.json'),
+ require('cldr-data/main/sk/dateFields.json'),
+ require('cldr-data/main/sk/numbers.json'),
require('cldr-data/supplemental/numberingSystems.json'),
require('cldr-data/supplemental/currencyData.json'),
require('cldr-data/supplemental/likelySubtags.json'),
require('cldr-data/supplemental/timeData.json'),
require('cldr-data/supplemental/weekData.json')
);
-Globalize.locale('en-GB')
+Globalize.locale('sk')
localizers(Globalize)
diff --git a/dev/configure-simplenumber.js b/dev/configure-simplenumber.js
new file mode 100644
index 000000000..ced57a47e
--- /dev/null
+++ b/dev/configure-simplenumber.js
@@ -0,0 +1,3 @@
+var localizers = require('../src/localizers/simple-number')
+
+localizers()
diff --git a/dev/dev.jsx b/dev/dev.jsx
index 250aa7b2e..955e8ebb0 100644
--- a/dev/dev.jsx
+++ b/dev/dev.jsx
@@ -19,7 +19,8 @@ var NumberPicker = require('../src/NumberPicker.jsx')
// var List = require('../src/List.jsx')
require('../src/less/react-widgets.less')
-require('./configure-moment')
+require('./configure-globalize')
+//require('./configure-simplenumber')
var chance = new (require('chance'))
@@ -96,12 +97,7 @@ var App = React.createClass({
>
add
-
+
diff --git a/docs/components/pages/i18n.md b/docs/components/pages/i18n.md
index 0cb676ed1..7c635ac3c 100644
--- a/docs/components/pages/i18n.md
+++ b/docs/components/pages/i18n.md
@@ -246,6 +246,16 @@ function(
) -> String
```
+#### `decimalChar` -> '.'
+
+Return the decimal separator character.
+
+```
+function(
+ format: String|Object,
+ culture: String?
+) -> String
+```
#### `precision`
diff --git a/src/NumberInput.jsx b/src/NumberInput.jsx
index 682840733..b0c6ec253 100644
--- a/src/NumberInput.jsx
+++ b/src/NumberInput.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import CustomPropTypes from './util/propTypes';
import { number as numberLocalizer } from './util/localizers';
-var format = props => numberLocalizer.getFormat('default', props.format)
+let getFormat = props => numberLocalizer.getFormat('default', props.format)
export default React.createClass({
@@ -13,6 +13,7 @@ export default React.createClass({
placeholder: React.PropTypes.string,
format: CustomPropTypes.numberFormat,
+
parse: React.PropTypes.func.isRequired,
culture: React.PropTypes.string,
@@ -25,20 +26,23 @@ export default React.createClass({
getDefaultProps(){
return {
value: null,
- editing: false,
- parse: (number, culture) => numberLocalizer.parse(number, culture)
+ editing: false
}
},
- getDefaultState(props){
- var value = props.editing
- ? props.value
- : formatNumber(props.value, format(props), props.culture)
+ getDefaultState(props = this.props){
+ var value = props.value
+ , decimal = numberLocalizer.decimalChar(null, props.culture)
+ , format = getFormat(props);
this._beginningWithSign = false;
if (value == null || isNaN(props.value))
value = ''
+ else
+ value = props.editing
+ ? ('' + value).replace('.', decimal)
+ : numberLocalizer.format(value, format, props.culture)
return {
stringValue: '' + value
@@ -46,7 +50,7 @@ export default React.createClass({
},
getInitialState() {
- return this.getDefaultState(this.props)
+ return this.getDefaultState()
},
componentWillReceiveProps(nextProps) {
@@ -82,7 +86,7 @@ export default React.createClass({
_change(e) {
var val = e.target.value
- , number = this.props.parse(e.target.value, this.props.culture)
+ , number = this._parse(e.target.value)
, atSign = this.isSign(val.trim())
, startingWithSign = this._beginningWithSign;
@@ -93,16 +97,20 @@ export default React.createClass({
return this.props.onChange(null)
}
- if (this.isFlushable(number, val))
- return this.props.onChange(number)
+ if (this.isFlushable(number, val)) {
+ if (number !== this.props.value)
+ return this.props.onChange(number)
+ else
+ this.setState(this.getDefaultState()) // 5. -> 5
+ }
- if (!isNaN(number) || (atSign && startingWithSign) || this.isAtDelimiter(number, val))
+ if ((atSign && startingWithSign) || this.isAtDelimiter(number, val))
this.current(e.target.value)
},
_finish() {
var str = this.state.stringValue
- , number = this.props.parse(str, this.props.culture);
+ , number = this._parse(str);
// if number is below the min
// we need to flush low values and decimal stops, onBlur means i'm done inputing
@@ -113,19 +121,21 @@ export default React.createClass({
_parse(strVal) {
let culture = this.props.culture
- , format = this.props.editFormat
+ , delimChar = numberLocalizer.decimalChar(null, culture)
, userParse = this.props.parse;
if (userParse)
return userParse(strVal, culture)
- return format ? numberLocalizer.parse(strVal, culture) : +strVal
+ strVal = strVal.replace(delimChar, '.')
+ strVal = parseFloat(strVal);
+
+ return strVal
},
isFlushable(num, str) {
return (
- this.isValid(num)
- && num !== this.props.value
+ this.isValid(num)
&& !this.isAtDelimiter(num, str)
&& !this.isSign(str)
)
@@ -135,17 +145,17 @@ export default React.createClass({
return (val || '').trim() === '-';
},
- isAtDelimiter(num, str) {
- var next;
+ isAtDelimiter(num, str, props = this.props) {
+ var localeChar = numberLocalizer.decimalChar(null, props.culture)
+ , lastIndex = str.length - 1
+ , char;
if (str.length <= 1) return false
- next = this.props.parse(
- str.substr(0, str.length - 1), this.props.culture)
+ char = str[lastIndex]
- return typeof next === 'number'
- && !isNaN(next)
- && next === num
+ return char === localeChar
+ && str.indexOf(char) === lastIndex
},
isValid(num) {
@@ -160,8 +170,3 @@ export default React.createClass({
}
});
-
-
-function formatNumber(number, format, culture){
- return numberLocalizer.format(number, format, culture)
-}
diff --git a/src/NumberPicker.jsx b/src/NumberPicker.jsx
index e0fdae512..90ccfeb97 100644
--- a/src/NumberPicker.jsx
+++ b/src/NumberPicker.jsx
@@ -195,7 +195,7 @@ let NumberPicker = React.createClass({
},
@widgetEnabled
- _focus(focused, e){
+ _focus(focused, e) {
focused && compat.findDOMNode(this.refs.input).focus()
diff --git a/src/localizers/globalize.js b/src/localizers/globalize.js
index 2552ccd63..3d421b88f 100644
--- a/src/localizers/globalize.js
+++ b/src/localizers/globalize.js
@@ -77,11 +77,12 @@ function newGlobalize(globalize){
propType: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
- parse(value, format, culture){
- return locale(culture).parseNumber(value, format)
+ // TODO major bump consistent ordering
+ parse(value, culture) {
+ return locale(culture).parseNumber(value)
},
- format(value, format, culture){
+ format(value, format, culture) {
if (value == null)
return value
@@ -91,7 +92,12 @@ function newGlobalize(globalize){
return locale(culture).formatNumber(value, format)
},
- precision(format){
+ decimalChar(format, culture) {
+ let str = this.format(1.1, { raw: '0.0' }, culture)
+ return str[str.length - 2] || '.'
+ },
+
+ precision(format) {
return !format || format.maximumFractionDigits == null
? null : format.maximumFractionDigits
}
@@ -154,13 +160,26 @@ function oldGlobalize(globalize){
}
}
+ function formatData(format, _culture){
+ var culture = getCulture(_culture)
+ , numFormat = culture.numberFormat
+
+ if (typeof format === 'string') {
+ if (format.indexOf('p') !== -1) numFormat = numFormat.percent
+ if (format.indexOf('c') !== -1) numFormat = numFormat.curency
+ }
+
+ return numFormat
+ }
+
var number = {
formats: {
default: 'D'
},
- parse(value, culture){
+ // TODO major bump consistent ordering
+ parse(value, culture) {
return globalize.parseFloat(value, 10, culture)
},
@@ -168,21 +187,18 @@ function oldGlobalize(globalize){
return globalize.format(value, format, culture)
},
- precision(format, _culture){
- var culture = getCulture(_culture)
- , numFormat = culture.numberFormat
-
- if (typeof format === 'string') {
- if (format.length > 1)
- return parseFloat(format.substr(1))
+ decimalChar(format, culture){
+ var data = formatData(format, culture)
+ return data['.'] || '.'
+ },
- if (format.indexOf('p') !== -1) numFormat = numFormat.percent
- if (format.indexOf('c') !== -1) numFormat = numFormat.curency
+ precision(format, _culture){
+ var data = formatData(format, _culture)
- return numFormat.decimals || null
- }
+ if (typeof format === 'string' && format.length > 1)
+ return parseFloat(format.substr(1))
- return null
+ return data ? data.decimals : null
}
}
diff --git a/src/localizers/simple-number.js b/src/localizers/simple-number.js
index 5a5e5a274..ea3534608 100644
--- a/src/localizers/simple-number.js
+++ b/src/localizers/simple-number.js
@@ -2,24 +2,27 @@ import configure from '../configure'
import formatNumber from 'format-number-with-string';
import deconstruct from 'deconstruct-number-format';
-export default function simpleNumber(){
+let defaults = {
+ decimal: '.',
+ grouping: ','
+}
+
let localizer = {
formats: {
- default: '-#,##0.'
+ default: `-#${grouping}##0${decimal}`,
},
-
- parse(value, format){
+
+ // TODO major bump consistent ordering
+ parse(value, culture, format) {
if (format) {
let data = deconstruct(format)
-
- if (data.negativeLeftPos !== -1)
- value = value.substr(data.negativeLeftPos + 1)
-
- if (data.negativeRightPos !== -1)
- value = value.substring(0, data.negativeRightPos)
+ , negative = (data.negativeLeftSymbol && value.indexOf(data.negativeLeftSymbol) !== -1)
+ || (data.negativeRightSymbol && value.indexOf(data.negativeRightSymbol) !== -1)
value = value
+ .replace(data.negativeLeftSymbol, '')
+ .replace(data.negativeRightSymbol, '')
.replace(data.prefix, '')
.replace(data.suffix, '')
@@ -31,18 +34,29 @@ export default function simpleNumber(){
if (data.decimalsSeparator)
halves[1] = halves[1].replace(new RegExp('\\' + data.decimalsSeparator, 'g'))
- value = halves.join(data.decimalChar)
+ if (halves[1] === '') halves.pop();
+
+ value = halves.join('.')
+ value = +value
+
+ if (negative)
+ value = -1 * value
}
- let number = parseFloat(value)
+ else
+ value = parseFloat(value)
- return number
+ return isNaN(value) ? null : value
},
- format(value, format){
+ format(value, format) {
return formatNumber(value, format)
},
- precision(format){
+ decimalChar(format) {
+ return format && deconstruct(format).decimalsSeparator || '.'
+ },
+
+ precision(format) {
let data = deconstruct(format)
return data.maxRight !== -1 ? data.maxRight : null
}
diff --git a/src/util/localizers.js b/src/util/localizers.js
index 523e13196..d5016c9d3 100644
--- a/src/util/localizers.js
+++ b/src/util/localizers.js
@@ -42,7 +42,7 @@ function checkFormats(requiredFormats, formats){
let _numberLocalizer = createWrapper('NumberPicker')
-export function setNumber({ format, parse, precision = () => null, formats, propType }) {
+export function setNumber({ format, parse, decimalChar = () => '.', precision = () => null, formats, propType }) {
invariant(typeof format === 'function'
, 'number localizer `format(..)` must be a function')
invariant(typeof parse === 'function'
@@ -50,17 +50,20 @@ export function setNumber({ format, parse, precision = () => null, formats, prop
checkFormats(REQUIRED_NUMBER_FORMATS, formats)
+ formats.editFormat = formats.editFormat || (str => parseFloat(str));
+
_numberLocalizer = {
formats,
precision,
+ decimalChar,
propType: propType || localePropType,
format(value, str, culture){
return _format(this, format, value, str, culture)
},
- parse(value, culture) {
- let result = parse.call(this, value, culture)
+ parse(value, culture, format) {
+ let result = parse.call(this, value, culture, format)
invariant(result == null || typeof result === 'number'
, 'number localizer `parse(..)` must return a number, null, or undefined')
return result
@@ -107,6 +110,9 @@ export let number = {
format(...args){
return _numberLocalizer.format(...args)
},
+ decimalChar(...args){
+ return _numberLocalizer.decimalChar(...args)
+ },
precision(...args){
return _numberLocalizer.precision(...args)
}