0

I have a component with an input field and checkbox. As it stands the checkbox disables the input field and clears any validation errors. What I'm trying to do is create additional functionality that if someone unchecks that box and the input becomes active again, a validation will run and once again prompt the user to enter an email. I have a code sandbox here for example and my full component listed below

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {
  Col, Row, Icon, Input, Tooltip
} from 'antd'
import Checkbox from '../elements/Checkbox'
import Markup from '../core/Markup'

function validateEmail(value) {
  const errors = {}
  if (value === '') {
    errors.email = 'Email address is required'
  } else if (!/\S+@\S+\.\S+/.test(value)) {
    errors.email = 'Email address is invalid'
  }
  return errors
}

const CustomerDetails = ({ customer }) => {
  const { contact = {}, account = {}, site = {} } = customer || {}
  const [disableInput, setDisableInput] = React.useState(false)
  const [errors, setErrors] = React.useState({})
  const [inputValue, setInputValue] = React.useState(contact.email)

  function onBlur(e) {
    setErrors(validateEmail(e.target.value))
  }

  function clearInput() {
    setInputValue(' ')
  }

  function handleInputChange(event) {
    setInputValue(event.target.value)
  }

  function CheckboxClick() {
    if (!disableInput) {
      clearInput()
    }
    setDisableInput(prevValue => !prevValue)
    setError({})
  }


  return (
    <Container>
      <Row>
        <Col span={10}>
          <h4>
            PRIMARY CONTACT EMAIL &nbsp;
          </h4>
        </Col>
      </Row>
      <Row>
        <Col span={8}>
          <StyledInput
            value={inputValue}
            onChange={handleInputChange}
            disabled={disableInput}
            onBlur={onBlur}
            isError={!!errors.email}
          />
          {errors.email && <ErrorDiv>{errors.email}</ErrorDiv>}
        </Col>
        <Col span={2} />
        <Col span={8}>
          <StyledCheckbox
            value={disableInput}
            onChange={CheckboxClick}
          /> EMAIL
          OPT OUT{' '}
        </Col>
      </Row>
    </Container>
  )
}



const Container = styled.div`
  text-align: left;
`
const StyledCheckbox = styled(Checkbox)`
  &&& {
    background: white;

    input + span {
      width: 35px;
      height: 35px;
      border: 2px solid ${({ theme }) => theme.colors.black};
    }

    input + span:after {
      width: 12.5px;
      height: 20px;
    }

    input:focus + span {
      width: 35px;
      height: 35px;
    }
  }
`

const ErrorInput = ({ isError, ...remainingProps }) => (
  <Input {...remainingProps} />
)

ErrorInput.propTypes = {
  isError: PropTypes.bool
}

const StyledInput = styled(Input)`
  max-width: 100%;
  background: white;

  &&& {
    border: 2px solid ${props => (props.isError ? '#d11314' : 'black')};
    border-radius: 0px;
    height: 35px;
  }
`

const ErrorDiv = styled.div`
  color: #d11314;
`


export default CustomerDetails
1
  • 1
    It's hard to follow what you trying to do, try and put a MINIMAL WORKING example and explain in few words desired input and output, I suggest adding a sandbox like codesandbox.io/s/new Commented Jun 10, 2019 at 19:31

1 Answer 1

1

There are a few problems with your code:

  1. Why validate input only on onBlur
  2. Why the checkbox has a side effect for clearing output? Add a button for it.
  3. Too much boil trap code.

Here is a minimal example, you should figure it out from here what suits you:

const CustomerDetails = () => {
  const [email, setEmail] = useState('');
  const [disabled, setDisabled] = useState(false);
  const [isValid, setIsValid] = useState(false);
  const [showMsg, setShowMsg] = useState(true);

  return (
    <div className="App">
      Insert "hello"
      <Row>
        <Input
          value={email}
          onChange={e => {
            setEmail(e.target.value);
            setIsValid(isValidEmail(e.target.value));
          }}
          disabled={disabled}
        />
      </Row>
      <Row>{!isValid && showMsg && 'Email is invalid'}</Row>
      <Row type="flex" justify="space-between">
        <Col>
          <Checkbox
            value={!disabled}
            onChange={() => {
              setDisabled(prev => !prev);
              setShowMsg(prev => !prev);
              setIsValid(isValidEmail(''));
              setEmail('');
            }}
          />{' '}
          EMAIL OPT OUT
        </Col>
      </Row>
    </div>
  );
};

A Demo which validates the word hello:

Edit flamboyant-newton-mhjq7

Sign up to request clarification or add additional context in comments.

12 Comments

Both the validation and the clearing effect of the checkbox are requested functionality from the client so I'm working within those confines
Ok, I updated the clearance on a check, hope it helps
So I think I still need to add more detail to my question. If a user unchecks that checkbox another validation should run to check if the field is empty and because it will be empty after being cleared initially, the error message will flash saying email is required
And you don't understand how to accomplish that? Did you try it?
I'm not sure how to no. I tried manipulating my CheckboxClick method to run the validation after setDisableInput but nothing is working
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.