Skip to content

Commit

Permalink
Merge pull request #631 from poanetwork/restrict-token-mantissa-to-de…
Browse files Browse the repository at this point in the history
…cimals-#592

(Fix) Restrict token mantissa to decimals
  • Loading branch information
vbaranov committed Mar 1, 2018
2 parents c1c4040 + 1810e9f commit f8d26b9
Show file tree
Hide file tree
Showing 14 changed files with 1,092 additions and 669 deletions.
2 changes: 1 addition & 1 deletion src/components/Common/InputField.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const InputField = props => {
onPaste={props.onPaste}
/>
<p className="description">{props.description}</p>
{ props.pristine ? null : <p style={errorStyle}>{error}</p> }
{ props.pristine ? <p style={errorStyle}/> : <p style={errorStyle}>{error}</p> }
</div>
);
};
112 changes: 74 additions & 38 deletions src/components/Common/NumericInput.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Component } from 'react'
import { InputField } from './InputField'
import { VALIDATION_TYPES } from '../../utils/constants'
import { observer } from 'mobx-react'
import { countDecimalPlaces } from '../../utils/utils'
import { observer } from 'mobx-react'

const { VALID, INVALID } = VALIDATION_TYPES

Expand All @@ -12,78 +12,114 @@ export class NumericInput extends Component {
super(props)

this.state = {
value: '',
pristine: true,
valid: INVALID
value: props.value || '',
pristine: props.pristine !== undefined ? props.pristine : true,
valid: props.valid || VALID
}
}

onPaste = e => {
if (isNaN(parseFloat(e.clipboardData.getData('text/plain'))))
if (isNaN(parseFloat(e.clipboardData.getData('text/plain')))) {
e.preventDefault()
}
}

onKeyPress = e => {
if (!this.props.acceptFloat) {
const firstCharacterIsMinus = e.key === '-' && this.state.value === ''
const acceptsNegativeValues = this.props.min < 0 || this.props.max < 0
const { min, max, acceptFloat } = this.props
const allowsNegative = min < 0 || max < 0

if (!(firstCharacterIsMinus && acceptsNegativeValues) && isNaN(parseInt(e.key, 10))) e.preventDefault()
if ((e.key === 'e' || e.key === '.' || e.key === '+') && !acceptFloat) {
e.preventDefault()
}

// '-' symbol is required for scientific notation and negative values
if (e.key === '-' && !allowsNegative && !acceptFloat) {
e.preventDefault()
}
}

onChange = e => {
let value = this.props.acceptFloat ? parseFloat(e.target.value) : parseInt(e.target.value, 10)
const value = this.props.acceptFloat ? parseFloat(e.target.value) : parseInt(e.target.value, 10)
this.validate(value)
}

validate = value => {
const { acceptFloat, maxDecimals, minDecimals, min, max } = this.props
let isValid = true

if (this.props.acceptFloat) {
if (this.props.maxDecimals !== undefined) {
isValid = isValid && countDecimalPlaces(value) <= this.props.maxDecimals
if (acceptFloat) {
if (maxDecimals !== undefined) {
isValid = isValid && countDecimalPlaces(value) <= maxDecimals
}

if (this.props.minDecimals !== undefined) {
isValid = isValid && countDecimalPlaces(value) >= this.props.minDecimals
if (minDecimals !== undefined) {
isValid = isValid && countDecimalPlaces(value) >= minDecimals
}
}

if (isValid && this.props.min !== undefined) {
isValid = isValid && value >= this.props.min
if (isValid && min !== undefined) {
isValid = isValid && value >= min
}

if (isValid && this.props.max !== undefined) {
isValid = isValid && value <= this.props.max
if (isValid && max !== undefined) {
isValid = isValid && value <= max
}

if (isNaN(value)) {
value = ''
isValid = true
const result = {
value: '',
pristine: value === this.props.value && this.state.pristine,
valid: INVALID
}

if (!isNaN(value)) {
result.value = value
result.valid = isValid ? VALID : INVALID
}

this.props.onValueUpdate(result)
}

componentWillReceiveProps (newProps) {
this.setState({
pristine: false,
valid: isValid ? VALID : INVALID,
value
value: newProps.value,
pristine: newProps.pristine,
valid: newProps.valid
})
}

componentDidUpdate (prevProps) {
const { acceptFloat, maxDecimals, minDecimals, min, max } = this.props

this.props.onValueUpdate(value)
if (
prevProps.acceptFloat !== acceptFloat ||
prevProps.minDecimals !== minDecimals ||
prevProps.maxDecimals !== maxDecimals ||
prevProps.min !== min ||
prevProps.max !== max
) {
// re-check validity if any of the props had changed
this.validate(this.state.value)
}
}

render () {
const { value, pristine, valid } = this.state
const { disabled, side, errorMessage, title, description } = this.props

return (
<InputField
disabled={this.props.disabled}
side={this.props.side}
disabled={disabled}
side={side}
type='number'
errorMessage={this.props.errorMessage}
valid={this.state.valid}
pristine={this.state.pristine}
value={this.state.value}
title={this.props.title}
style={this.props.style}
onKeyPress={e => this.onKeyPress(e)}
onChange={e => this.onChange(e)}
onPaste={e => this.onPaste(e)}
description={this.props.description}
errorMessage={errorMessage}
value={value}
pristine={pristine}
valid={valid}
title={title}
onKeyPress={this.onKeyPress}
onChange={this.onChange}
onPaste={this.onPaste}
description={description}
/>
)
}
Expand Down
Loading

0 comments on commit f8d26b9

Please sign in to comment.