Check that after all inputs have value make button active - javascript

I want to remove the disabled attribute from the button when each field is filled out.
My code works when a single input is filled.
What am i doing wrong here?
Here are the HTML and JS
checkInput()
function checkInput() {
let input = document.querySelectorAll('.form-control')
const button = document.querySelector('.submit-btn')
input.forEach(function (e) {
let disabled = true;
e.addEventListener('keyup', function () {
if (e.value !== '') {
disabled = false
} else {
disabled = true
return false
}
if(disabled) {
button.setAttribute('disabled', 'disabled')
} else {
button.removeAttribute('disabled')
}
})
})
}
<div class="form-group">
<label for="name">Name*</label>
<input class="form-control" type="text" id="name" placeholder="Name">
</div>
<div class="form-group">
<label for="lastName">lastName*</label>
<input class="form-control" type="text" id="lastName" placeholder="lastName">
</div>
<div class="form-group">
<label for="fiscalCode">fiscalCode*</label>
<input class="form-control" type="text" id="fiscalCode" placeholder="fiscalCode">
</div>
<button type="submit" disabled="disabled" class="submit-btn">Continue</button>

It does not work because you want to have all inputs affect the state of a button, yet you only check one variable for adding/removing disabled property.
Here is a working code snippet with an example where i created an array of properties, one for each input, that i can refer to in every fired key up event
checkInput()
function checkInput() {
let input = document.querySelectorAll('.form-control')
const button = document.querySelector('.submit-btn')
const disabled = Array(input.length).fill(true);
input.forEach(function (e, index) {
e.addEventListener('input', function () {
disabled[index] = e.value === ''; // simplified if/else statement of yours
if(disabled.some(Boolean)) {
button.setAttribute('disabled', 'disabled')
} else {
button.removeAttribute('disabled')
}
})
})
}
<div class="form-group">
<label for="name">Name*</label>
<input class="form-control" type="text" id="name" placeholder="Name">
</div>
<div class="form-group">
<label for="lastName">lastName*</label>
<input class="form-control" type="text" id="lastName" placeholder="lastName">
</div>
<div class="form-group">
<label for="fiscalCode">fiscalCode*</label>
<input class="form-control" type="text" id="fiscalCode" placeholder="fiscalCode">
</div>
<button type="submit" disabled="disabled" class="submit-btn">Prosegui</button>
Additionaly stoping the function execution when assigning disabled = true in the first else statement is also a wrong approach, as you most likely want to not only assign the disable value, but also the disabled property of the button.
EDIT: as mentioned in the comment by CID it is reasonable to change the event listener to input so we can handle the copying and pasting events as well

You are adding a keyup event for each input field.
that event only checks the current input field if it is empty or not.
it does not check the 3 input fields itself
this should do the trick:
checkInput()
function checkInput() {
let input = document.querySelectorAll('.form-control')
const button = document.querySelector('.submit-btn')
input.forEach(function (e) {
let disabled = true;
e.addEventListener('keyup', function () {
const emptyFields = Array.from(input).filter( input => input.value === "");
disabled = emptyFields.length > 0;
if(disabled) {
button.setAttribute('disabled', 'disabled')
} else {
button.removeAttribute('disabled')
}
})
})
}

You are enabling the submit button on keyup event of any 3 inputs. So it gets enabled on any 3 inputs.
Remove the return on disabled flow to disable button after clearing.
checkInput()
function checkInput() {
let input = document.querySelectorAll('.form-control')
const button = document.querySelector('.submit-btn')
input.forEach(function (e) {
let disabled = true;
e.addEventListener('keyup', function () {
if (e.value !== '') {
disabled = false
} else {
disabled = true
// return false <-- this makes function exit before your disable button
}
if(disabled) {
button.setAttribute('disabled', 'disabled')
} else {
button.removeAttribute('disabled')
}
})
})
}
<div class="form-group">
<label for="name">Name*</label>
<input class="form-control" type="text" id="name" placeholder="Name">
</div>
<div class="form-group">
<label for="lastName">lastName*</label>
<input class="form-control" type="text" id="lastName" placeholder="lastName">
</div>
<div class="form-group">
<label for="fiscalCode">fiscalCode*</label>
<input class="form-control" type="text" id="fiscalCode" placeholder="fiscalCode">
</div>
<button type="submit" disabled="disabled" class="submit-btn">Continue</button>

Another solution is to check if all inputs are filled out on every change in any input.
addHandlers();
// Return true if all fields are not empty
function areAllFieldsFilledOut() {
let inputs = document.querySelectorAll('.form-control');
let result = true;
inputs.forEach(e => {
if (e.value === "")
result = false;
});
return result;
}
// Add keyup event handlers to all input fields
function addHandlers() {
let inputs = document.querySelectorAll('.form-control');
const button = document.querySelector('.submit-btn');
inputs.forEach(e => {
// On each change in any input, check if all inputs are
// not empty, and if true, enable the button
e.addEventListener('keyup', e => {
let result = areAllFieldsFilledOut();
if (result) {
button.removeAttribute('disabled');
} else {
button.setAttribute('disabled', 'disabled');
}
});
});
}
<div class="form-group">
<label for="name">Name*</label>
<input class="form-control" type="text" id="name" placeholder="Name">
</div>
<div class="form-group">
<label for="lastName">lastName*</label>
<input class="form-control" type="text" id="lastName" placeholder="lastName">
</div>
<div class="form-group">
<label for="fiscalCode">fiscalCode*</label>
<input class="form-control" type="text" id="fiscalCode" placeholder="fiscalCode">
</div>
<button type="submit" disabled="disabled" class="submit-btn">Prosegui</button>

