From c57d504794b6020d42dcdabe08a13ed412450fc1 Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 7 Nov 2017 20:06:26 -0330 Subject: Add currency-input component to correct send amount behaviour and move currency display value state to parent component. --- ui/app/components/currency-input.js | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 ui/app/components/currency-input.js (limited to 'ui/app/components/currency-input.js') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js new file mode 100644 index 000000000..5e534d87b --- /dev/null +++ b/ui/app/components/currency-input.js @@ -0,0 +1,93 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits + +module.exports = CurrencyInput + +inherits(CurrencyInput, Component) +function CurrencyInput (props) { + Component.call(this) + + this.state = { + value: sanitizeValue(props.value), + } +} + +function removeNonDigits (str) { + return str.match(/\d|$/g).join('') +} + +// Removes characters that are not digits, then removes leading zeros +function sanitizeInteger (val) { + return String(parseInt(removeNonDigits(val) || '0', 10)) +} + +function sanitizeDecimal (val) { + return removeNonDigits(val) +} + +// Take a single string param and returns a non-negative integer or float as a string. +// Breaks the input into three parts: the integer, the decimal point, and the decimal/fractional part. +// Removes leading zeros from the integer, and non-digits from the integer and decimal +// The integer is returned as '0' in cases where it would be empty. A decimal point is +// included in the returned string if one is included in the param +// Examples: +// sanitizeValue('0') -> '0' +// sanitizeValue('a') -> '0' +// sanitizeValue('010.') -> '10.' +// sanitizeValue('0.005') -> '0.005' +// sanitizeValue('22.200') -> '22.200' +// sanitizeValue('.200') -> '0.200' +// sanitizeValue('a.b.1.c,89.123') -> '0.189123' +function sanitizeValue (value) { + let [,integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value) + + integer = sanitizeInteger(integer) || '0' + decimal = sanitizeDecimal(decimal) + + return `${integer}${point}${decimal}` +} + +CurrencyInput.prototype.handleChange = function (newValue) { + const { onInputChange } = this.props + + this.setState({ value: sanitizeValue(newValue) }) + + onInputChange(sanitizeValue(newValue)) +} + +// If state.value === props.value plus a decimal point, or at least one +// zero or a decimal point and at least one zero, then this returns state.value +// after it is sanitized with getValueParts +CurrencyInput.prototype.getValueToRender = function () { + const { value } = this.props + const { value: stateValue } = this.state + + const trailingStateString = (new RegExp(`^${value}(.+)`)).exec(stateValue) + const trailingDecimalAndZeroes = trailingStateString && (/^[.0]0*/).test(trailingStateString[1]) + + return sanitizeValue(trailingDecimalAndZeroes + ? stateValue + : value) +} + +CurrencyInput.prototype.render = function () { + const { + className, + placeholder, + readOnly, + } = this.props + + const inputSizeMultiplier = readOnly ? 1 : 1.2 + + const valueToRender = this.getValueToRender() + + return h('input', { + className, + value: valueToRender, + placeholder, + size: valueToRender.length * inputSizeMultiplier, + readOnly, + onChange: e => this.handleChange(e.target.value), + }) +} -- cgit v1.2.3 From 5120cfdff3047e4bf88cec544895cc713d063cdd Mon Sep 17 00:00:00 2001 From: Thomas Huang Date: Thu, 9 Nov 2017 14:23:10 -0800 Subject: Linting --- ui/app/components/currency-input.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/currency-input.js') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js index 5e534d87b..f192ee531 100644 --- a/ui/app/components/currency-input.js +++ b/ui/app/components/currency-input.js @@ -40,7 +40,7 @@ function sanitizeDecimal (val) { // sanitizeValue('.200') -> '0.200' // sanitizeValue('a.b.1.c,89.123') -> '0.189123' function sanitizeValue (value) { - let [,integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value) + let [integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value) integer = sanitizeInteger(integer) || '0' decimal = sanitizeDecimal(decimal) -- cgit v1.2.3 From a33ced39946c1448b56aef22ab3573b00d1faeca Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 10 Nov 2017 15:17:02 -0330 Subject: Focus amount input when click anywhere in amount field container --- ui/app/components/currency-input.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ui/app/components/currency-input.js') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js index f192ee531..016f14d3e 100644 --- a/ui/app/components/currency-input.js +++ b/ui/app/components/currency-input.js @@ -76,6 +76,7 @@ CurrencyInput.prototype.render = function () { className, placeholder, readOnly, + inputRef, } = this.props const inputSizeMultiplier = readOnly ? 1 : 1.2 @@ -89,5 +90,6 @@ CurrencyInput.prototype.render = function () { size: valueToRender.length * inputSizeMultiplier, readOnly, onChange: e => this.handleChange(e.target.value), + ref: inputRef, }) } -- cgit v1.2.3 From 0a91671ff69957596abbcffb7d20c89f144d7a69 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 8 Nov 2017 15:48:27 -0330 Subject: Fix lint errors. --- ui/app/components/currency-input.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/currency-input.js') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js index 016f14d3e..66880091f 100644 --- a/ui/app/components/currency-input.js +++ b/ui/app/components/currency-input.js @@ -40,7 +40,7 @@ function sanitizeDecimal (val) { // sanitizeValue('.200') -> '0.200' // sanitizeValue('a.b.1.c,89.123') -> '0.189123' function sanitizeValue (value) { - let [integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value) + let [ , integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value) integer = sanitizeInteger(integer) || '0' decimal = sanitizeDecimal(decimal) -- cgit v1.2.3 From baebf64afd594316a4e160ff1d046ea68bfc5c70 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 15 Jan 2018 14:37:59 -0800 Subject: Fix send screen value input --- ui/app/components/currency-input.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'ui/app/components/currency-input.js') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js index 66880091f..6f7862e51 100644 --- a/ui/app/components/currency-input.js +++ b/ui/app/components/currency-input.js @@ -50,10 +50,18 @@ function sanitizeValue (value) { CurrencyInput.prototype.handleChange = function (newValue) { const { onInputChange } = this.props + const { value } = this.state - this.setState({ value: sanitizeValue(newValue) }) + let parsedValue = newValue + const newValueLastIndex = newValue.length - 1 - onInputChange(sanitizeValue(newValue)) + if (value === '0' && newValue[newValueLastIndex] === '0') { + parsedValue = parsedValue.slice(0, newValueLastIndex) + } + + const sanitizedValue = sanitizeValue(parsedValue) + this.setState({ value: sanitizedValue }) + onInputChange(sanitizedValue) } // If state.value === props.value plus a decimal point, or at least one @@ -90,6 +98,6 @@ CurrencyInput.prototype.render = function () { size: valueToRender.length * inputSizeMultiplier, readOnly, onChange: e => this.handleChange(e.target.value), - ref: inputRef, + ref: inputRef, }) } -- cgit v1.2.3