0

I want to validate if the fields of all inputs in a form are not empty, currently I'm doing that like so:

const handleSubmit = (e) => {
    if (!formCompra.input1|| !formCompra.input2|| !restForm.input3|| 
    !restForm.input4|| !restForm.input5) {
      alert('you are missing some fields')
    }
}

This works fine, but the message is very generic. That's why I'm looking for a way to perform the validation in a way that outputs a message containing all the missing fields, for example: "you're missing input1, input2".

0

3 Answers 3

1

Let's say your formComp is an object with values. We should be making a generic error handler here.

let formComp = {
  input1: 'fdsg/',
  input2: 'fdsfsd',
  input3: 321,
  input4: '',
  input5: null
}


let errorMessage = Object.keys(formComp).reduce((message, key) => {
  if (!formComp[key]) {
    message += `${key} is missing ! \n`
  }
  return message
}, '')

if (errorMessage) console.log(errorMessage)

This is a pretty good use case of reduce method.

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

Comments

1

You could just loop through formCompra like so:

const data = {
  input1: "1",
  input2: "",
  input3: "3"
}

for (input in data) {
  if (!data[input]) console.log(`you are missing ${input}`)
}

[...]for example "you're missing input1, input2"

If you want to have multiple fields in your error message, you could do something like this:

const data = {
  input1: "1",
  input2: "",
  input3: "3",
  input4: ""
}

const validate = () => {
  let missing_fields = []
  for (input in data) {
    if (!data[input]) missing_fields.push(input)
  }
  let message = "You are missing"
  for (let i = 0; i < missing_fields.length; i++) {
    if (i === missing_fields.length - 1) {
      message += ` ${missing_fields[i]}.`
      console.log(message)
    }
    message += ` ${missing_fields[i]},`
  }
}

validate()


PS: The object keys should be given descriptive names instead of input1 etc. for this approach

Comments

1

With this example, where I assume all of your inputs are controlled, you either need to backlink those values to the element, to know what kind of alert to throw and get some reasonable normal text to throw (you probably don't want to throw "You are missing input5") from data property of HTML element, or in your instance I'd just go and if(){} else if(){} every single case.

The better thing to do would be to get all the inputs from event that you are getting on handleSubmit and check it with those values.

As it's not exactly straight forward to have good responding form in multiple languages there are packages available to solve this. I'd recommend https://www.npmjs.com/package/yup.

Also checking for empty input by doing !value is not a good practice, as when you get to TypeScript you might encounter the fact that 0 == True inside of your numeric inputs and EsLint errors regarding not explicitly asking to handle the nullish/empty cases explicitly.

Here is a one way of doing it:

const MyForm = () => {
  const handleSubmit = (event) => {
    event.preventDefault();
    const formChildren = event.target.children;
    for (let index = 0; index < formChildren.length; ++index) {
      if (formChildren[index].nodeName == "INPUT") {
        //console.log(formChildren[index].validity); Or you can go this route
        if (
          formChildren[index].value == "" ||
          formChildren[index].value == undefined
        ) {
          console.log(
            `Input ${formChildren[index].dataset["userFriendlyInputName"]} cannot be empty`
          );
        }
      }
    }
  };
  return (
    <form onSubmit={handleSubmit}>
      <input name="name" data-user-friendly-input-name="Name" />
      <input name="surname" 
      />
      {/*
        Or you can choose any of those build in parameters
        <input name="email" 
          pattern=""
          min-length=""
          required=""
        />
      */
      }
      <button type="submit" />
    </form>
  );
};
export default MyForm;

2 Comments

!"" = true this should be true since this would be considered empty. !0 = true would only happen if 0 is set by the value property (e.g.: value={0}), since numeric inputs still produce a string, i.e.: a 0 input into an input of type="number" by a user would produce "0" and not an integer.
@Finn Those were just a examples, it's more of a problem of bad practice rather than problem in this example. As if you go to TypeScript and strict linting, you will start to convert your numeric inputs to numeric values and some big rulesets for Eslint require you to be solve nullish cases explicitly. Also there are much better ways to solve this using somethings such as built in input validity/pattern etc.

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.