20

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;
Max T
  • 1,365
  • 4
  • 23
  • 38

11 Answers11

36

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.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Try with a RegExp constructor. – Wiktor Stribiżew Dec 27 '16 at 16:48
  • figured it out - it was just missing ) in the end :) – Max T Dec 27 '16 at 16:55
  • 1
    I see, I focused on the parentheses around `test` and missed the one for the if condition, fixed. – Wiktor Stribiżew Dec 27 '16 at 17:01
  • 1
    @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 `xxx@xxxxxx.xxx` like emails. For emails like yours, you may use `/^[a-zA-Z0-9]+@(?:[a-zA-Z0-9]+\.)+[A-Za-z]+$/` – Wiktor Stribiżew Sep 13 '18 at 13:21
  • @WiktorStribiżew Thanks for the reply, and yeah I know. The email pattern is quite tricky actually, there are emails like `as.df@abc.com.au` :-/ – MewX Sep 13 '18 at 13:31
  • @MahiGunjal You have other requirements, you might want to use [`^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@(?:[a-zA-Z0-9]+\.)+[A-Za-z]+$`](https://regex101.com/r/007EIj/1). Or, follow the link in the answer. – Wiktor Stribiżew May 26 '20 at 11:03
  • @wiktorstribizew thanks for reply, you are right. its working.. :) – Chandler Bing May 26 '20 at 11:09
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.

tw_hoff
  • 390
  • 3
  • 8
7

Maybe not perfect, customized @tw_hoff's post.

/.+@.+\.[A-Za-z]+$/.test("rr@rr.com.tr") //true
/.+@.+\.[A-Za-z]+$/.test("rr@rr.co.tr2") //false
7urkm3n
  • 6,054
  • 4
  • 29
  • 46
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>}
lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228
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';
    }
}
Abdessabour Mtk
  • 3,895
  • 2
  • 14
  • 21
3

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

  /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/
Chandler Bing
  • 293
  • 4
  • 18
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,}$
JaZ
  • 21
  • 1
  • 2
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

collinsmarra
  • 148
  • 1
  • 7
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,}$',
              }}
            />
Oded BD
  • 2,788
  • 27
  • 30
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
    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](/help/how-to-answer). – Community Jun 02 '22 at 13:25
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]+$/
Merrin K
  • 1,602
  • 1
  • 16
  • 27