Reputation: 131
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
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:
error
class to the existing email fieldvalid
class to the existing email fieldYou 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