I am trying to develop a full screen search field and would like the orange "search" button to close the overlay only if all inputs are valid.
Each input has a limit of 2 digits, only numbers and between 1 and 20.
Everything works fine except the "search" button closes the overlay when the last input is valid even if the first 2 inputs are left blank (error)….
Is there any conflict or is the script wrong?
$(function() {
$('a[href="#search"]').on("click", function(event) {
event.preventDefault();
$("#search").addClass("open");
$('#search > form > input[type="search"]').focus();
});
$("#search, #search button.close").on("click keyup", function(event) {
if (
event.target == this ||
event.target.className == "close" ||
event.keyCode == 27
) {
$(this).removeClass("open");
}
});
$(".send_btn").submit(function(event) {
event.preventDefault();
return false;
});
});
// validation input - error if not..
function handleChange(input) {
if (input.value < 0) input.value = "";
else if (input.value < 0.9 || input.value > 20 || input.value.length === 1 || input.value.length === 0) {
input.style.borderColor = 'red';
} else {
input.style.borderColor = '';
}
}
$('input').keypress(function(event) {
event = event || window.event;
var charCode = event.which || event.keyCode;
var charStr = String.fromCharCode(charCode);
if (event.key !== undefined && event.charCode === 0) {
return;
}
if (!/^([0-9])*$/.test(charStr)) {
event.preventDefault();
}
if (!/^[a-zA-Z0-9]+$/.test(charStr)) {
event.preventDefault();
}
});
// If input is empty Send Button Click - error - no action
$('.send_btn').click(function() {
$("input.each_item").each(function() {
if (this.value.trim().length === 0 || this.value.trim().length === 1 || this.value > 20)
$(this).css('border-color', 'red') &&
$('#search').addClass('open') &&
$('html').addClass("noScrollSimple");
else
$(this).css('border-color', '') &&
$('#search').removeClass('open') &&
$('html').removeClass("noScrollSimple");
});
});
html {
overflow-y: scroll;
}
body {
margin: 0px;
font-weight: 400;
font-size: 12px;
-webkit-font-smoothing: antialiased;
width: 100%;
min-width: auto;
background: #ebebeb;
padding: 50px;
}
.button {
width: 250px;
height: 50px;
color: #ebebeb;
background-color: cornflowerblue;
margin: 0 auto;
text-align: center;
font-size: 2.3em;
margin-top: 50px;
font-size: 2.3em;
cursor: pointer;
}
.input_cont {
display: inline-block;
width: 100%;
margin: 0px auto;
text-align: center;
max-width: 1250px;
}
.items {
display: flex;
flex: 1;
padding: 0px 20px 0px;
}
.each_item {
width: 100px;
height: 100px;
min-width: 100px;
min-height: 100px;
line-height: 2.75em;
margin: 0px auto;
display: table-cell;
float: left;
font-weight: bold;
color: #ebebeb;
font-size: 2.3em;
background: rgba(0, 0, 0, .6);
text-align: center;
-webkit-appearance: none;
}
#search {
position: fixed;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: rgba(50, 50, 50, .9);
-webkit-transform: translate(-50%, -50%) scale(0, 0);
-moz-transform: translate(-50%, -50%) scale(0, 0);
-o-transform: translate(-50%, -50%) scale(0, 0);
-ms-transform: translate(-50%, -50%) scale(0, 0);
transform: translate(-50%, -50%) scale(0, 0);
opacity: 0;
}
#search input[type=search] {
color: #ebebeb;
background: rgba(0, 0, 0, 0);
font-weight: 300;
text-align: center;
border: 0px;
margin: 0px auto;
margin-top: -51px;
padding-left: 30px;
padding-right: 30px;
outline: none;
}
#search .btn {
background: chocolate;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
border: 0px solid transparent;
}
#search .close {
position: fixed;
top: 15px;
right: 15px;
opacity: 1;
width: 50px;
height: 50px;
}
#search .close:after {
content: '';
height: 45px;
border-left: 5px solid #ebebeb;
position: absolute;
transform: rotate(45deg);
left: 28px;
}
#search .close:before {
content: '';
height: 45px;
border-left: 5px solid #ebebeb;
position: absolute;
transform: rotate(-45deg);
left: 28px;
}
#search.open {
-webkit-transform: translate(-50%, -50%) scale(1, 1);
-moz-transform: translate(-50%, -50%) scale(1, 1);
-o-transform: translate(-50%, -50%) scale(1, 1);
-ms-transform: translate(-50%, -50%) scale(1, 1);
transform: translate(-50%, -50%) scale(1, 1);
opacity: 1;
}
#search,
#search.open {
-webkit-transition: all .35s;
-moz-transition: all .35s;
-ms-transition: all .35s;
-o-transition: all .35s;
transition: all .35s;
transition-property: initial;
transition-duration: 0.35s;
transition-timing-function: initial;
transition-delay: initial;
}
.search__input {
width: 100%;
height: 100%;
background: transparent;
outline: none;
color: #ebebeb;
transition: opacity 0s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#search">
<div class="button">
Search</div>
</a>
<div id="search">
<div type="button" class="close"></div>
<div class="input_cont">
<div class="items">
<input name="num" type="text" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
<input name="num" type="text" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
<input name="num" type="text" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
</div>
</div>
<button type="submit" class="button btn btn-primary send_btn">Search</button>
</div>
2
Answers
You are running the function for each input field, so when the last one is valid it would hide the overlay – which is what happens. Create a new variable outside the loop and use it to keep track if any of the input fields were invalid, then after the loop use the value to hide the element as needed.
First, the problem is because of you are checking the value one by one. So, in the end the last input’s value is taking effect. And you should not add
type="text"
and then check if the input doesn’t contains anything other than numbers. It is completely unnecessary, just addtype="number"
to all inputs and it will only allow numberical inputs. Most of the code is just doing double checks and same thing again and again.I’ve cleaned up the unnecessary parts and now it is working very good like you wanted –
Here’s the code