Here is my answer:
function checkInput() {
document.querySelectorAll('input').forEach(input => {
input.addEventListener('keyup', function () {
let emptyFieldsCount = Array.from(input).filter(input => input.value == "").length;
if (emptyFieldsCount > 0) {
button.setAttribute('disabled', 'disabled')
} else {
button.removeAttribute('disabled')
}
})
});
}

Related

Can you onblur a set of checkboxes?

I have a set of checkboxes, and validation such that at least one of those checkboxes need to be checked on submit. But I want to be able to set a validation error if the user blurs out of the set of checkboxes. The problem is that if I do a blur for the last one it doesn't work because they could be shift-tabbing to the second from last checkbox. I've tried to but the onblur in the fieldset tag, but that didn't trigger a blur at all. Is this just a limitation that can't be overcome with plain html and vanilla JS?
You can look at what the next element that is focused is and determine if they are under the same grouping.
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function (event) {
const nextElem = event.relatedTarget;
const fieldSet = elem.closest('fieldset');
const isValid = fieldSet.querySelector("input:checked") !== null;
if (nextElem?.closest('fieldset') !== fieldSet) {
fieldSet.classList.toggle("error", !isValid);
} else if (isValid) {
fieldSet.classList.remove("error");
}
});
});
.error {
color: red;
}
<form>
<fieldset>
<legend>Pizza One</legend>
<input type="checkbox" name="x1-1" id="x1-1">
<label for="x1-1">Cheese</label>
<input type="checkbox" name="x1-2" id="x1-2">
<label for="x1-2">Peppers</label>
<input type="checkbox" name="x1-3" id="x1-3">
<label for="x1=3">Mushrooms</label>
</fieldset>
<fieldset>
<legend>Pizza Two</legend>
<input type="checkbox" name="x2-1" id="x2-1">
<label for="x2-1">Cheese</label>
<input type="checkbox" name="x2-2" id="x2-2">
<label for="x2-2">Peppers</label>
<input type="checkbox" name="x2-3" id="x2-3">
<label for="x2-3">Mushrooms</label>
</fieldset>
<input type="submit" />
</form>
Adding in a trick to use HTML5 validation
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function(event) {
const nextElem = event.relatedTarget;
const fieldSet = elem.closest('fieldset');
const isValid = fieldSet.querySelector("input:checked") !== null;
if (nextElem?.closest('fieldset') !== fieldSet) {
fieldSet.classList.toggle("error", !isValid);
}
});
elem.addEventListener("change", function(event) {
const fieldSet = elem.closest('fieldset');
const isValid = fieldSet.querySelector("input:checked") !== null;
if (isValid) {
fieldSet.classList.remove("error");
fieldSet.querySelectorAll("input").forEach((cb) => {
cb.removeAttribute("required");
});
} else {
fieldSet.querySelectorAll("input").forEach((cb) => {
cb.setAttribute("required", "required");
});
}
});
const changeEvt = document.createEvent("HTMLEvents");
changeEvt.initEvent("change", false, true);
elem.dispatchEvent(changeEvt);
});
.error {
color: red;
}
<form>
<fieldset>
<legend>Pizza One</legend>
<input type="checkbox" name="x1-1" id="x1-1">
<label for="x1-1">Cheese</label>
<input type="checkbox" name="x1-2" id="x1-2">
<label for="x1-2">Peppers</label>
<input type="checkbox" name="x1-3" id="x1-3">
<label for="x1=3">Mushrooms</label>
</fieldset>
<fieldset>
<legend>Pizza Two</legend>
<input type="checkbox" name="x2-1" id="x2-1">
<label for="x2-1">Cheese</label>
<input type="checkbox" name="x2-2" id="x2-2">
<label for="x2-2">Peppers</label>
<input type="checkbox" name="x2-3" id="x2-3">
<label for="x2-3">Mushrooms</label>
</fieldset>
<input type="submit" />
</form>
Based on epascarello's suggestion I was able to create a function that provided similar functionality to the one provided. I have an error span that's underneath the checkboxes. I wanted behavior that would immediately remove that if any checkbox was checked, but only add the error span if the user blurred out of the entire set of checkboxes. Note that there is only one fieldset on this page, and the error span has an specific id I could reference. Here's the function that I got working:
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function (event) {
var errorSpan = document.getElementById("checkboxesErrorSpan");
var isValid = document.querySelector("fieldset").querySelectorAll("input:checked").length > 0;
if (isValid) {
if ((errorSpan.style.display == "inline")) {
errorSpan.style.display = "none";
}
}
else {
if (event.relatedTarget.type != "checkbox") {
if ((errorSpan.style.display == "none")) {
errorSpan.style.display = "inline";
}
}
}
});
});

Form is not submitting , not sure if this has to do with the captcha

