22

I'm trying to set an error for when the email isn't correct. When I'm checking if the string is empty the form alerts with the proper message. But when I'm checking if the email matches the regular expression it doesn't work. Any ideas?

import React, { Component } from 'react';
import { Link } from 'react-router';
// Our custom input component, which uses label, id and tabIndex properties
var MyInput = React.createClass({
  render: function() {

    // Get the error message by calling a function, passed to this
    // component through getError property
    var errorMessage = this.props.getError(this.props.id);

    return (
        <fieldset className={"form-fieldset ui-input first " + (errorMessage ?    "erroneous" : "")}>
            <input type="text" name={this.props.id} id={this.props.id} tabIndex={this.props.tabIndex} />
            <label htmlFor={this.props.id}>
              <span data-text={this.props.label}>{this.props.label}</span>
            </label>
            <span className="error">{errorMessage ? errorMessage : null}</span>
          </fieldset>
    )
  }
});

// Form
var SendForm = React.createClass ({
  getError: function (fieldName) {
    return this.state[fieldName+"Error"];
  },
  setError: function (fieldName, error) {
    var update = {};
    update[fieldName+"Error"] = error;
    this.setState(update);
  },
  getInitialState: function() {
    return {
      isMailSent: false,
      errorMessage: null,
    };
  },
  componentDidMount: function () {
    // This will be called right when the form element is displayed
    $('form').parsley()
  },
  validateForm: function(){
    var hasErrors = false;

    if ($('#company').val().length < 1){
      this.setError("company", "Please enter your company name");
      hasErrors = true;
    } else this.setError("company", null)

    if ($('#industry').val().length < 1){
      this.setError("industry", "Please enter the industry");
      hasErrors = true;
    } else this.setError("industry", null)

    if ($('#firstName').val().length < 1){
      this.setError("firstName", "Please enter your first name");
      hasErrors = true;
    } else this.setError("firstName", null)

    if ($('#lastName').val().length < 1) {
      this.setError("lastName", "Please enter your last name");
      hasErrors = true;
    } else this.setError("lastName", null)

    if ($('#email').val() == '') {
      this.setError("email", "Please enter your email address");
      hasErrors = true;
    } else this.setError("email", null)

    if ($('#email').val() !== /^[a-zA-Z0-9]+@+[a-zA-Z0-9]+.+[A-z]/) {
      this.setError("email", "Please enter a valid email address");
      hasErrors = true;
    } else this.setError("email", null)


    if ($('#phone').val().length < 1) {
      this.setError("phone", "Please enter your phone number");
      hasErrors = true;
    } else this.setError("phone", null)

    return !hasErrors;
  },
  handleSubmit: function (e) {
    e.preventDefault();

    // Check if data is valid
    if (!this.validateForm()) {
      //return if not valid
      return;
    }

    // Get the form.
    var form = $('form');

    // Serialize the form data.
    var formData = $(form).serialize();

    var self = this;
    console.log(formData)
    // Submit the form using AJAX.
    $.ajax({
      type: 'POST',
      url: 'email-handler.php',
      data: formData
    }).done(function(response) {

      // Update the state, notifying that mail was sent
      // This value will be used in the form when rendering
      self.setState({isMailSent: true})

      // Hide the form
      $('.formCont').hide();
    }).fail(function(data) {
      // Make sure that the formMessages div has the 'error' class.
      self.setState({errorMessage : "Something went wrong. Please try again."});
    });
  },
 render: function(){
   return (
     <div className="companyForm">

       <h2 className="header compFormHead">Form</h2>

       { this.state.isMailSent ?
           <div className="success">Thank you for submission. Someone will be in contact with you shortly.</div>
           : null }

       <div className="container formCont">
         <form method="post" acceptCharset="utf-8" autoComplete="off" onSubmit={this.handleSubmit}>

         <MyInput id="company" label="Company" tabIndex="1" getError={this.getError}/>
         <MyInput id="industry" label="Industry" tabIndex="2" getError={this.getError}/>

         <div className="two-column">
           <MyInput id="firstName" label="First Name" tabIndex="3" getError={this.getError}/>
           <MyInput id="lastName" label="Last Name" tabIndex="4" getError={this.getError}/>
         </div>
         <div className="two-column">
           <MyInput id="email" type="email" label="Email" tabIndex="5" getError={this.getError}/>
           <MyInput id="phone" label="Phone" tabIndex="6" getError={this.getError}/>
         </div>

         {this.state.errorMessage ? <div className="fail">{this.state.errorMessage}</div> : null}

         <div className="form">
           <input type="submit" name="submit" className="btn btn-primary" value="APPLY" tabIndex="7" />
         </div>

         </form>
       </div>

     </div>
   );
 }
});

export default SendForm;

11 Answers 11

37

Use RegExp#test and fix the regex like this:

if (/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[A-Za-z]+$/.test($('#email').val())) { /* return true */ }
                               ^^^^^^^^^^^^  

To support multiple dots in the domain name, you may wrap the first part with a non-capturing group and set a 1 or more occurrences quantifier:

