Change button styling if element is visible - javascript

I would imagine that this is a very simple code solution to fix but I haven't managed to get it functional.
To give you some perspective, what I currently have done is a form formatting with intl tel input and then I have included the following code(which works great!) inorder to validate the input;
<span id="valid-msg" class="hide">✓Valid number</span>
<span id="error-msg" class="hide"></span>
<style>
.hide {
display: none;
}
#valid-msg {
color: #2b9348;
}
#error-msg {
color: #C31014;
}
<style>
<!--for validation-->
<script>
var input = document.querySelector("#phone"),
errorMsg = document.querySelector("#error-msg"),
validMsg = document.querySelector("#valid-msg");
var updateInputValue = function (event) {
dialCode.value = "+" + iti.getSelectedCountryData().dialCode;
};
input.addEventListener('input', updateInputValue, false);
input.addEventListener('countrychange', updateInputValue, false);
var errorMap = ["Invalid number", "Invalid country code", "Too short", "Too long", "Invalid number"];
var reset = function() {
input.classList.remove("error");
errorMsg.innerHTML = "";
errorMsg.classList.add("hide");
validMsg.classList.add("hide");
};
input.addEventListener('blur', function() {
reset();
if (input.value.trim()) {
if (iti.isValidNumber()) {
validMsg.classList.remove("hide");
} else {
input.classList.add("error");
var errorCode = iti.getValidationError();
errorMsg.innerHTML = errorMap[errorCode];
errorMsg.classList.remove("hide");
}
}
});
input.addEventListener('change', reset);
input.addEventListener('keyup', reset);
</script>
What I'm looking to do is change the style of the submit button if the phone number is valid, I thought this might be done by checking if the #valid-msg span was visible or didn't have a class.
Here is what I have tried:
<script>
document.addEventListener('DOMContentLoaded', () => {
const phoneInput = document.querySelector('#phone');
const validMsg = document.querySelector('#valid-msg');
const targetFormButton = document.querySelector('#form-submit');
if (!phoneInput || !targetFormButton || !validInput) return;
phoneInput.addEventListener('input', () => {
const isValid = validMsg.className !== 'hide';
targetFormButton.classList[isValid ? 'remove' : 'add']('invalid');
targetFormButton.classList[isValid ? 'add' : 'remove']('valid');
});
});
</script> ```
If anyone have suggestions they would be greatly appreciated!

If your validator works correctly, then what you need is a conditional formatting via class toggle:
const btnSubmit = document.querySelector('#form-submit')
const phoneInput = document.getElementById('phone')
const form = document.getElementById('form')
// simplified validation: valid if more
// than 3 characters long
const validator = (val) => {
if (val.length < 3) return false
return true
}
// general function to change classes (add & remove)
// on an element (el)
const validClassToggle = (addClass, removeClass) => (el) => {
el.classList.add(addClass)
el.classList.remove(removeClass)
}
// creating setInvalid & setValid functions
const setInvalid = validClassToggle('invalid', 'valid')
const setValid = validClassToggle('valid', 'invalid')
phoneInput.addEventListener('input', function(e) {
validator(e.target.value) ?
setValid(btnSubmit) :
setInvalid(btnSubmit)
})
form.addEventListener('submit', function(e) {
e.stopPropagation()
e.preventDefault()
if (validator(phoneInput.value)) {
console.log("form submitted")
} else {
console.log("form not submitted")
}
})
.valid {
background-color: green;
color: white;
}
.invalid {
background-color: red;
color: white;
}
<form id="form">
<input id="phone" type="text" /><br />
<button id="form-submit" type="submit">SUBMIT</button>
</form>

Related

Add a blinking effect to single character of array

I am trying to achieve blinking effect to a single character of an array.
For example, if "text" get load inside paragraph <p> tag or container then first character of text should blink and when user types the blinking character in input area blinking effect must move to blink on next character.
I need assistance in solving this problem. Any instructions or help will be so grateful.
Here what I've tried so far:
let displayElem = document.getElementById("me");
const inputElem = document.getElementById("input");
const text = "Hey It's bad day, not a bad life,you'll be okay...!"
text.split('').forEach(char => {
const chrspan = document.createElement('span')
chrspan.innerText = char;
displayElem.appendChild(chrspan);
});
inputElem.addEventListener('input', () => {
var vl = document.getElementById("input").value;
const arrayq = displayElem.querySelectorAll('span')
const arrayv = inputElem.value
let correct = true;
arrayq.forEach((chSpan, index) => {
const char = arrayv[index];
if (char == null) {
correct = false;
} else if (char === chSpan.innerText) {
chSpan.classList.add('blink-bg')
} else {
chSpan.classList.remove('blink-bg')
correct = false
}
})
})
.blink-bg {
text-align: center;
color: #fff;
display: inline-block;
border-radius: 3px;
animation: blinkingBackground 1s infinite;
}
#keyframes blinkingBackground {
from { background-color: #f1ebeb; }
to { background-color: #080808; }
}
<p id="me"></p>
<input id="input" type="input" />
let displayElem = document.getElementById("me");
const inputElem = document.getElementById("input");
const text = "Hey It's bad day, not a bad life,you'll be okay...!"
text.split('').forEach(char => {
const chrspan = document.createElement('span')
chrspan.innerText = char;
displayElem.appendChild(chrspan);
});
inputElem.addEventListener('input', () => {
var vl = document.getElementById("input").value;
const arrayq = displayElem.querySelectorAll('span')
const arrayv = inputElem.value
let correct = true;
arrayq.forEach((chSpan, index) => {
const char = arrayv[index];
if (char == null) {
correct = false;
} else if (char === chSpan.innerText) {
chSpan.classList.add('blink-bg')
// document.getElementById("p_id").innerHTML = chSpan.innerText;
} else {
chSpan.classList.remove('blink-bg')
correct = false
}
})
})
This might be a good starting point for you. I changed a couple things,
I made a helper function $ to grab items from the dom as a personal prefrence.
I created an array of all the spans on the document, making it easier to keep track of which element has the blinking class. I created a helper function to grab what the activeText is from the txtArr instead of checking the text content. This way I can avoid using the rendered screen as a storage area for information, and instead have the screen mirror what is happening in my js.
On input I check the last character entered, and if it is the character that is blinking, I increment increment which span is blinking.
This is meant to be a simple demo of how to accomplish this task, you may want to have different functionality, but hopefully this helps as a starting point!
const $ = str => [...document.querySelectorAll(str)];
let displayElem = $("#me")[0];
const inputElem = $("#input")[0];
const text = "Hey! It's a bad day, not a bad life, you'll be okay...!"
const txtArr = [...text];
const txtSpans = txtArr.map(char => {
const span = document.createElement("span");
span.innerText = char;
return span;
});
let activeIndex = -1;
const activeText = () => txtArr[activeIndex];
function renderSpans() {
displayElem.innerHtml = "";
txtSpans.forEach(span => displayElem.appendChild(span));
};
function updateActive() {
const firstRun = activeIndex == -1;
if (!firstRun)
txtSpans[activeIndex].classList.remove("blink-bg");
activeIndex++;
if (activeIndex == txtSpans.length) return;
txtSpans[activeIndex].classList.add("blink-bg");
}
updateActive();
renderSpans();
inputElem.addEventListener('input', e => {
const val = e.target.value;
if (val == "") return;
const lastChar = val[val.length - 1];
if (lastChar == activeText()) updateActive();
})
.blink-bg {
text-align: center;
color: #fff;
display: inline-block;
border-radius: 3px;
animation: blinkingBackground 1s infinite;
}
#keyframes blinkingBackground {
from { background-color: #f1ebeb; }
to { background-color: #080808; }
}
<p id="me"></p>
<input id="input" type="input" />

change array element value's style

im building a to-do list but cant figure out how to keep my array values that have line-through decoration.
the moment render method is called, the array is built from the start. means that if i delete an li, all other li that have been marked by the checkbox with a line-through, losing the decoration.
what can i do to keep the line-through ?
i tried so far in the markTask method to replace the original value with the value that have line-through on it but it didn't work.
basically what im trying to accomplish is by inserting the value with line-through, to be able to check if this value have the line-through style and after the render to be able to keep the checked checkboxes as checked.
my code so far:
class Todo {
constructor() {
this.input = document.getElementById("input");
this.ul = document.getElementById("ul");
this.form = document.getElementById("form");
this.tasks = [];
this.registerEvent();
}
registerEvent() {
this.form.addEventListener("submit", (event) => {
event.preventDefault();
this.createTask(this.input.value);
this.form.reset();
});
}
createTask(task) {
if (task.trim().length === 0) {
return;
}
this.tasks.push(task);
this.render();
}
deleteTask(task) {
const myTask = task.target;
const parent = myTask.parentNode;
const taskToRemove = parent.childNodes[1].textContent;
const index = this.tasks.indexOf(taskToRemove);
this.tasks.splice(index, 1);
this.render();
}
markTask(task) {
const myTask = task.target;
const parent = myTask.parentNode;
if (myTask.checked) {
parent.style.textDecoration = "line-through";
} else {
parent.style.textDecoration = "none";
}
}
render() {
this.ul.innerHTML = "";
this.tasks.forEach((task) => {
const li = document.createElement("li");
const cb = document.createElement("input");
cb.type = "checkbox";
cb.addEventListener("click", (e) => {
this.markTask(e);
});
li.appendChild(cb);
li.append(document.createTextNode(task));
const btn = document.createElement("button");
li.appendChild(btn);
btn.textContent = "Delete";
btn.classList.add("remove");
btn.addEventListener("click", (e) => {
this.deleteTask(e);
});
this.ul.appendChild(li);
});
}
}
new Todo();
<form id="form">
<input id="input" />
<button id="add">Add</button>
</form>
<ul id="ul">
</ul>
it's because you're not tracking which tasks are done and you're just pushing strings. for your createTask method you need to push an object with a done property to indicate which tasks have been done like so
createTask(task) {
if (task.trim().length === 0) {
return;
}
this.tasks.push({title: task, done: false});
this.render();
}
update your render to account for tasks already done
render() {
this.ul.innerHTML = "";
this.tasks.forEach((task) => {
const li = document.createElement("li");
const cb = document.createElement("input");
cb.type = "checkbox";
cb.addEventListener("click", (e) => {
this.markTask(e);
});
li.appendChild(cb);
li.append(document.createTextNode(task.title));
const btn = document.createElement("button");
li.appendChild(btn);
btn.textContent = "Delete";
btn.classList.add("remove");
btn.addEventListener("click", (e) => {
this.deleteTask(e);
});
this.ul.appendChild(li);
if (task.done) {
cb.checked = true;
li.style.textDecoration = "line-through";
} else {
cb.checked = false;
li.style.textDecoration = "none";
}
});
}
in your constructor update your tasks variable to see this in effect
constructor() {
this.input = document.getElementById("input");
this.ul = document.getElementById("ul");
this.form = document.getElementById("form");
this.tasks = [{title: 'mill', done: true}, {title: 'jus', done: false}];
this.registerEvent();
}
hope you get the general idea. I won't do the entire implementation on markTask as this should be enough to give you a view of what the solution should be. good luck.
If I may, I have revised your code a bit.
The technique you need is event delegation:
any click on a child element is also a click on its parent elements. we plas the event listener on the parent and we see on which child element it occurred.
In your case, this only makes one event listerner for all your 'remove' buttons.
the other idea is not to ignore the DOM, it also keeps the list of tasks, you don't need to keep them in a table in memory, this is redundant.
here is the code: css is also helfull
class Todo
{
constructor()
{
this.form = document.getElementById('todo-form')
this.liste = document.getElementById('todo-list')
this.form.onsubmit = e => this.addTask(e)
this.liste.onclick = e => this.delTask(e)
}
addTask(e)
{
e.preventDefault()
if (this.form.task.value.trim() === '') return
let li = document.createElement('li')
, cb = document.createElement('input')
, sp = document.createElement('span')
, bt = document.createElement('button')
;
cb.type = 'checkbox'
sp.textContent = this.form.task.value
bt.textContent = 'Delete'
bt.className = 'remove'
li.appendChild(cb)
li.appendChild(sp)
li.appendChild(bt)
this.liste.appendChild(li)
this.form.reset()
}
delTask(e)
{
if (!e.target.matches('button.remove')) return // reject others clicks
e.target.closest('li').remove()
}
}
new Todo();
#todo-list li > span {
display : inline-block;
background-color : whitesmoke;
width : 20em;
}
#todo-list li input[type=checkbox]:checked + span {
text-decoration : line-through;
}
#todo-list li button.remove {
font-size: .6em;
}
<form id="todo-form">
<input name="task">
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
As you can see this code is shorter. You can also use a IIFE unstead of a class, like that :
(function() // IIFE
{
let form = document.getElementById('todo-form')
, liste = document.getElementById('todo-list')
;
form.onsubmit = e => // addTask
{
e.preventDefault()
if (form.task.value.trim() === '') return
let li = document.createElement('li')
, cb = document.createElement('input')
, sp = document.createElement('span')
, bt = document.createElement('button')
;
cb.type = 'checkbox'
sp.textContent = form.task.value
bt.textContent = 'Delete'
bt.className = 'remove'
li.appendChild(cb)
li.appendChild(sp)
li.appendChild(bt)
liste.appendChild(li)
form.reset()
}
liste.onclick = e => // delTask
{
if (!e.target.matches('button.remove')) return // reject others clicks
e.target.closest('li').remove()
}
}
)()
btTaskList.onclick = e =>
{
let tasks = [...document.querySelectorAll('#todo-list li')].map(li=>
{
let val = li.querySelector('span').textContent
, chk = li.querySelector('input[type=checkbox]').checked
;
return {val,chk}
})
console.clear()
console.log( tasks )
}
#todo-list li > span {
display : inline-block;
background-color : whitesmoke;
width : 20em;
}
#todo-list li input[type=checkbox]:checked + span {
text-decoration : line-through;
}
#todo-list li button.remove {
font-size: .6em;
}
<form id="todo-form">
<input name="task">
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
<button id="btTaskList">get task list</button>
I also added a get task list button...
After marking an element you are changing only the stayle and atrribute of element. But after delete you recreate with render whole list and in render you are not rendereing checked parameter.
Your render should be:
render() {
this.ul.innerHTML = "";
this.tasks.forEach((task) => {
const li = document.createElement("li");
const cb = document.createElement("input");
cb.type = "checkbox";
cb.addEventListener("click", (e) => {
this.markTask(e);
});
li.appendChild(cb);
// missed rendering checked
if (task.checked) {
li.style.textDecoration = "line-through";
cb.checked = 'checked';
}
li.append(document.createTextNode(task));
const btn = document.createElement("button");
li.appendChild(btn);
btn.textContent = "Delete";
btn.classList.add("remove");
btn.addEventListener("click", (e) => {
this.deleteTask(e);
});
this.ul.appendChild(li);
});
}

javascript add and remove className, keep setting

I want to make a button for night and day mode.I found this link but it doesn't work for me.
when i click the button, it applies css to change background and text color and button value which is night to day but if i click button again it doesn't work. it keeps execute "if" part not "else" part.
//nightmode
var mode = localStorage.getItem("mode");
if (mode != null) {
document.getElementById("body").classList.add(mode);
}
document.getElementById("nightButton").onclick = function() {
var nightButton = document.getElementById("nightButton")
var body = document.getElementById("body");
if (nightButton.value = "night") {
body.classList.add("nightMode");
nightButton.value = "day";
localStorage.setItem('mode', 'nightMode');
} else {
body.classList.remove("nightMode");
nightButton.value = "night";
localStorage.setItem("mode", null);
}
};
.nightMode {
background-color: black;
color: white;
}
<body id="body">
<input type="button" value="night" id="nightButton">
<div>abcd</div>
</body>
Just change the line
if (nightButton.value = "night") {
to
if (nightButton.value == "night") {
You can simplify the mode button handler. This snippet including handling of localStorage (can't be used in SO-snippets) can be found #JsFiddle
document.addEventListener("click", evt => {
if (evt.target.id === "nightButton") {
const body = document.body;
body.classList.toggle("nightMode");
evt.target.value = `set ${
body.classList.contains("nightMode") ? "day" : "night"}`;
document.querySelector("#currentMode").textContent = `Current mode: ${
body.classList.contains("nightMode") ? "NIGHT" : "DAY"}`;
}
});
.nightMode {
background-color: black;
color: white;
}
body {
margin: 2rem;
}
#currentMode {
margin-top: 1rem;
}
<div>abcd
<input type="button" value="set night" id="nightButton">
</div>
<div id="currentMode"></div>
there is a little error in your code.
This code: if (nightButton.value = "night") {
Can you change it: if (nightButton.value == "night") {
Example here: https://codepen.io/yasgo/pen/OJRLErL
thank you all
I don't know if this is good codes but i tried this and it works ...
var mode = localStorage.getItem("mode");
document.getElementById("body").classList.add(mode);
if (mode == "nightMode") {
document.getElementById("nightButton").value = "day"
} else {
document.getElementById("nightButton").value = "night"
}
document.getElementById("nightButton").onclick = function () {
var nightButton = document.getElementById("nightButton")
var body = document.getElementById("body");
if (nightButton.value == "night") {
body.classList.add("nightMode");
nightButton.value = "day";
localStorage.setItem('mode', 'nightMode');
} else {
body.classList.remove("nightMode");
nightButton.value = "night";
localStorage.setItem("mode", "daymode");
}
};

Javascript display div only once

So I have a calculator with an error message that displays, if they press the "calculate" button if the input is NaN. The error message keeps getting created everytime the user presses calculate. How do i make it so it only shows even after pressing "calculate" multiple times?
function displayErr() {
const formBox = document.querySelector("form");
const errorBox = document.createElement("div");
errorBox.className = "errorBox";
const errorText = document.createTextNode("Those are not numbers!");
errorBox.appendChild(errorText);
formBox.appendChild(errorBox);
}
if ((isNaN(billInput)) || (isNaN(peopleAmount)) || (billInput === "") || (peopleAmount === "")) {
displayErr();
}
The most straightforward way is to check if the element already exists.
function displayErr() {
// Get error element
const errorElement = document.getElementsByClassName('errorBox');
// If it already exists
if (errorElement && errorElement.length > 0) {
// Dont add another one
return;
}
// Add new errorBox
const formBox = document.querySelector("form");
const errorBox = document.createElement("div");
errorBox.className = "errorBox";
const errorText = document.createTextNode("Those are not numbers!");
errorBox.appendChild(errorText);
formBox.appendChild(errorBox);
}
Another option would to be using css classes to 'hide' the element;
Always render the element, but hide it with display: none
In the displayErr(), make the element visible with something like document.getElementsByClassName('errorBox')[0].style.display = block;
a better way of doing this is
to show and hide the element using CSS classes
create the element and hide it using
display: none;
and show it by adding a class to the element
display: block;
const element = document.getElementById("myDIV");
const button = document.getElementById("btn");
button.addEventListener("click", () => element.classList.toggle("show"));
#myDIV {
display: none;
}
.show {
display: block !important;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<button id="btn">Try it</button>
<div id="myDIV">
This is a DIV element.
</div>
</body>
</html>
For what it's worth, here is a pure JavaScript example of a show/hide interpretation:
function CheckInput() {
const billInput = document.getElementById("b").value;
const peopleAmount = document.getElementById("p").value;
if ((isNaN(billInput)) || (isNaN(peopleAmount)) || (billInput === "") || (peopleAmount === "")) {
showErr();
}
else{
hideErr();
}
}
function hideErr(){
console.log("hide");
const el = document.getElementById("error");
el.style.display = "none";
}
function showErr(){
console.log("show");
const el = document.getElementById("error");
el.style.display = "block";
el.innerHTML = "Hey sorry wrong input";
}
window.onload = function() {
hideErr();
}
You can see the HTML and try the code here: https://jsfiddle.net/0mrx5ev7/
You can pass a parameter to your displayErr function, then use it to set the hidden HTML attribute and textContent of a single target div, identified by its HTML id.
This way, the functionality becomes reusable, and you can set/unset the error message whenever you need.
const input = document.querySelector('#input')
const errDisplay = document.querySelector('#err-display')
function displayErr(msg) {
errDisplay.textContent = msg || ''
errDisplay.hidden = msg ? null : 'hidden'
}
input.addEventListener('input', () => {
displayErr(isNaN(input.value) ? "Not a number" : null)
})
#err-display {
font-family: sans-serif;
background: red;
color: white;
margin: .5em 0;
padding: .5em;
}
<input id='input' placeholder='Start typing'>
<div id='err-display' hidden></div>
try to use a counter. like if int i == 0 --> do the function. i would do so
int i = 0;
function displayErr() {
const formBox = document.querySelector("form");
const errorBox = document.createElement("div");
errorBox.className = "errorBox";
const errorText = document.createTextNode("Those are not numbers!");
errorBox.appendChild(errorText);
formBox.appendChild(errorBox);
}
if ((isNaN(billInput)) && i == 0 || (isNaN(peopleAmount)) && i == 0 ||
(billInput === "") && i == 0 || (peopleAmount === "") && i == 0)
{
displayErr();
i += 1;
}
now it will display an error only once, because i is never going to be 0 anymore

JS: How to enable submit button in form only if all inputs pass validation

I have a simple input that I'm using an keyup event listener on. If the input length is too short, the span element will remove the class on it that hides the element and display "Input too short".
If I have multiple inputs, how can I only enable the Submit button if all fields pass the validation.
Unfortunately, I'm thinking in a React-way and would accomplish this via state.
<style type="text/css">
.hide-first {
display: none;
}
.hide-last {
display: none;
}
</style>
<div>
<div>
<input id="first-name" />
<span id="validation-span" class="hide-first">Input too short</span>
</div>
<button>Submit</button>
</div>
<script type="text/javascript">
let firstName = document.getElementById( 'first-name' );
let span = document.getElementById( 'validation-span' );
firstName.addEventListener( 'keyup', () => {
console.log( event.target.value.length )
if ( event.target.value.length < 5 ) {
span.classList.remove( 'hide-first' )
} else {
span.classList.add( 'hide-first' )
}
} );
</script>
All your inputs could call the same validation function that checks everything except inputs that are empty. Only show the submit button if they all succeed and show the appropriate message on inputs that fail the validation.
Pseudo-code:
boolean succes = true
if username is invalid and not empty
username invalid message
success = false
if password is invalid and not empty
password invalid message
success = false
if success is true
show submit button
At first add style your button style="display:none". You can use jQuery as bellow
$( document ).ready( function () {
var _rules = {
"first-name": function ( $owner ) {
var val = $owner.val();
if ( !val ) return false;
if ( val.length < 5 ) return false;
return true;
}
};
//Validate here
function validate(total_mark) {
var mark = 0;//total mark
//Read all input value, than check rules
$( 'input' ).each( function () {
if ( 'function' !== typeof ( _rules[this.id] ) ) return;
var $owner = $( this );
var result = _rules[this.id]( $owner );
if ( !result ) {
mark -= 1;
$owner.next().removeClass( 'hide-first' );
return;
}
$owner.next().addClass( 'hide-first' );
mark += 1;
return;
} );
return mark;
};
var $btn = $( 'button' );
//Register keyup event for all input
var total_input = 1;
$( 'input' ).on( "keyup", function ( e ) {
e.preventDefault();
$btn.css( "display", "none" );
if ( validate() < total_input ) return;
$btn.css( "display", "" );
} );
} );
Something like this should work
<div>
<div>
<input id="first-name" onchange='validation()'/>
<span id ="validation-span" class="hide-first">Input too short</span>
</div>
<button id='submit-button'>
Submit
</button>
</div>
<script type="text/javascript">
function validateFirstName() {
let firstName = document.getElementById('first-name');
let span = document.getElementById('validation-span');
if (event.target.value.length < 5) {
span.classList.remove('hide-first')
return True
}
span.classList.add('hide-first')
return False
}
function validation() {
let submitButton = document.getElementById('submit-button');
submitButton.disabled = validateFirstName();
}
</script>
As you add additional fields, you should create the validation function for that field, and then running it inside validation() like:
function validation() {
let submitButton = document.getElementById('submit-button');
submitButton.disabled = validateFirstName() && validateSecondField() && validateThirdField() &&...;
}
Remember to add to the html input the onchange event listener.
Simple logic. Make a function that checks if all of the fields are validated, and call it from within the onkeyup event. A seemingly straight-forward way would be like this:
let firstName = document.getElementById('first-name'),
lastName = document.getElementById('last-name'),
company = document.getElementById('company-name');
let span = document.getElementById('validation-span'),
span1 = document.getElementById('validation-span1'),
span2 = document.getElementById('validation-span2'),
conditions = [],
length = 3;
firstName.addEventListener('keyup', () => {
console.log(event.target.value.length)
if (event.target.value.length < 5) {
span.classList.remove('hide-first')
conditions[0] = true;
} else {
span.classList.add('hide-first')
conditions[0] = false;
}
})
lastName.addEventListener('keyup', () => {
console.log(event.target.value.length)
if (event.target.value.length < 5) {
span1.classList.remove('hide-first')
conditions[1] = true;
} else {
span1.classList.add('hide-first')
conditions[1] = false;
}
})
company.addEventListener('keyup', () => {
console.log(event.target.value.length)
if (event.target.value.length < 5) {
span2.classList.remove('hide-first')
conditions[2] = true;
} else {
span2.classList.add('hide-first')
conditions[2] = false;
}
})
function checkAllTrueAndActivateSubmitBtn() {
var result = true;
for(var i = 0; i < length; i++) {
if(!conditions[i]) {
result = false;
}
}
if(result) {
submitBtn.classList.add("shown"); //or whatever
}
}
but of course, the more fields you have,the more messy this becomes. A more efficient way would be to use an array for the fields, and conditions:
let IDsAndConditions = {
'first-name':{
condition: (x) => x.length >= 5,
span: 'validation-span'
},
'last-name': {
condition: (x) => x.length >= 8,
span: 'validation-span-lastName'
},
'phoneNumber':{
condition: (x) => x.match(/^-{0,1}\d+$/),//or whatever
span:"phone-span"
}
};
var conditions = [];
var num = 0;
for(var k in IDsAndConditions) {
var cur = IDsAndConditions[k];
var el = document.getElementById(k);
var span = document.getElementById(cur["span"]);
if(el && span) {
el.addEventListener('keyup', () => {
console.log(event.target.value.length)
if (!cur["condition"](event.target.value)) {
span.classList.remove('hide-first')
conditions[num] = true;
} else {
span.classList.add('hide-first')
conditions[num] = false;
}
checkAllTrueAndActivateSubmitBtn();
});
} else {
conditions[num] = true; //this is to make the validation work even if the element doesn't exist
}
num++;
}
function checkAllTrueAndActivateSubmitBtn() {
var result = true;
for(var i = 0; i < IDsAndConditions.length; i++) {
if(!conditions[i]) {
result = false;
}
}
if(result) {
submitBtn.classList.add("active"); //or whatever
} else {
submitBtn.classList.remove("active"); //even if it was active at one point, if someone changes a field to an incorrect value, it deactivates again
}
}

Categories