Reputation: 54
I want to show the error message of required if mandatory fields are left blank. I implement it using the following way but every time the function checkinput() is invoked it adds a new span element due to which "required" message is outputted multiple times. I want the span element to be added once and disappears when user fills in the requirement. Here is my code.
const checkinput=(event)=>{
if(event.target.value===""){
event.target.insertAdjacentHTML('afterend','<span class="text-danger">Required</span>')
}
if(event.target.value!==""){
var child=document.querySelector('span');
child.remove();
}
}
document.getElementById("username").addEventListener('blur',checkinput);
document.getElementById("password").addEventListener('blur',checkinput);
document.getElementById("confirmPassword").addEventListener('blur',checkinput);
Upvotes: 1
Views: 2462
Reputation: 129
<style>
.errorMsg {
border: 1px solid red;
}
.err {
color: red;
}
</style>
<form>
<input type="text" name="name" id="name">
<input type="password" name="password" id="password">
<button id="submit" type="submit">Submit</button>
</form>
<script>
let nameTag = document.querySelector('#name');
let passwordTag = document.querySelector('#password');
let submitBtn = document.querySelector('#submit');
nameTag.addEventListener('blur', e => validation(e));
passwordTag.addEventListener('blur', e => validation(e));
function validation(e) {
if (e.target.value == '') {
e.target.classList.add('errorMsg')
submitBtn.setAttribute('disabled', true) // Disable submit that user cannot submit
e.target.insertAdjacentHTML('afterend', `<span class="err ${e.target.id}">It is required</span>`)
// In the above line we are inserting an element with class same as id of input that in the remove we remove a particular error message only
} else {
e.target.classList.remove('errorMsg')
submitBtn.removeAttribute('disabled')
document.querySelector(`.err.${e.target.id}`).remove();
//Here code is saying that the element with if 'err' and 'class same as id of input' if both class present then remove it
}
}
</script>
Upvotes: 0
Reputation: 29281
Reason why new span
element is added each time you have a empty input field is because you are calling insertAdjacentHTML
each time and inserting a new span
element.
What you should do is add span
elements with each input field in the html and initially they should be empty.When you want to validate the input fields, if any of the input is empty, select the span
element next to that input element and show the error message in that span
element using .textContent
property. To clear the error message, you just need to set .textContent
of the span
element to an empty string.
Following code snippets show different ways of validating form inputs.
Following code snippet validates form inputs when form is submitted.
const form = document.querySelector('form');
const usernameError = document.querySelector('#usernameError');
const passwordError = document.querySelector('#passwordError');
form.addEventListener('submit', (event) => {
event.preventDefault();
const usernameValid = validateField(form, 'username', usernameError);
const passwordValid = validateField(form, 'password', passwordError);
if (usernameValid && passwordValid) {
console.log('form submitted');
form.reset();
}
});
function validateField(form, fieldName, errorEl) {
if (form.elements[fieldName].value == '') {
errorEl.textContent = `${fieldName} is required`;
return false;
} else {
errorEl.textContent = '';
return true;
}
}
form div {
margin: 0 0 10px;
display: flex;
flex-direction: column;
max-width: 200px;
}
form label { margin: 0 0 5px; }
span { color: red; }
<form>
<div>
<label>Username</label>
<input type="text" name="username" />
<span id="usernameError"></span>
</div>
<div>
<label>Password</label>
<input type="password" name="password" />
<span id="passwordError"></span>
</div>
<button>Submit</button>
</form>
Following code snippet validates form inputs when any of the input looses focus.
const form = document.querySelector('form');
const inputsContainer = document.getElementById('formInputsContainer');
const submitBtn = document.querySelector('button');
form.addEventListener('submit', (event) => {
event.preventDefault();
const usernameValid = validateField(form, 'username');
const passwordValid = validateField(form, 'password');
if (usernameValid && passwordValid) {
console.log('form submitted');
form.reset();
}
});
submitBtn.addEventListener('focus', () => {
form.requestSubmit();
});
inputsContainer.addEventListener('focusout', (event) => {
validateField(form, event.target.name);
});
function validateField(form, fieldName) {
const errorEl = document.getElementById(`${fieldName}Error`);
if (form.elements[fieldName].value == '') {
errorEl.textContent = `${fieldName} is required`;
return false;
} else {
errorEl.textContent = '';
return true;
}
}
form div {
margin: 0 0 10px;
display: flex;
flex-direction: column;
max-width: 200px;
}
form label { margin: 0 0 5px; }
span { color: red; }
<form>
<div id="formInputsContainer">
<div>
<label>Username</label>
<input type="text" name="username" />
<span id="usernameError"></span>
</div>
<div>
<label>Password</label>
<input type="password" name="password" />
<span id="passwordError"></span>
</div>
</div>
<button>Submit</button>
</form>
Following code snippet validates form input as user types in any input field.
const form = document.querySelector('form');
const inputsContainer = document.getElementById('formInputsContainer');
form.addEventListener('submit', (event) => {
event.preventDefault();
const usernameValid = validateField(form, 'username');
const passwordValid = validateField(form, 'password');
if (usernameValid && passwordValid) {
console.log('form submitted');
form.reset();
}
});
inputsContainer.addEventListener('input', (event) => {
validateField(form, event.target.name);
});
function validateField(form, fieldName) {
const errorEl = document.getElementById(`${fieldName}Error`);
if (form.elements[fieldName].value == '') {
errorEl.textContent = `${fieldName} is required`;
return false;
} else {
errorEl.textContent = '';
return true;
}
}
form div {
margin: 0 0 10px;
display: flex;
flex-direction: column;
max-width: 200px;
}
form label { margin: 0 0 5px; }
span { color: red; }
<form>
<div id="formInputsContainer">
<div>
<label>Username</label>
<input type="text" name="username" />
<span id="usernameError"></span>
</div>
<div>
<label>Password</label>
<input type="password" name="password" />
<span id="passwordError"></span>
</div>
</div>
<button>Submit</button>
</form>
Upvotes: 2
Reputation: 5603
You can use this code which create a span which is add to the DOM with the ID
which is based on the form element'sname attribute. And that element can be refered to based on the ID which was attach to it before It's been add to the DOM
const checkinput=(event)=>{
if(event.target.value===""){
let spanId = `input-${event.target.name}`
let span = `<span id="${spanId}" class="text-danger">Required</span>`
setTimeout(() =>{
document.getElementById(spanId).remove();
}, 5000);
event.target.insertAdjacentHTML('afterend',span)
}
}
document.getElementById("username").addEventListener('blur',checkinput);
document.getElementById("password").addEventListener('blur',checkinput);
document.getElementById("confirmPassword").addEventListener('blur',checkinput);
<form>
<input type="text" name="username" id="username"/>
<input type="text" name="password" id="password"/>
<input type="text" name="confirmPassword" id="confirmPassword"/>
</form>
Upvotes: 0
Reputation: 6888
You need something like
if(event.target.value==="" && document.querySelector('span') === null){
event.target.insertAdjacentHTML('afterend','<span class="text-danger">Required</span>')
}
if(event.target.value!==""){
var child=document.querySelector('span');
child.remove();
}
You only want to add a span IF the value is an empty string AND the span hsan't been added yet.
Upvotes: 1