/^[a-zA-Z0-9]+@(?:[a-zA-Z0-9]+\.)+[A-Za-z]+$/
               ^^^              ^^ 

The [A-z] actually matches some non letter symbols, and unescaped . matches any char but line break chars. Note that $ anchors the string at the end and + matches 1 or more occurrences.

There are other email regexps out there, see Validate email address in JavaScript? if your scenario differs from the one in OP.

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

7 Comments

Try with a RegExp constructor.
figured it out - it was just missing ) in the end :)
I see, I focused on the parentheses around test and missed the one for the if condition, fixed.
@MewX It is not meant to work with that email, the fix is for /^[a-zA-Z0-9]+@+[a-zA-Z0-9]+.+[A-z]/ pattern that is supposed to match [email protected] like emails. For emails like yours, you may use /^[a-zA-Z0-9]+@(?:[a-zA-Z0-9]+\.)+[A-Za-z]+$/
@WiktorStribiżew Thanks for the reply, and yeah I know. The email pattern is quite tricky actually, there are emails like [email protected] :-/
|
8

Maybe not perfect, customized @tw_hoff's post.

/.+@.+\.[A-Za-z]+$/.test("[email protected]") //true
/.+@.+\.[A-Za-z]+$/.test("[email protected]") //false

Comments

7

Another regex you can use which is a bit shorter is .+@.+\..+

It's not so strict but it checks the format which is the most important thing.

Comments

4

Instead of using a regex, I suggest using a library called yup.

You can use as as follows:

import * as Yup from 'yup';

// here you can add multiple validations per field
const EmailSchema = Yup.object().shape({
  email: Yup.string().required('This field is mandatory').email('Enter a valid email'),
});

Inside your

{<Formik
  initialValues={this.state.form}
  validationSchema={EmailSchema}
  onSubmit={ values => {
    const data = {
      email: values.email
    };
  }}
>
{({handleSubmit, handleChange, values, touched, errors, isSubmitting}) => (
  <form onSubmit={handleSubmit} autoComplete="off" noValidate>
    <div className="form-group">
      <label htmlFor="id_email">Email <span>*</span></label>
      <input
        type="email"
        name="email"
        id="id_email"
        className={((errors.email && touched.email) ? 'is-invalid ' : '') + 'form-control'}
        autoComplete="off"
        value={values.email}
        onChange={handleChange}
      />
      {errors.email && touched.email && <div className="invalid-feedback">{errors.email}</div>}
    </div>
    <div className="row">
      <div className="col text-right">
        <button type="submit" name="btn-letsgo" disabled={isSubmitting} className="btn btn-primary">Submit</button>
      </div>
    </div>
  </form>
)}
</Formik>}

Comments

4
function isEmail(val) {
    let regEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    if(!regEmail.test(val)){
      return 'Invalid Email';
    }
}

Comments

3

For me its working on most of email id's, hope it helps

  /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/

Comments

2

Try this, quite long but should work on most emails.

^[a-z0-9][\-_\.\+\!\#\$\%\&\'\*\/\=\?\^\`\{\|]{0,1}([a-z0-9][\-_\.\+\!\#\$\%\&\'\*\/\=\?\^\`\{\|]{0,1})*[a-z0-9]@[a-z0-9][-\.]{0,1}([a-z][-\.]{0,1})*[a-z0-9]\.[a-z0-9]{1,}([\.\-]{0,1}[a-z]){0,}[a-z0-9]{0,}$

Comments

1

For me, this regex worked fine:

^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

export const EmailRegex=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

all credits to: Alfred Ayi-bonte

Comments

1

For a simple solution

Here is how my TextField component looks like:

            <TextField
              autoFocus
              defaultValue={user?.email}
              onChange={(e) => onSetValue(e, e.target.value)}
              required={field.required}
              fullWidth
              label={field.title || key}
              variant="outlined"
              inputProps={{
                className: classes.input,
                pattern: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+[.]{1}[a-zA-Z]{2,}$',
              }}
            />

Comments

0
const [email, setEmail] = React.useState("");
const [message, setMessage] = React.useState("");
const emailValidation = () => {
  const regEx = /[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,8}(.[a-z{2,8}])?/g;
  if (regEx.test(email)) {
     setMessage("Valid Email");
     } else if (!regEx.test(email`enter code here`) && email !== "") {
          setMessage("Invalid email");
     } else {
         setMessage("");
     }
}
const handleOnChange = (e)=> {
     setEmail(e.target.value);
}
    <input id="email" className="input" type="email" placeholder="email" value={email} onChange={handleOnChange} />
    <button onClick={emailValidation}>Check</button>
    <p className="message">{message}</p>

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

Try This

pattern: { value: /[a-zA-Z][a-zA-Z0-9]+@(?:[a-zA-Z0-9]+\.)+[A-Za-z]+$/, message: 'Please enter a valid email' },
[a-zA-Z][a-zA-Z0-9]+@(?:[a-zA-Z0-9]+\.)+[A-Za-z]+$/

Comments

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.