是否有一种方法可以使表单提交按钮检查具有必需属性的输入元素,如果未填写则显示错误,然后运行另一功能以确保至少单击了一个复选框?
当我给我的HTML按钮一个“ onClick ='return CheckForm()”时,如果未单击复选框,它只是阻止表单提交,但不显示通常显示的“必需”的任何错误。 / p>
必须有一种方法可以使它们同时执行。
document.getElementById('name').focus();
//variables
let otherJobRole = document.getElementById('other');
let defaultDisplay = otherJobRole.style.display;
let title = document.getElementById("title");
let design = document.getElementById('design');
let colorsSection = document.getElementById('colors-js-puns');
let color = document.getElementById('color');
let creditCard = document.getElementById('credit-card');
let paypal = document.getElementById('paypal');
let bitcoin = document.getElementById('bitcoin');
let payment = document.getElementById('payment');
let activities = document.getElementsByClassName('activities')[0];
let email = document.getElementById('mail');
let ccNum = document.getElementById('cc-num');
let zip = document.getElementById('zip');
let cvv = document.getElementById('cvv');
let expMonth = document.getElementById('exp-month');
let expYear = document.getElementById('exp-year');
var times = [];
let submitButton = document.querySelector('button');
let form = document.querySelector('form');
let activitiesFirstLabel = activities.childNodes[3];
let checkboxErrorP = document.createElement('p');
// let button = document.getElementbyTagName('button');
checkboxErrorP.innerHTML = "You must select at least one activity"
checkboxErrorP.setAttribute('id', 'error');
//Hides HTML elements that shouldn't be displayed yet
otherJobRole.style.display = 'none';
paypal.style.display = 'none';
bitcoin.style.display = 'none';
colorsSection.style.display = 'none';
//Displays additional field if "other" is selected for a job
title.addEventListener('click', () => {
if(title.value === "other") {
otherJobRole.style.display = defaultDisplay;
} else {
otherJobRole.style.display = 'none';
}
});
//Handles the color display based on chosed design
design.addEventListener('click', () => {
if(design.value === 'js puns') {
colorsSection.style.display = defaultDisplay;
for(let i = 3; i < color.options.length; i++) {
color.options[i].style.display = 'none';
};
for(let i = 0; i < 3; i++) {
color.options[i].style.display = defaultDisplay;
};
} else if(design.value === 'heart js') {
colorsSection.style.display = defaultDisplay;
for(let i = 0; i < 3; i++) {
color.options[i].style.display = 'none';
};
for(let i = 3; i < color.options.length; i++) {
color.options[i].style.display = defaultDisplay;
};
} else {
colorsSection.style.display = 'none';
};
});
//Array of objects containing the events, their time, and cost
let activitiesDict = [
{
associate: document.getElementsByName('all')[0],
name: 'main',
// time: 'none',
cost: 200
},
{
associate: document.getElementsByName('js-frameworks')[0],
name: 'js-frameworks',
time: 'Tuesday 9am-12pm',
cost: 100
},
{
associate: document.getElementsByName('js-libs')[0],
name: 'js-libs',
time: 'Tuesday 1pm-4pm',
cost: 100
},
{
associate: document.getElementsByName('express')[0],
name: 'express',
time: 'Tuesday 9am-12pm',
cost: 100
},
{
associate: document.getElementsByName('node')[0],
name: 'node',
time: 'Tuesday 1pm-4pm',
cost: 100
},
{
associate: document.getElementsByName('build-tools')[0],
name: 'build-tools',
// time: 'Wednesday 9am-12pm',
cost: 100
},
{
associate: document.getElementsByName('npm')[0],
name: 'npm',
// time: 'Wednesday 1pm-4pm',
cost: 100
},
];
//Checks for conflicting times and disables events you wouldn't be able to attend
activities.addEventListener('click', (event) => {
let cost = 0;
let timeToSplice = null;
let elementName = ""
//gets the name of the activity that was clicked
if(event.path[0].tagName == "LABEL") {
return;
} else {
elementName = event.path[0].name;
}
//if element unchecked, find the time to remove from times and re-enable elements
//that corrospond with that time
if (event.target.checked == false){
for(var i = 0; i < activities.childElementCount-2; i++) {
if(elementName == activitiesDict[i].name){
timeToSplice = activitiesDict[i].time;
break;
}
}
for(var i = 0; i < activities.childElementCount-2; i++) {
if(activitiesDict[i].time == timeToSplice) {
activitiesDict[i].associate.disabled = false;
activitiesDict[i].associate.parentElement.style.color = "black";
}
}
}
//Removes a time from times array so activities with that time will be re-enabled
if(timeToSplice != null) {
let index = times.indexOf(timeToSplice);
if(times.length == 1) {
times = [];
} else if(index == times.length-1) {
times.splice(index);
} else {
times.splice(index, index+1);
}
}
//Adds a time to the time array, letting us know what we need to disable for next step
for(var i = 0; i < activities.childElementCount-2; i++) {
if(activitiesDict[i].associate.checked == true) {
cost += activitiesDict[i].cost;
if (activitiesDict[i].time)
if (times.indexOf(activitiesDict[i].time) == -1){
times.push(activitiesDict[i].time);
}
}
};
//Disables elements that are unclicked but have a conflicting time with an activity
//that is clicked.
if(event.target.checked) {
for(var i = 0; i < activities.childElementCount-2; i++) {
for(var x = 0; x < times.length; x++) {
if(activitiesDict[i].time === times[x] && activitiesDict[i].associate.checked == false) {
activitiesDict[i].associate.disabled = true;
activitiesDict[i].associate.parentElement.style.color = 'rgb(152, 152, 152)';
}
}
}
}
let DisplayCost = document.getElementById('displayCost');
DisplayCost.innerHTML = "Total Cost: $" + cost;
cost = 0;
validateCheckbox();
});
//Displays CC, paypal, or bitcoin payment info and adds or removes validation if needed
payment.addEventListener('click', () => {
if(payment.value === 'credit card') {
paypal.style.display = 'none';
creditCard.style.display = defaultDisplay;
addRequired();
bitcoin.style.display = 'none';
} else if(payment.value === 'paypal') {
removeRequired();
paypal.style.display = defaultDisplay;
creditCard.style.display = 'none';
bitcoin.style.display = 'none';
} else if(payment.value === 'bitcoin') {
removeRequired();
paypal.style.display = 'none';
creditCard.style.display = 'none';
bitcoin.style.display = defaultDisplay;
};
});
//Adds credit card info validation
function addRequired() {
ccNum.required = true;
ccNum.minLength = 13;
ccNum.maxLength = 16;
zip.required = true;
zip.minLength = 5;
zip.maxLength = 5;
cvv.required = true;
cvv.minLength = 3;
cvv.maxLength = 3;
expMonth.required = true;
expYear.required = true;
//validate CC Num
ccNum.addEventListener('keyup', () => {
if(ccNum.value.length < 13 || ccNum.value.length > 16) {
ccNum.setCustomValidity('CC number must be between 13 and 16 digits.');
} else {
ccNum.setCustomValidity('');
}
});
//Validate Zip
zip.addEventListener('keyup', () => {
if(zip.value.length != 5) {
zip.setCustomValidity('Zip must be exactly 5 digits.');
} else {
zip.setCustomValidity('');
}
});
//Validate CVV
cvv.addEventListener('keyup', () => {
if(cvv.value.length != 3) {
cvv.setCustomValidity('CVV must be exactly 3 digits.');
} else {
cvv.setCustomValidity('');
}
});
}
//Removes credit card vaildation
function removeRequired() {
ccNum.required = false;
zip.required = false;
cvv.required = false;
expMonth.required = false;
expYear.required = false;
ccNum.value = "";
zip.value = "";
cvv.value = "";
expMonth.value = "";
expYear.value = "";
ccNum.setCustomValidity('');
zip.setCustomValidity('');
cvv.setCustomValidity('');
};
//Validate checkboxes and returns false if no boxes are checked
function validateCheckbox() {
let atLeastOneChecked = false;
for(var i = 0; i < activitiesDict.length; i++) {
if(activitiesDict[i].associate.checked) {
atLeastOneChecked = true;
}
}
if(atLeastOneChecked == false) {
form.insertBefore(checkboxErrorP, activities);
checkboxErrorP.style.display = defaultDisplay;
} else {
checkboxErrorP.style.display = 'none';
}
return atLeastOneChecked;
};
//Returns true if there is an @ in email value and letters after
let emailValid = false;
email.setCustomValidity('Please enter a valid email with an @ sign');
email.addEventListener('keyup', (event) => {
let emailValue = event.target.value;
console.log(emailValue);
for(let i = 0; i < emailValue.length; i++)
if(emailValue[i] == '@'){
console.log('valid email');
emailValid = true;
email.setCustomValidity('');
}
});
function checkForm() {
console.log('checking');
if(emailValid && validateCheckbox()) {
return true;
} else {
// button.preventDefault();
return false;
}
};
// submitButton.addEventListener('click', (e) => {
// console.log("is the form complete?")
// if(checkForm() == false) {
// e.preventDefault();
// } else {
// form.submit();
// }
// });
function valuable() {
console.log('running');
return false;
}
addRequired();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register for Full Stack Conf</title>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header>
<span>Register for</span>
<h1>Full Stack Conf</h1>
</header>
<form action="index.html" method="post" >
<fieldset>
<legend>Basic Info</legend>
<label for="name">*Name:</label>
<input type="text" id="name" name="user_name" required>
<label for="mail">*Email:</label>
<input type="email" id="mail" name="user_email" required>
<label for="title">Job Role</label>
<select id="title" name="user_title">
<option value="full-stack js developer">Full Stack JavaScript Developer</option>
<option value="front-end developer">Front End Developer</option>
<option value="back-end developer">Back End Developer</option>
<option value="designer">Designer</option>
<option value="student">Student</option>
<option value="other">Other</option>
</select>
<input type="text" id="other" name="other" placeholder="Your Job Role">
</fieldset>
<fieldset class="shirt">
<legend>T-Shirt Info</legend>
<div>
<label for="size">Size:</label>
<select id="size" name="user_size">
<option value="small">S</option>
<option value="medium" selected>M</option>
<option value="large">L</option>
<option value="extra large">XL</option>
</select>
</div>
<div>
<label for="design">Design:</label>
<select id="design" name="user_design">
<option>Select Theme</option>
<option value="js puns">Theme - JS Puns</option>
<option value="heart js">Theme - I ♥ JS</option>
</select>
</div>
<div id="colors-js-puns" class="">
<label for="color">Color:</label>
<select id="color">
<option value="cornflowerblue">Cornflower Blue (JS Puns shirt only)</option>
<option value="darkslategrey">Dark Slate Grey (JS Puns shirt only)</option>
<option value="gold">Gold (JS Puns shirt only)</option>
<option value="tomato">Tomato (I ♥ JS shirt only)</option>
<option value="steelblue">Steel Blue (I ♥ JS shirt only)</option>
<option value="dimgrey">Dim Grey (I ♥ JS shirt only)</option>
</select>
</div>
</fieldset>
<fieldset class="activities" >
<legend>Register for Activities</legend>
<label><input type="checkbox" name="all"> Main Conference — $200</label>
<label><input type="checkbox" name="js-frameworks"> JavaScript Frameworks Workshop — Tuesday 9am-12pm, $100</label>
<label><input type="checkbox" name="js-libs"> JavaScript Libraries Workshop — Tuesday 1pm-4pm, $100</label>
<label><input type="checkbox" name="express"> Express Workshop — Tuesday 9am-12pm, $100</label>
<label><input type="checkbox" name="node"> Node.js Workshop — Tuesday 1pm-4pm, $100</label>
<label><input type="checkbox" name="build-tools"> Build tools Workshop — Wednesday 9am-12pm, $100</label>
<label><input type="checkbox" name="npm"> npm Workshop — Wednesday 1pm-4pm, $100</label>
<p id="displayCost"> $0 </p>
</fieldset>
<fieldset>
<legend>Payment Info</legend>
<label for="payment">I'm going to pay with:</label>
<select id="payment" name="user_payment">
<option value="select_method" disabled>Select Payment Method</option>
<option value="credit card">Credit Card</option>
<option value="paypal">PayPal</option>
<option value="bitcoin">Bitcoin</option>
</select>
<div id="credit-card" class="credit-card">
<div class="col-6 col">
<label for="cc-num">Card Number:</label>
<input id="cc-num" name="user_cc-num" type="text">
</div>
<div class="col-3 col">
<label for="zip">Zip Code:</label>
<input id="zip" name="user_zip" type="text">
</div>
<div class="col-3 col">
<label for="cvv">CVV:</label>
<input id="cvv" name="user_cvv" type="text">
</div>
<label for="exp-month">Expiration Date:</label>
<select id="exp-month" name="user_exp-month">
<option value="1">1 - January</option>
<option value="2">2 - February</option>
<option value="3">3 - March</option>
<option value="4">4 - April</option>
<option value="5">5 - May</option>
<option value="6">6 - June</option>
<option value="7">7 - July</option>
<option value="8">8 - August</option>
<option value="9">9 - September</option>
<option value="10">10 - October</option>
<option value="11">11 - November</option>
<option value="12">12 - December</option>
</select>
<label for="exp-year">Expiration Year:</label>
<select id="exp-year" name="user_exp-year">
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
</select>
</div>
<div id="paypal">
<p>If you selected the PayPal option we'll take you to Paypal's site to set up your billing information, when you click “Register” below.</p>
</div>
<div id="bitcoin">
<p>If you selected the Bitcoin option we'll take you to the Coinbase site to set up your billing information. Due to the nature of exchanging Bitcoin, all Bitcoin transactions will be final.</p>
</div>
</fieldset>
<button onClick='return checkForm()' type="submit">Register</button>
</form>
</div>
</body>
<script src="js/script.js"></script>
</html>