Add additional validation to Amount input field (#1982)

* Adjust the validator and update validity class logic on AmountField

* Improve readability and add a condition to invalidity for Input

* Undo changes to Input and pass down showInvalidWithoutValue

* Fix prop ordering issue

* Add removed validator

* Adjust logic for NoneField
This commit is contained in:
Connor Bryan 2018-07-02 16:51:51 -05:00 committed by Daniel Ternyak
parent a3a92504d2
commit 0d13dc93c5
7 changed files with 30 additions and 5 deletions

View File

@ -9,6 +9,7 @@ interface Props {
hasUnitDropdown?: boolean; hasUnitDropdown?: boolean;
hasSendEverything?: boolean; hasSendEverything?: boolean;
showAllTokens?: boolean; showAllTokens?: boolean;
showInvalidWithoutValue?: boolean;
customValidator?(rawAmount: string): boolean; customValidator?(rawAmount: string): boolean;
} }
@ -16,7 +17,8 @@ export const AmountField: React.SFC<Props> = ({
hasUnitDropdown, hasUnitDropdown,
hasSendEverything, hasSendEverything,
showAllTokens, showAllTokens,
customValidator customValidator,
showInvalidWithoutValue
}) => ( }) => (
<AmountFieldFactory <AmountFieldFactory
withProps={({ currentValue: { raw }, isValid, onChange, readOnly }) => ( withProps={({ currentValue: { raw }, isValid, onChange, readOnly }) => (
@ -30,6 +32,7 @@ export const AmountField: React.SFC<Props> = ({
value={raw} value={raw}
readOnly={!!readOnly} readOnly={!!readOnly}
onChange={onChange} onChange={onChange}
showInvalidWithoutValue={showInvalidWithoutValue}
/> />
{hasSendEverything && <SendEverything />} {hasSendEverything && <SendEverything />}
{hasUnitDropdown && <UnitDropDown showAllTokens={showAllTokens} />} {hasUnitDropdown && <UnitDropDown showAllTokens={showAllTokens} />}

View File

@ -12,6 +12,7 @@ import './NonceField.scss';
interface OwnProps { interface OwnProps {
alwaysDisplay: boolean; alwaysDisplay: boolean;
showInvalidBeforeBlur?: boolean;
} }
interface StateProps { interface StateProps {
@ -27,7 +28,13 @@ type Props = OwnProps & DispatchProps & StateProps;
class NonceField extends React.Component<Props> { class NonceField extends React.Component<Props> {
public render() { public render() {
const { alwaysDisplay, requestNonce, noncePending, isOffline } = this.props; const {
alwaysDisplay,
showInvalidBeforeBlur,
requestNonce,
noncePending,
isOffline
} = this.props;
return ( return (
<NonceFieldFactory <NonceFieldFactory
withProps={({ nonce: { raw, value }, onChange, readOnly, shouldDisplay }) => { withProps={({ nonce: { raw, value }, onChange, readOnly, shouldDisplay }) => {
@ -51,6 +58,7 @@ class NonceField extends React.Component<Props> {
onChange={onChange} onChange={onChange}
disabled={noncePending} disabled={noncePending}
showInvalidWithoutValue={true} showInvalidWithoutValue={true}
showInvalidBeforeBlur={showInvalidBeforeBlur}
/> />
{noncePending ? ( {noncePending ? (
<div className="Nonce-spinner"> <div className="Nonce-spinner">

View File

@ -106,7 +106,7 @@ class AdvancedGas extends React.Component<Props, State> {
)} )}
{nonceField && ( {nonceField && (
<div className="AdvancedGas-nonce"> <div className="AdvancedGas-nonce">
<NonceField alwaysDisplay={true} /> <NonceField alwaysDisplay={true} showInvalidBeforeBlur={true} />
</div> </div>
)} )}
</div> </div>

View File

@ -49,7 +49,7 @@ class Input extends React.Component<Props, State> {
} else if (!hasBlurred && !showInvalidBeforeBlur) { } else if (!hasBlurred && !showInvalidBeforeBlur) {
validClass = ''; validClass = '';
} }
if (!hasValue && showInvalidWithoutValue) { if ((!isStateless || showInvalidBeforeBlur) && !hasValue && showInvalidWithoutValue) {
validClass = 'invalid'; validClass = 'invalid';
} }

View File

@ -54,7 +54,11 @@ class FieldsClass extends Component<StateProps> {
<div <div
className={schedulingAvailable ? 'col-sm-9 col-md-10' : 'col-sm-12 col-md-12'} className={schedulingAvailable ? 'col-sm-9 col-md-10' : 'col-sm-12 col-md-12'}
> >
<AmountField hasUnitDropdown={true} hasSendEverything={true} /> <AmountField
hasUnitDropdown={true}
hasSendEverything={true}
showInvalidWithoutValue={true}
/>
</div> </div>
{schedulingAvailable && ( {schedulingAvailable && (
<div className="col-sm-3 col-md-2"> <div className="col-sm-3 col-md-2">

View File

@ -102,6 +102,7 @@ class RequestPayment extends React.Component<Props, {}> {
hasUnitDropdown={true} hasUnitDropdown={true}
showAllTokens={true} showAllTokens={true}
customValidator={isValidAmount(decimal)} customValidator={isValidAmount(decimal)}
showInvalidWithoutValue={true}
/> />
</div> </div>
</div> </div>

View File

@ -133,11 +133,20 @@ export const validPositiveNumber = (num: number) => validNumber(num) && num !==
export const validDecimal = (input: string, decimal: number) => { export const validDecimal = (input: string, decimal: number) => {
const arr = input.split('.'); const arr = input.split('.');
// Only a single decimal can exist.
if (arr.length > 2) {
return false;
}
const fractionPortion = arr[1]; const fractionPortion = arr[1];
if (!fractionPortion || fractionPortion.length === 0) { if (!fractionPortion || fractionPortion.length === 0) {
return true; return true;
} }
const decimalLength = fractionPortion.length; const decimalLength = fractionPortion.length;
return decimalLength <= decimal; return decimalLength <= decimal;
}; };