I am trying to tie the code in together.
I recently just made a form and found a captcha on codepen that I wanted to try out
But for some reason I cant get the captcha to validate the form even though it does perform the calculation. Any idea what could be causing the problem in my code? Thanks in advance.
<form
class="form mt-4"
method="POST"
action="action_page.php">
<!-- Name Field -->
<div class="form-group">
<label for="name">Name:</label>
<input
type="text"
name="name"
id="name"
placeholder="Enter Your Name"
class="form-control"
required
/>
</div>
<!-- Email Field -->
<div class="form-group">
<label for="email"
>Email Address:</label
>
<input
type="email"
name="email"
id="email"
placeholder="Enter Your Email"
class="form-control"
required
/>
</div>
<!-- Password Field -->
<div class="form-group">
<label for="password"
>Password:</label
>
<input
type="password"
name="password"
minlength="8"
id="password"
placeholder="Password"
class="form-control"
required
/>
</div>
<!-- Confirm Password Field -->
<div class="form-group">
<label for="confirm_password"
>Confirm Password:</label
>
<input
type="password"
name="confirm_password"
minlength="8"
id="confirm_password"
placeholder="Confirm Password"
class="form-control"
required
/>
</div>
<!-- Telegram API Token Field -->
<div class="form-group">
<label for="telegram_token"
>Telegram API Token:</label
>
<input
type="text"
name="telegram_token"
id="telegram_token"
placeholder="Enter Telegram API Token"
class="form-control"
required
/>
</div>
<!-- Telegram Chat ID Field -->
<div class="form-group">
<label for="telegram_id"
>Telegram Chat ID:</label
>
<input
type="text"
name="telegram_id"
id="telegram_id"
placeholder="Enter Telegram Chat ID"
class="form-control"
required
/>
</div>
<!-- Captcha Field -->
<div class="form-group">
<label>Are you human?</label>
<br />
<label class="submit__control">
<div
class="submit__generated"
></div>
<i
class="fa fa-refresh"
></i>
<span
class="submit__error hide"
>Incorrect value</span
>
<span
class="submit__error--empty hide"
>Required field cannot
be left blank</span
>
</label>
</div>
<!-- Register Button -->
<div class="form-group">
<button
type="submit"
class="btn btn-info btn-block"
>
Register
</button>
var a,
b,
c,
submitContent,
captcha,
locked,
validSubmit = false,
timeoutHandle;
// Generating a simple sum (a + b) to make with a result (c)
function generateCaptcha() {
a = Math.ceil(Math.random() * 10);
b = Math.ceil(Math.random() * 10);
c = a + b;
submitContent =
"<span>" +
a +
"</span> + <span>" +
b +
"</span>" +
' = <input class="submit__input" type="text" maxlength="2" size="2" required />';
$(".submit__generated").html(submitContent);
init();
}
// Check the value 'c' and the input value.
function checkCaptcha() {
if (captcha === c) {
// Pop the green valid icon
$(".submit__generated").removeClass("unvalid").addClass("valid");
$(".submit").removeClass("overlay");
$(".submit__overlay").fadeOut("fast");
$(".submit__error").addClass("hide");
$(".submit__error--empty").addClass("hide");
validSubmit = true;
} else {
if (captcha === "") {
$(".submit__error").addClass("hide");
$(".submit__error--empty").removeClass("hide");
} else {
$(".submit__error").removeClass("hide");
$(".submit__error--empty").addClass("hide");
}
// Pop the red unvalid icon
$(".submit__generated").removeClass("valid").addClass("unvalid");
$(".submit").addClass("overlay");
$(".submit__overlay").fadeIn("fast");
validSubmit = false;
}
return validSubmit;
}
function unlock() {
locked = false;
}
// Refresh button click - Reset the captcha
$(".submit__control i.fa-refresh").on("click", function () {
if (!locked) {
locked = true;
setTimeout(unlock, 500);
generateCaptcha();
setTimeout(checkCaptcha, 0);
}
});
// init the action handlers - mostly useful when 'c' is refreshed
function init() {
$("form").on("submit", function (e) {
e.preventDefault();
if ($(".submit__generated").hasClass("valid")) {
// var formValues = [];
captcha = $(".submit__input").val();
if (captcha !== "") {
captcha = Number(captcha);
}
checkCaptcha();
if (validSubmit === true) {
validSubmit = false;
// Temporary direct 'success' simulation
submitted();
}
} else {
return false;
}
});
// Captcha input result handler
$(".submit__input").on(
"propertychange change keyup input paste",
function () {
// Prevent the execution on the first number of the string if it's a 'multiple number string'
// (i.e: execution on the '1' of '12')
window.clearTimeout(timeoutHandle);
timeoutHandle = window.setTimeout(function () {
captcha = $(".submit__input").val();
if (captcha !== "") {
captcha = Number(captcha);
}
checkCaptcha();
}, 150);
}
);
// Add the ':active' state CSS when 'enter' is pressed
$("body")
.on("keydown", function (e) {
if (e.which === 13) {
if ($(".submit-form").hasClass("overlay")) {
checkCaptcha();
} else {
$(".submit-form").addClass("enter-press");
}
}
})
.on("keyup", function (e) {
if (e.which === 13) {
$(".submit-form").removeClass("enter-press");
}
});
// Refresh button click - Reset the captcha
$(".submit-control i.fa-refresh").on("click", function () {
if (!locked) {
locked = true;
setTimeout(unlock, 500);
generateCaptcha();
setTimeout(checkCaptcha, 0);
}
});
// Submit white overlay click
$(".submit-form-overlay").on("click", function () {
checkCaptcha();
});
}
generateCaptcha();
// Password Match Function
function check(input) {
if (input.value != document.getElementById('password').value) {
input.setCustomValidity('Passwords do not match.');
} else {
// input is valid -- reset the error message
input.setCustomValidity('');
}
}
It was the function for submit was missing

Why ajax request doubles?

