user_1234
user_1234

Reputation: 131

Validate multiple input type="email" using Javascript

I have one form which contain multiple email field so this email to be submitted in database but before that it should validate to avoid duplication, (multiple email fields generated by click on add more button which is present in form ).

I have written ValidateEmail script to avoid duplication however it will work for only one email field but not successfull for multiple email field.

issue: 1) if we type email id in first field it will go for validation and check email exist or not if exist disable submit button if not exist enable button.

2) if we type type email id in second field and after validation it return email not exist then it will enable submit button however in first email field contain duplicate email.

3) if all email fields not contain duplicate values then only enable submit button else it should remain disabled..

<form>
<div>
<input type="email" name="email[]" class="email" onblur="validate_email(this)" />   // initially single filed

// This additional email fields created when click on add more button 

<input type="email" name="email[]" class="email" onblur="validate_email(this)" /> 
<input type="email" name="email[]" class="email" onblur="validate_email(this)" />
<input type="email" name="email[]" class="email" onblur="validate_email(this)" />
</div>

<button class="add_more">Add more</button>   // this will append extra email fileds
</form>

<script>
// This is the script it will check whether email already exist or not
function ValidateEmail(data) {
        var email_id = data.value;
        $.ajax({
            type: "POST",
            url: "<?= base_url('controller') ?>",
            data:{
               email_id:email_id 
            },
            dataType: 'json',
            success: function (response) {
                if(response.exist){
                       // disable submit button and show error

                    }
                     else{
                      //enable submit field and hide error

                        }
            },
            error: function (jqXHR, textStatus, errorMessage) {
                console.log(errorMessage); // Optional
            }
        });
    }

</script>

Upvotes: 1

Views: 2547

Answers (1)

Duc Hong
Duc Hong

Reputation: 1179

If you're using jQuery for this, you can use event delegation for dynamic inserted/removed element. As of now, those will be the email inputs.

Basically the idea here is:

  • Get the value of last changed/onblur input element.
  • Validate for existing email on server side (asynchronous check)
  • Scan through the current available email inputs, then validate and match each value with the Current Email in step (1).
  • If found, add a error class to the existing email field
  • Otherwise, add a valid class to the existing email field

You dont need to pass onblur="validate_email(this)" , this can be done in jquery.

const data = [
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
]

function isEmail(email) {
  // eslint-disable-next-line no-useless-escape
  return RegExp(/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i).test(email);
};

function asyncEmailValidate(email) {
  return new Promise(function(resolve, reject) {
    if (data.includes(email))
       return reject('Found duplicated')
    
    return resolve(true);
  })
}

$(document).ready(function() {
  $(document)
    .on('blur',"input.email", function(e) {
      // Current email input
      var currentEmail = e.target.value,
          $emailNode = $(this),
          isValid = true;
    
      // Validate email
      if (!isEmail(currentEmail))
        return;
    
      // Validate email on server side first,
      // If found no existing email, then check 
      // siblings email for duplicates
      var serverResult = asyncEmailValidate(currentEmail);
      
      serverResult
        .then(function(result) {
          // There's no existing email with the inputed email. Now
          // look up on other available email inputs fields, except
          // the current one, and validate with the current email value
          var siblingsEmailInputs = $("input.email").not($emailNode);

          if (!siblingsEmailInputs)
            return;

          if (siblingsEmailInputs.length > 0) {
            siblingsEmailInputs.each(function(index) {
              console.log('input : ', $(this).val())
              
              if ($(this).val() !== "" && $(this).val() === currentEmail) {
                 isValid = false;
              }
            });
          }
          
          // Finally update the state for the current field
          if (isValid) {
            $emailNode.addClass('is-valid');
          } else $emailNode.addClass('is-error');
        })
        .catch(function(error) {
          $emailNode.addClass('is-error');
          console.log('error:', error);
        })
    });
  
})
.email.is-error {
   border: 1px solid red;
}

.email.is-valid {
  border: 1px solid green;
}

.email {
  width: 300px;
  margin: 5px;
  height: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<pre>
const data = [
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
  '[email protected]',
]
</pre>

<div>
<input type="email" name="email[]" class="email" /> 
</div>
  <div>
    <input type="email" name="email[]" class="email" /> 
</div>
    <div> 
      <input type="email" name="email[]" class="email" />
</div>
<div>
<input type="email" name="email[]" class="email" />
</div>

Those are just the basic way for you to handle email validation and duplicated emails. I think you can take it from here to work on your submit logic.

One quick note, you should leave the ajax submitting process in a separate function, not mixing up with validation process, it will be clearer.

Hope this help

Link working sample: https://codepen.io/DieByMacro/pen/jOOdWMr

Updated: - I haven't used ajax with jQuery for a while so I'm not sure about the correct syntax, so I've replaced it with a Promised call which works the same as you make an asynchronous request. You can follow the updated version for your reference.

Upvotes: 1

Related Questions