I have an issue, with ajax request. When button enter is clecked it is doubles ajax request. I spent 4 hours dealing with it and no effect at all. Can someone help me with it. I have created consol.log here. For better understanding of my bad code. Thank you in advanced!
let formSubmitHandler = (data) => {
console.log(data)
// $.ajax({ url: 'index.php',
}
let handleInputEdit = (data) => {
let onFocusHandler = (element) => {
element.keypress(function( event ) {
if ( event.which == 13) {
let inputData = element.val();
let name = element.attr('name');
return onHandlerFormData(name, inputData);
}
})
}
let onHandlerFormData = (name, data) => {
let str = `${name}=${data}`;
$('#data').html(str)
return formSubmitHandler(str);
}
let onEditHandler = () => {
let checkboxes = document.querySelectorAll('input[type=checkbox]');
for (let i = 0; i < checkboxes.length; i++) {
const element = checkboxes[i];
let getNaighborInput = $(element).parent().next();
getNaighborInput.attr("disabled", true);
if (element.checked) {
let getNaighborInput = $(element).parent().next();
getNaighborInput.attr("disabled", false)
.focus(function(){
onFocusHandler($(this));
})
}
}
};
onEditHandler();
$("input[type=checkbox]").on("click", onEditHandler);
}
handleInputEdit();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="mainForm">
<label for="companyName">Label 2</label>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input
id="companyName"
type="text"
class="form-control"
aria-label="..."
name="companyName"
>
</div>
<label for="edrpou">Label 2</label>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input
id="edrpou"
type="text"
class="form-control"
aria-label="..."
name="edrpou"
>
</div>
</form>
You are calling onFocusHandler multiple times. You binding the onFocusHandler multiple times each time the checkbox is clicked. Moving the onFocusHandler from the definition of onEditHandler will solve this issue. Try out the following code,
The onEditHandler will change as follows,
let onEditHandler = () => {
let checkboxes = document.querySelectorAll('input[type=checkbox]');
for (let i = 0; i < checkboxes.length; i++) {
const element = checkboxes[i];
let getNaighborInput = $(element).parent().next();
getNaighborInput.attr("disabled", true);
if (element.checked) {
let getNaighborInput = $(element).parent().next();
getNaighborInput.attr("disabled", false)
}
}
};
And bind the onFocusHandler function with the checkboxes only once as follows,
$('input[type=checkbox]').each(function () {
onFocusHandler($(this).parent().next());
});
I have re-written the javascript to handle enabling/disabling the textboxes, and also to handle keyup event for the ENTER press.
I think the code is more readable this way, plus: it works as expected.
// disable all textboxes by default
$('input[type=text]').attr('disabled','disabled');
//only enable the textbox next to the checkbox if it was checked
$(document).on('click','input[type=checkbox]',function(){
if ($(this).is(':checked')) {
$(this).parent().siblings('input[type=text]')
.removeAttr('disabled');
} else {
$(this).parent().siblings('input[type=text]')
.attr('disabled','disabled');
}
});
//whenever the ENTER key is pressed within an enabled textbox, handle it
$(document).on('keyup','input[type=text]',function(e) {
if(e.which == 13) {
console.log( $(this).attr('id') + '=' + $(this).val() );
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="mainForm">
<label for="companyName">Label 2</label>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input
id="companyName"
type="text"
class="form-control"
aria-label="..."
name="companyName"
>
</div>
<label for="edrpou">Label 2</label>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input
id="edrpou"
type="text"
class="form-control"
aria-label="..."
name="edrpou"
>
</div>
</form>
Like Ahmad... I also re-written your way too complex code.
It made my brain bleed.
And it does a so simple task in the end!
About changes on HTML, I only added the disabled attribute straith in the markup.
Have a look:
$("#mainForm input[type='checkbox']").on("click",function(){
var text_input = $(this).parent().next("input");
var text_input_dasbled = text_input.prop("disabled");
text_input.attr("disabled", !text_input_dasbled); // Toggle disabled
});
$("#mainForm input[type='text']").on("keyup",function(e){
if(e.which==13){
var data = {[$(this).attr("name")]:$(this).val()};
console.log(data)
// $.ajax({ ... });
}
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
<form id="mainForm">
<label for="companyName">Label 2</label>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input
id="companyName"
type="text"
class="form-control"
aria-label="..."
name="companyName"
disabled>
</div>
<label for="edrpou">Label 2</label>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input
id="edrpou"
type="text"
class="form-control"
aria-label="..."
name="edrpou"
disabled>
</div>
</form>

form validation problems with jquery / javascript

This is my first real project which involves form validation. I am experiancing a problem which I can not find the solution to.
The objective is this, there is a continue button which will be activated once all the field inputs have been passed as valid. I am going about this by creating seperate variables, all initially set as false, devoted to checking each input field. When the user has entered correct validation data, the variable is set to true.
I then run an if statement to check if all the variables are set to true, and if so, I activate the continue button which, when clicked, slides the next part of the form into the page.
HTML:
<div class="container">
<h3>Step 3: Your Details</h3>
<!-- SLIDE-IN DIV TO REPRESENT DAY PASS -->
<div class="row chosenmembership">
<div class="col-md-12 text-center" id="yourdetails">
<form action="" method="">
<div class="form-group">
<label for="email">Email:</label>
<input type="text" placeholder="Email Address" id="email" class="form-control your-details">
<span class="warning" id="email-warning"></span>
</div>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" placeholder="Full Name" id="name" class="form-control your-details">
<span class="warning" id="name-warning"></span>
</div>
<div class="form-group">
<label for="number">Contact Number:</label>
<input type="text" placeholder="Contact Number" id="number" class="form-control your-details">
<span class="warning" id="number-warning"></span>
</div>
<div class="form-group">
<label for="dob">Date of Birth:</label>
<input type="date" id="dob" class="form-control your-details">
<span class="warning" id="dob-warning"></span>
</div>
</form>
<input type="submit" id="submit" value="CONTINUE">
</div>
</div>
</div>
JAVASCRIPT / JQUERY:
//collection of input form fields//
var formSubmit = $("#submit");
var emailField = $("#email");
var nameField = $("#name");
var numberField = $("#number");
//Switch to true when each validation has passed//
emailValidated = false;
nameValidated = false;
numberValidated = false;
//email validation check//
emailField.on("input",function(){
var emailInput = $(this).val()
var testExp = new RegExp(/[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,3}$/);
if (emailInput < 1) {
$("#email-warning").html("Email is required!");
$("#email-warning").css("visibility","visible");
emailValidated = false;
}
else if (!testExp.test(emailInput)){
$("#email-warning").html("Please enter a valid email");
$("#email-warning").css("visibility","visible");
emailValidated = false;
} else {
$("#email-warning").css("visibility","hidden");
emailValidated = true;
}
})
//name validation check//
nameField.on("input",function(){
var nameInput = $(this).val()
if (nameInput < 1) {
$("#name-warning").html("Name is required");
$("#name-warning").css("visibility","visible");
nameValidated = false;
} else {
$("#name-warning").css("visibility","hidden");
nameValidated = true;
}
})
//contact number validation check//
numberField.on("input",function(){
var numberInput = $(this).val()
if (typeof numberInput !== "number" && numberInput.length < 9) {
$("#number-warning").html("Please enter a valid number");
$("#number-warning").css("visibility","visible");
numberValidated = false;
} else {
$("#number-warning").css("visibility","hidden");
numberValidated = true;
}
})
if (emailValidated && nameValidated && numberValidated){
alert("correct");
}
})
at the moment, I am simply using the alert prompt to test if it is working, but it fails.
As mentioned, this is my first real form validation. Any other tips or advice would be greatly appreciated. Thanks for the help in advance.
There were a couple things that I found from copying pasting your snippets of code. 1 there was an ending "})" without a beginning $(document).ready(function(){ ". 2 none of your ".on" statements had an ending semi colon.
Here is my javascript with a small change
$(document).ready(function () {
//collection of input form fields//
var formSubmit = $("#submit");
var emailField = $("#email");
var nameField = $("#name");
var numberField = $("#number");
//Switch to true when each validation has passed//
emailValidated = false;
nameValidated = false;
numberValidated = false;
//email validation check//
emailField.on("input", function () {
var emailInput = $(this).val()
var testExp = new RegExp(/[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,3}$/);
if (emailInput < 1) {
$("#email-warning").html("Email is required!");
$("#email-warning").css("visibility", "visible");
emailValidated = false;
}
else if (!testExp.test(emailInput)) {
$("#email-warning").html("Please enter a valid email");
$("#email-warning").css("visibility", "visible");
emailValidated = false;
} else {
$("#email-warning").css("visibility", "hidden");
emailValidated = true;
enableContinue();
}
});
//name validation check//
nameField.on("input", function () {
var nameInput = $(this).val()
if (nameInput < 1) {
$("#name-warning").html("Name is required");
$("#name-warning").css("visibility", "visible");
nameValidated = false;
} else {
$("#name-warning").css("visibility", "hidden");
nameValidated = true;
enableContinue();
}
});
//contact number validation check//
numberField.on("input", function () {
var numberInput = $(this).val()
if (typeof numberInput !== "number" && numberInput.length < 9) {
$("#number-warning").html("Please enter a valid number");
$("#number-warning").css("visibility", "visible");
numberValidated = false;
} else {
$("#number-warning").css("visibility", "hidden");
numberValidated = true;
enableContinue();
}
});
enableContinue = function () {
if (emailValidated && nameValidated && numberValidated) {
$('#submit').prop('disabled', false);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h3>Step 3: Your Details</h3>
<!-- SLIDE-IN DIV TO REPRESENT DAY PASS -->
<div class="row chosenmembership">
<div class="col-md-12 text-center" id="yourdetails">
<form action="" method="">
<div class="form-group">
<label for="email">Email:</label>
<input type="text" placeholder="Email Address" id="email" class="form-control your-details">
<span class="warning" id="email-warning"></span>
</div>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" placeholder="Full Name" id="name" class="form-control your-details">
<span class="warning" id="name-warning"></span>
</div>
<div class="form-group">
<label for="number">Contact Number:</label>
<input type="text" placeholder="Contact Number" id="number" class="form-control your-details">
<span class="warning" id="number-warning"></span>
</div>
<div class="form-group">
<label for="dob">Date of Birth:</label>
<input type="date" id="dob" class="form-control your-details">
<span class="warning" id="dob-warning"></span>
</div>
</form>
<input type="submit" class="btn btn-primary" id="submit" disabled="disabled" value="CONTINUE">
</div>
</div>
</div>
Your form CONTINUE button becomes enables once all fields have a value. Note: I did not try to improve your javascript any, just made it work.
Right now you synchronically check validation variables at script, so they are all false. You have to asynchronically check them after form submit. Just add event listener to form submit to check variables like this:
document.getElementById('#form').addEventListener('submit', function(){
if (emailValidated && nameValidated && numberValidated){
alert("correct");
}
});
Don't forget to set id to your form.
You may be able to save a lot of work if you leverage some of the built in HTML5 form validation. https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation
This simple example adds a new field every time you submit the form, as long as the existing fields are valid. You would need to test the state of the form to see if you should be adding another section or submitting.
$('form').on('submit', function() {
$(this).find('fieldset').append('<input type="text" required />');
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<fieldset>
<input type="text" required />
</fieldset>
<input type="submit" id="submit" value="continue" />
</form>

Force user to fill all fields before enabling form submit

I have a form containing various fields.
See jsFiddle demo.
My aim is to enable the submit button only when the user has filled in all fields.
So far, I'm able to force the title field to have content before submit button is enabled. How do I make it so that all other fields need to be filled too before submit button is enabled.
jQuery("input[type='text']").on("keyup", function () {
if (jQuery(this).val() != "" ) {
if (jQuery("#titlenewtide").val() != '')
{
jQuery("#subnewtide").removeAttr("disabled");
}
} else {
jQuery("#subnewtide").attr("disabled", "disabled");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post" id="new_tide">
Title: <input id="titlenewtide" type="text" name="title" required> <br>
Description: <textarea name="description" id="description"></textarea> <br>
Tag: <input id="newtag" type="text" name="newtag" required> <br>
Category: <input type="radio" name="category" value="19" required> Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
Note that I am loading the JavaScripts in my footer.
Make the changes take effect after changing inputs values:
On each input change, test the values of other inputs and checked state of radio, if all inputs has been entered it will make the submit button enabled:
var validateInputs = function validateInputs(inputs) {
var validForm = true;
inputs.each(function(index) {
var input = $(this);
if (!input.val() || (input.type === "radio" && !input.is(':checked'))) {
$("#subnewtide").attr("disabled", "disabled");
validForm = false;
}
});
return validForm;
}
inputs.change(function() {
if (validateInputs(inputs)) {
$("#subnewtide").removeAttr("disabled");
}
});
Demo:
var inputs = $("form#myForm input, form#myForm textarea");
var validateInputs = function validateInputs(inputs) {
var validForm = true;
inputs.each(function(index) {
var input = $(this);
if (!input.val() || (input.type === "radio" && !input.is(':checked'))) {
$("#subnewtide").attr("disabled", "disabled");
validForm = false;
}
});
return validForm;
}
inputs.change(function() {
if (validateInputs(inputs)) {
$("#subnewtide").removeAttr("disabled");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post" id="myForm">
Title:
<input id="titlenewtide" type="text" name="title" required>
<br>Description:
<textarea name="description" id="description"></textarea>
<br>Tag:
<input id="newtag" type="text" name="newtag" required>
<br>Category:
<input type="radio" name="category" value="19" required>Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
Also it uses the form id="myForm", so you can use it to validate only specific forms in your pages.
Note: This is tested and working on Chrome, Firefox and IE.
EDIT:
Make the changes take effect when we type in the inputs:
In the previous code we are using onchange event handler to call the function so it's only called when we click outside a given input (after change).
To perform the call automatically when the user enters a character in a field (the last one) we need to use the onkeyup event so we don't need to click outside of it.
This is the changed code you need :
var inputs = $("form#myForm input, form#myForm textarea");
var validateInputs = function validateInputs(inputs) {
var validForm = true;
inputs.each(function(index) {
var input = $(this);
if (!input.val() || (input.type === "radio" && !input.is(':checked'))) {
$("#subnewtide").attr("disabled", "disabled");
validForm = false;
}
});
return validForm;
}
inputs.each(function() {
var input = $(this);
if (input.type === "radio") {
input.change(function() {
if (validateInputs(inputs)) {
$("#subnewtide").removeAttr("disabled");
}
});
} else {
input.keyup(function() {
if (validateInputs(inputs)) {
$("#subnewtide").removeAttr("disabled");
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post" id="myForm">
Title:
<input id="titlenewtide" type="text" name="title" required>
<br>Description:
<textarea name="description" id="description"></textarea>
<br>Tag:
<input id="newtag" type="text" name="newtag" required>
<br>Category:
<input type="radio" name="category" value="19" required>Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
Use this code below. On each input, it will check all the form fields by using this function validate().
jQuery("input[type='text'], textarea").on("input", function () {
var isValid = validate();
if (isValid) {
jQuery("#subnewtide").removeAttr("disabled");
} else {
jQuery("#subnewtide").attr("disabled", "disabled");
}
});
function validate() {
var isValid = true;
$('input, textarea').each(function() {
if ($(this).val() === '')
isValid = false;
});
return isValid;
}
Fiddle
Update
To make it validate if the form has id="new_tide" and fix about the radio button.
$("input[type='text'], textarea").on("change input", function() {
validate($(this));
});
$("input:radio[name='category']").on("change", function() {
validate($(this));
});
function validate(self) {
if (self.parents("form:first").attr("id") == "new_tide") {
var isValid = true;
$('input[type="text"], textarea').each(function() {
if ($(this).val() === '')
isValid = false;
});
if (!$("input:radio[name='category']").is(':checked'))
isValid = false;
if (isValid) {
$("#subnewtide").removeAttr("disabled");
} else {
$("#subnewtide").attr("disabled", "disabled");
}
}
}
Fiddle
Here's how you can do it:
$(document).ready(function () {
var $inputs = $("#new_tide input:not([type=hidden]), #new_tide textarea");
$inputs.on("input change", function () {
valid = true;
$inputs.each(function () {
valid *= this.type == "radio" ? this.checked : this.value != "";
return valid;
});
$("#subnewtide").prop("disabled", !valid);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<form action="#" method="post" id="new_tide">
Title: <input id="titlenewtide" type="text" name="title" required> <br>
Description: <textarea name="description" id="description"></textarea> <br>
Tag: <input id="newtag" type="text" name="newtag" required> <br>
Category: <input type="radio" name="category" value="19" required> Animation
Hidden: <input type="hidden">
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
Try utilizing .siblings() , .map() to compile values of form elements , Array.prototype.every() to return Boolean representation of input , textarea values , set disabled property of form input[type=submit] element
$("form *[required]").on("input change", function(e) {
$(this).siblings("[type=submit]").prop("disabled"
, !$(this).siblings(":not([type=submit])").add(this).map(function(_, el) {
return el.type === "radio" ? el.checked : el.value
}).get().every(Boolean)
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<form action="#" method="post" id="new_tide">
Title: <input id="titlenewtide" type="text" name="title" required> <br>
Description: <textarea name="description" id="description" required></textarea> <br>
Tag: <input id="newtag" type="text" name="newtag" required> <br>
Category: <input type="radio" name="category" value="19" required> Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
By far the easiest, would be to rely on the HTML5 validation you're already using.
You'd have to add required to all form controls if you want to require all of them, and that can easily be done by using jQuery's :input selector and setting the property, like so
$(':input:not(#subnewtide)').prop('required', true)
We'll exclude the submit button, as that doesn't have to be required, obviously, not that it would matter in this case.
Then we'll listen for the input event, which covers all sorts of inputs, like typing, pasting etc, and the change event as well to cover the radio button.
Using form.checkValidity() tells us if the form is valid, and returns a boolean, so we could use it directly to set the disabled property of the submit button.
All together it looks like this, and that's all you need, a few lines of really simple code
$(':input:not(#subnewtide)').prop('required', true).on('input change', function() {
$('#subnewtide').prop( 'disabled', !this.form.checkValidity() );
});
FIDDLE
If you have to support old browsers that don't have HTML5 validation, you can use the H5F polyfill
My solution is base on standard JavaScript.
HTML form
<form action="#" method="post" id="new_tide" name="form1">
Title: <input onkeyup="myBtnActivator(1)" id="titlenewtide" name="title" type="text" required> <br>
Description: <textarea onkeyup="myBtnActivator(2)" id="description" name="description"></textarea> <br>
Tag: <input id="newtag" onkeyup="myBtnActivator(3)" name="newtag" type="text" required> <br>
Category: <input name="category" onchange="myBtnActivator(4)" type="radio" value="19" required> Animation
<button id="subnewtide" name="subnewtide" type="submit" value="Submit">Submit</button>
</form>
JavaScript
<script>
document.getElementById("subnewtide").disabled = true;
var input1 = false;
var input2 = false;
var input3 = false;
var input4 = false;
function myBtnActivator(i) {
switch (i) {
case 1:
input1 = true;
if (document.form1.title.value == "")
input1 = false;
break;
case 2:
input2 = true;
if (document.form1.description.value == "")
input2 = false;
break;
case 3:
input3 = true;
if (document.form1.newtag.value == "")
input3 = false;
break;
case 4:
input4 = true;
if (document.form1.subnewtide.value == "")
input4 = false;
break;
}
trigger();
}
function trigger() {
if (input1 == true && input2 == true && input3 == true && input4 == true) {
document.getElementById("subnewtide").disabled = false;
} else {
document.getElementById("subnewtide").disabled = true;
}
}
</script>
Why don't you use jquery validate . It's a good plugin .
The logic works like, any change in the form it will check the form is valid or not. And also using the errorplacement function it will disable the default error message also.
$().ready(function() {
// validate signup form on keyup and submit
$("#contactForm").validate({
rules: {
title: "required",
description: {
required: true
},
newtag: {
required: true
},
category: {
required: true
}
},
errorPlacement: function(error, element) {
return true;
},
submitHandler: function() {
}
});
$('#contactForm').change(function() {
if ($("#contactForm").valid()) {
$("#subnewtide").removeAttr("disabled");
}
});
});
Fiddle
There's actually a pretty easy approach. I'm using native JavaScript, but I think it is applicable in jQuery as well:
var form = document.getElementById("new_tide");
form.onchange = function onChange() {
var enable = true;
var inputs = form.getElementsByTagName("input");
var textareas = form.getElementsByTagName("textarea");
for (var i in inputs) {
enable = enable && inputs[i].value != "";
}
for (var i in textareas) {
enable = enable && textareas[i].value != "";
}
enable = enable && textarea.value != "";
document.getElementById("subnewtide").disabled = !enable;
}
The change event on form is always called, when any input or textarea element was changed (click in element, type, click somewhere else or lose focus).
Edit:
Regarding hidden fields, you can exclude them by surrounding the enable calculation with an if-condition:
if (!inputs[i].hidden) {
enable = enable && inputs[i].value != "";
}
Note:
This will work in any browser (even Internet Explorer 5.5). Check on MDN:
for ..in Loop
element.getElementsByTagName()
document.getElementById()
Thought I might chip in. Assuming as little as possible.
jQuery("input, textarea").on("keyup click", function () { // going vanilla after easy-mode attach
var sub = document.getElementById('subnewtide');
if (require_all(find_form(this))) {
sub.removeAttribute('disabled');
sub.disabled = false;
} else {
sub.setAttribute('disabled', 'disabled');
sub.disabled = true;
}
});
function concat(a, b) { // concating Array-likes produces Array
var slice = [].slice; // not assuming Array.prototype access
return [].concat.call(
slice.call(a, 0),
slice.call(b, 0)
);
}
function find_form(e) { // shim input.form
if (e) do {
if (e.tagName === 'FORM') return e;
} while (e = e.parentNode);
return null;
}
function require_all(form, dontIgnoreHidden) { // looks at textareas & inputs (excluding buttons)
var inp = concat(form.getElementsByTagName('input'), form.getElementsByTagName('textarea')),
rad = {}, // not assuming Object.create
i, j,
has = {}.hasOwnProperty; // not assuming Object.prototype access
for (i = 0; i < inp.length; ++i) {
switch ((inp[i].type || '').toLowerCase()) {
default: // treat unknown like texts
case 'text':
if (!inp[i].value) return false; break;
case 'checkbox':
if (!inp[i].checked) return false; break;
case 'radio':
j = inp[i].getAttribute('name');
if (!rad[j]) rad[j] = inp[i].checked;
break;
case 'hidden':
if (dontIgnoreHidden && !inp[i].value) return false; break;
case 'button':
case 'submit':
break;
}
}
for (j in rad) if (!has || has.call(rad, j)) // not assuming hasOwnProperty
if (!rad[j]) return false;
return true;
}
Here is a quick way to accomplish that. It involves attaching a change event listener to :radio and :checkbox elements and an input event listener to other elements. These can both use a common predefined handler that will count the number of unfilled element each time each of these events fires on the appropriate element.
function checkForm() {
//define and initialize variables
var unfilled = 0,
form = $(this.form);
//disable submit button if enabled
$(':submit', form).prop('disabled', true);
//count number of unfilled elements
$(':input', form).each(function() {
if( $(this).is(':radio,:checkbox') ) {
$('input[name=' + this.name + ']:checked').length || unfilled++;
} else {
$('[name=' + this.name + ']').val() || unfilled++;
}
});
//enable submit button if no unfilled element is found
unfilled || $(':submit', form).prop('disabled', false);
}
//set up event listeners to fire above handler
$(':text,textarea,select').on('input', checkForm);
$(':radio,:checkbox').on('change', checkForm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="#" method="post" id="new_tide">
Title: <input id="titlenewtide" type="text" name="title" required> <br>
Description: <textarea name="description" id="description"></textarea> <br>
Tag: <input id="newtag" type="text" name="newtag" required> <br>
Category: <input type="radio" name="category" value="19" required> Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
var inputs = $("form#myForm input, form#myForm textarea");
var validateInputs = function validateInputs(inputs) {
var validForm = true;
inputs.each(function(index) {
var input = $(this);
if (!input.val() || (input.type === "radio" && !input.is(':checked'))) {
$("#subnewtide").attr("disabled", "disabled");
validForm = false;
}
});
return validForm;
}
inputs.each(function() {
var input = $(this);
if (input.type === "radio") {
input.change(function() {
if (validateInputs(inputs)) {
$("#subnewtide").removeAttr("disabled");
}
});
} else {
input.keyup(function() {
if (validateInputs(inputs)) {
$("#subnewtide").removeAttr("disabled");
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post" id="myForm">
Title:
<input id="titlenewtide" type="text" name="title" required>
<br>Description:
<textarea name="description" id="description"></textarea>
<br>Tag:
<input id="newtag" type="text" name="newtag" required>
<br>Category:
<input type="radio" name="category" value="19" required>Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
Use this html<br>
HTML:
<br>
<pre>
<form action="#" method="post" id="">
Title: ##<input id="titlenewtide" type="text" name="title" required>
Description: <textarea name="description" id="description"></textarea>
Tag: <input id="newtag" type="text" name="newtag" required>
Category: <input type="checkbox" onclick="validate()" name="category" id="cate"value="19" required > Animation
<button type="submit" value="Submit" name="subnewtide" id="subnewtide" disabled="disabled">Submit</button>
</form>
</pre>
validation code:<br>
//on each key up function intiate the function validate
<pre>
jQuery("input[type='text']").on("keyup", function () {
validate();
});
jQuery("#description").on("keyup", function () {
validate();
});
function validate(){
jQuery("input[type='text']").each(function(){
if (jQuery(this).val() != "" )
{
if((jQuery("#description").val() !="") && (jQuery("#cate").is(':checked')))
{
jQuery("#subnewtide").removeAttr("disabled");
}
else {
jQuery("#subnewtide").attr("disabled", "disabled");
}
}
});
}
</pre>
you can find the fiddle in : https://jsfiddle.net/s8uv2gkp/
Maytham Fahmi's relatively easy solution can be made even easier by passing this.name.
<form action="#" method="post" id="new_tide" name="form1">
<input onkeyup="myBtnActivator(this.name)" name="title" type="text" required> <br>
<textarea onkeyup="myBtnActivator(this.name)" name="description"></textarea> <br>
<input id="newtag" onkeyup="myBtnActivator(this.name)" name="newtag" type="text" required> <br>
<input name="category" onchange="myBtnActivator(this.name)" type="radio" value="19" required> Animation
<button id="subnewtide" name="subnewtide" type="submit" value="Submit">Submit</button>
</form>
this refers to the DOM object that called the function. So the switch can just directly take the name, or the value, or anything else you can pass with DOM.
myBtnActivator(n)
{
switch(n)
{
case "title":
break;
case "description":
break;
case "newtag":
break;
case "category":
break;
}
}

Categories

Resources