JS function is breaking remaining functions - javascript

I've got a function which breaks ALL other javascript / jquery on the page.
What I'm trying to do with the function below is duplicate a div upon button press and append it after the initial one (can be duplicated as many times as pressed) - and it works great, except everything else breaks.
I've added the snippets above it just for reference, but it's the actual function duplicateContact() which is causing the issues.
If someone could help with pointing out my mistake I'd love to be able to use the function without having it kill everything else.
//add more contacts
document.getElementById('C_addContact').onclick = duplicateContact;
var i = 0;
var original = document.getElementById('C_contacts');
var nextElement = $.extend(original);
function duplicateContact()
{
var clone = original.cloneNode(true); // "deep" clone
clone.id = "C_contacts" + ++i; // there can only be one element with an ID
nextElement.parentNode.insertBefore(clone, nextElement.nextSibling);
}
Below is my remaining js:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
//show hidden div upon select box selection
$(function() {
$('#otherTitleField').hide();
$('#title').change(function(){
if($('#title').val() == 'Other') {
$('#otherTitleField').show();
} else {
$('#otherTitleField').hide();
}
});
});
//show hidden div upon radio button selection
$(document).ready(function() {
$('input[type="radio"]').click(function() {
if($(this).attr('id') == 'postno') {
$('#postalnofield').show();
}
else {
$('#postalnofield').hide();
}
});
});
//show different hidden div based on checkboxes
function valueChanged1()
{
if($('#tfn').is(":checked")) {
$("#tfnfield").show();
}
else
$("#tfnfield").hide();
}
function valueChanged2()
{
if($('#abn').is(":checked")) {
$("#abnfield").show();
}
else
$("#abnfield").hide();
}
//clear contacts div
function clearBox(elementID)
{
if(elementID != 'C_contacts') {
document.getElementById(elementID).innerHTML = "";
}
}
</script>
And the HTML for the div which is being cloned:
<div id="C_contacts">
<p><label for="C_familyName">Family name<span class="mandatory">*</span></label>
<input type="text" id="C_familyName" name="Section C Family Name" required></p>
<p><span style="display:inline-block; width:49%;">
<label for="C_givenName">First given name<span class="mandatory">*</span></label>
<input type="text" id="C_givenName" name="Section C Given Name" required></span>
<span style="display:inline-block; width:49%;">
<label for="C_otherName">Other given name/s<span class="mandatory">*</span></label>
<input type="text" id="C_otherName" name="Section C Other Names" required>
</span></p>
<p><label for="C_position">Position held<span class="mandatory">*</span></label>
<input type="text" id="C_position" name="Section C Position Held" required></p>
<p><span style="display:inline-block; width:49%;">
<label for="C_busPhone">Business phone<span class="mandatory">*</span></label>
<input type="tel" id="C_busPhone" name="Section C Business Phone" required>
</span>
<span style="display:inline-block; width:49%;">
<label for="C_mobPhone">Mobile phone</label>
<input type="tel" id="C_mobPhone" name="Section C Mobile">
</span></p>
<p><label for="C_busEmail">Business email address</label>
<input type="email" id="C_busEmail" name="Section C Email"></p>
<p><label for="C_thisApp C_busOp">This person is the authorised contact for information about:<span class="mandatory">*</span></label><br>
<input type="checkbox" id="C_thisApp" name="This Application" value="thisApp"> this application<br>
<input type="checkbox" id="C_busOp" name="Operation of Business" value="busOp"> the operation of the business after we have granted a licence</p>
<p><input type="button" id="C_removeContact" value="Remove contact" onclick="clearBox(this.parentNode.parentNode.id)"></p>
<p><input type="button" id="C_addContact" onclick="duplicateContact()" value="Add more contacts"></p>
<hr>
</div>
UPDATE: Apparently I had two versions of jquery which was causing issues. I have no idea how I missed this - thank you to everyone for the suggestions and help, this is resolved.

I don't know what is your actual code, but I can see every time you are cloning a div in which you are cloning remove and add buttons. But you need to create a single Add button for cloning and there are remove buttons for all clone divs. Also your function clearBox is not called for the newly generated divs, to make it work you can use jQuery.on() and use toggle() to show hide so that your code can be short. Below is the working snippet which can help you for your functionality
//add more contacts
document.getElementById('C_addContact').onclick = duplicateContact;
var i = 0;
var original = document.getElementById('C_contacts');
var nextElement = $.extend(original);
function duplicateContact() {
var clone = original.cloneNode(true); // "deep" clone
clone.id = "C_contacts" + ++i; // there can only be one element with an ID
nextElement.parentNode.insertBefore(clone, nextElement.nextSibling);
}
//show hidden div upon select box selection
$(function() {
$('#otherTitleField').hide();
$('#title').change(function() {
$('#otherTitleField').toggle(this.value == 'Other');
});
//show hidden div upon radio button selection
$('input[type="radio"]').click(function() {
$('#postalnofield').toggle(this.id == 'postno');
});
// using event delegation with document for removing dynamic divs
$(document).on('click', '.remove-contacts', function() {
$(this).closest('.c-contacts').attr('id') !== 'C_contacts' &&
$(this).closest('.c-contacts').remove();
});
});
//show different hidden div based on checkboxes
function valueChanged1() {
$("#tfnfield").toggle($('#tfn').is(":checked"));
}
function valueChanged2() {
$("#abnfield").toggle($('#abn').is(":checked"));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="C_contacts" class="c-contacts">
<p>
<label for="C_familyName">Family name<span class="mandatory">*</span></label>
<input type="text" id="C_familyName" name="Section C Family Name" required>
</p>
<p><span style="display:inline-block; width:49%;">
<label for="C_givenName">First given name<span class="mandatory">*</span></label>
<input type="text" id="C_givenName" name="Section C Given Name" required>
</span>
<span style="display:inline-block; width:49%;">
<label for="C_otherName">Other given name/s<span class="mandatory">*</span></label>
<input type="text" id="C_otherName" name="Section C Other Names" required>
</span>
</p>
<p>
<label for="C_position">Position held<span class="mandatory">*</span></label>
<input type="text" id="C_position" name="Section C Position Held" required>
</p>
<p><span style="display:inline-block; width:49%;">
<label for="C_busPhone">Business phone<span class="mandatory">*</span></label>
<input type="tel" id="C_busPhone" name="Section C Business Phone" required>
</span>
<span style="display:inline-block; width:49%;">
<label for="C_mobPhone">Mobile phone</label>
<input type="tel" id="C_mobPhone" name="Section C Mobile">
</span></p>
<p>
<label for="C_busEmail">Business email address</label>
<input type="email" id="C_busEmail" name="Section C Email">
</p>
<p>
<label for="C_thisApp C_busOp">This person is the authorised contact for information about:<span class="mandatory">*</span></label>
<br>
<input type="checkbox" id="C_thisApp" name="This Application" value="thisApp"> this application
<br>
<input type="checkbox" id="C_busOp" name="Operation of Business" value="busOp"> the operation of the business after we have granted a licence</p>
<p>
<input type="button" id="C_removeContact" value="Remove contact" class="remove-contacts">
</p>
<hr>
</div>
<p>
<input type="button" id="C_addContact" value="Add more contacts">
</p>

Related

how can we display html form values as many times as the user insert them by pressing submit button each time?

<form action="#"></form>
<label for="First-name">First name: </label>
<input type="text" id="First-name" placeholder="Please insert fiid."><br>
<label for="Second-name">Second name: </label>
<input type="text" id="Second-name" placeholder="Please insert second name"> <br>
<label for="Passenger-weight">Passengers weight: </label>
<input type="number" class="weight" id ="Passenger-weight" placeholder="Please enter passengers weight"><br>
<label for="cargo-weight">cargo weight: </label>
<input type="number" class="weight" id ="cargo-weight" placeholder="Please enter cargo weight"><br>
<input type="submit" id ="submit" ><br>
</form>
<p id="sum"></p>
<div id="sumoftotal"></div>
<body>
<script language="JavaScript">
document.getElementById("submit").onclick=function (){
let firstName = document.getElementById("First-name").value;
let lastName= document.getElementById("Second-name").value;
let num1 = document.getElementById("Passenger-weight").value;
let num2 = document.getElementById("cargo-weight").value;
let total =parseInt(num1) + parseInt(num2);
document.getElementById("sum").innerHTML=(`${firstName} ${lastName} ${total }`)
}
</script>
</body>
my problem can be numbered:
number 1: when I press the submit button, input values show up, BUT when I want to insert a different data, the previous one disappear. I studied about it, because whatever comes in the function scope become local we cannot apply it outside, BUT I don't know how to change it.
number 2: I want to have the sum of total weights I insert at the end of my list, I know we can do this by loop, BUT I need something simpler and more preliminary because I am a novice and it would be a big jump for the time being.
all in all, I would be happy if anyone could help me.
Here is the primary and most basic approach.
var data = document.getElementById('data');
var weightElement = document.getElementById('total-weight');
document.getElementById("submit").onclick = function() {
/* Getting data */
let firstName = document.getElementById("First-name").value;
let lastName = document.getElementById("Second-name").value;
let num1 = document.getElementById("Passenger-weight").value;
let num2 = document.getElementById("cargo-weight").value;
let total = parseInt(num1) + parseInt(num2);
/* Appending element */
data.innerHTML = data.innerHTML + `First Name - ${firstName}, Last Name - ${lastName}, Weight - ${total} <br/>`;
weightElement.innerHTML = parseInt(weightElement.innerHTML) + total;
}
<body>
<form action="#"></form>
<label for="First-name">First name: </label>
<input type="text" id="First-name" placeholder="Please insert fiid."><br>
<label for="Second-name">Second name: </label>
<input type="text" id="Second-name" placeholder="Please insert second name"> <br>
<label for="Passenger-weight">Passengers weight: </label>
<input type="number" class="weight" id="Passenger-weight" placeholder="Please enter passengers weight"><br>
<label for="cargo-weight">cargo weight: </label>
<input type="number" class="weight" id="cargo-weight" placeholder="Please enter cargo weight"><br>
<input type="submit" id="submit"><br>
</form>
<div id="data"></div>
<div>Total weight = <span id="total-weight">0</span></div>
</body>

JAVASCRIPT , HTML enabling input field based on radio button choice

I tried to have two input option enable based on the radio button choice, but only one option is enabling not matter which option I choose. Eg- If I choose sheetcake, instead of having input option for sheetcake, I have the input option of roundcake. I am new in javascript and any advice will be much appreciated. Thank You. ( I tried to run the code in snippet and it works fine but I run the same code in browser and only one input box is working no matter what, I tried to run in 3 different browsers and got the same error, I don't know what is the issue and where I made a mistake. Thank You in advance.
const sheetcake = document.getElementById("sheetcake");
const roundcake = document.getElementById("roundcake");
var caketype = document.getElementsById("caketype");
function CakeChoice(choice){
if (choice == sheetcake){
document.getElementById("SheetLength").disabled=false;
document.getElementById("SheetWidth").disabled=false;
document.getElementById("RoundRadius").disabled=true;
}
else {
document.getElementById("SheetLength").disabled=true;
document.getElementById("SheetWidth").disabled=true;
document.getElementById("RoundRadius").disabled=false;
}
}
<div id="caketype">
<label class="caketype required">Cake Type:</label> <br>
<input type="radio" id="sheetcake" name="caketype" value="0" required onclick="CakeChoice(sheetcake)">
<label>Sheet Cake</label><br>
<input type="radio" id="roundcake" name="caketype" value="0" required onclick="CakeChoice(roundcake)">
<label>Round Cake</label>
</div>
<br>
<div id="CakeDimensions" >
<label>Cake size (cm)</label><br>
<input type="number" id="SheetLength" value="0" min="30" max="60" required disabled>
<label class="form-label required">cm Length</label><br>
<input type="number" id="SheetWidth" value="0" min="30" max="45" required disabled>
<label class="form-label required">cm Width</label>
</div>
<br>
<div id="round">
<label>Cake size</label><br>
<input type="number" id="RoundRadius" min="15" max="30" disabled required>
<label class="form-label required">cm Radius</label>
</div>
<br><br>
<div id="cakelayers">
<label class="form-label required">How many layers?</label><br>
<input type="radio" id="OneLayer" name="CakeLayers" value="1layer" required>
<label for="OneLayer">One Layer</label><br>
<input type="radio" id="TwoLayers" name="CakeLayers" value="2layers" required>
<label for="TwoLayers">Two Layers</label><br>
<input type="radio" id="ThreeLayers" name="CakeLayers" value="3layers" required>
<label for="ThreeLayers">Three Layers</label>
</div>
<br><br>
May I suggest a slightly alternative approach which avoids having irrelevant disabled options that some users might be trying to activate.
Instead of disabling the irrelevant options, manipulating the display styles of the two sets of option for cake dimensions (by javascript) allows for only the relevant one to be available for interaction. This lets you make the relevant size option only appear when a type has been chosen (and toggles between them if the user changes their mind).
As you have fairly complex markup for each option, I've added extra divisions containing each group. The ids for the relevant divisions, rectangle and round are used to create references to each grouping in the javascript allowing access to their style.display property, which can be toggled.
const sheetcake = document.getElementById("rectangle");
const roundcake = document.getElementById("round");
sheetcake.style = "display: none";
round.style = "display: none";
function CakeChoice(choice){
if (choice == 'sheetcake'){
sheetcake.style = "display: block";
roundcake.style = "display: none";
} else {
sheetcake.style = "display: none";
roundcake.style = "display: block";
}
}
<div id="caketype">
<label class="caketype required">Cake Type:</label> <br>
<input type="radio" id="sheetcake" name="caketype" value="0" required onclick="CakeChoice('sheetcake')">
<label>Sheet Cake</label><br>
<input type="radio" id="roundcake" name="caketype" value="0" required onclick="CakeChoice('roundcake')">
<label>Round Cake</label>
</div>
<br>
<div id="CakeDimensions" >
<div id="rectangle">
<label>Cake size (cm)</label><br>
<input type="number" id="SheetLength" value="0" min="30" max="60" required>
<label class="form-label required">cm Length</label><br>
<input type="number" id="SheetWidth" value="0" min="30" max="45" required>
<label class="form-label required">cm Width</label>
</div>
<div id="round">
<label>Cake size</label><br>
<input type="number" id="RoundRadius" min="15" max="30" required>
<label class="form-label" "required">cm Radius</label>
</div>
</div>
<br>
<div id="cakelayers">
<label class="form-label required">How many layers?</label><br>
<input type="radio" id="OneLayer" name="CakeLayers" value="1layer" required>
<label for="OneLayer">One Layer</label><br>
<input type="radio" id="TwoLayers" name="CakeLayers" value="2layers" required>
<label for="TwoLayers">Two Layers</label><br>
<input type="radio" id="ThreeLayers" name="CakeLayers" value="3layers" required>
<label for="ThreeLayers">Three Layers</label>
</div>
<br>
I've made some minor refactoring to your HTML then removed a bit of replication to your javascript, reducing the dependencies on Ids. This will make it more flexible should you add more options for dimensions or round. I've also illustrated adding the event listeners via javascript.
//Get all the radio buttons in the element with ID caketype and itterate them
document.querySelectorAll("#caketype input[type=radio]").forEach(function(item) {
//Add an on click event listener
item.addEventListener("click", function() {
//Is Sheet cake chosen from the clicked element
let isSheetCake = this.value === "sheetcake";
//Set out disabled AND required attributes based on the above
//Get the input elements in the fieldset and itterate instead of being bound by id
document.querySelectorAll("#CakeDimensions input").forEach(function(element) {
element.disabled = !isSheetCake;
element.required = isSheetCake;
});
//Do the same for round, but invert the logic
document.querySelectorAll("#round input").forEach(function(element) {
element.disabled = isSheetCake;
element.required = !isSheetCake;
});
//Bonus: lets set a class to indicate that group is disabled
//.classList.toggle() ,adds or removes a class, in this case
// based on a truthy value
document.getElementById("CakeDimensions").classList.toggle("disabled", !isSheetCake);
document.getElementById("round").classList.toggle("disabled", isSheetCake);
});
});
fieldset {
border: none;
padding: 0.5em;
margin: 0;
}
.disabled {
color: #EEE;
}
<!-- Ive Given the radio buttond values, which you are going to want if you send this to a server-->
<!-- Also encapsulated the radio button group with a fieldset which is more semantic-->
<!-- Inline Javascript has been removed -->
<!-- Labels have been associated with their form elements with the "for" attribute-->
<fieldset id="caketype">
<label class="caketype required">Cake Type:</label> <br>
<input type="radio" id="sheetcake" name="caketype" value="sheetcake" required>
<label for="sheetcake">Sheet Cake</label><br>
<input type="radio" id="roundcake" name="caketype" value="roundcake" required>
<label for="roundcake">Round Cake</label>
</fieldset>
<fieldset id="CakeDimensions">
<label>Cake size (cm)</label><br>
<input type="number" id="SheetLength" value="0" min="30" max="60" required disabled>
<label class="form-label required">cm Length</label><br>
<input type="number" id="SheetWidth" value="0" min="30" max="45" required disabled>
<label class="form-label required">cm Width</label>
</fieldset>
<fieldset id="round">
<label>Cake size</label><br>
<input type="number" id="RoundRadius" min="15" max="30" disabled required>
<label class="form-label required">cm Radius</label>
</fieldset>
Between Jon P's and Dave Pritlove's answers it looks like the basics are already covered. Tihs answer will focus on the following:
Event delegation: A programming paradigm in which event bubbling is used to leverage control of an unlimited number of elements by binding an ancestor element to listen for events and delegate which elements react to events and which elements are excluded.
HTMLFormElement interface: Part of the The HTML DOM API, that has terse syntax and unique features:
Referencing a form:
<form id="UI"></form>
const UI = document.forms.UI
/*or*/
const UI = document.forms[0] // the first of one or more forms.
Referencing all form controls✻ within UI with the .elements property:
<input id='i1' name='IO'> <button name='btn'></button> <input id='i2' name='IO'>
const fC = UI.elements;
// Reference by #id
const I1 = fC.i1 // first input by #id
// Refernce by [name]
const B = fC.btn // button by [name]
// HTMLFormsControlCollection of all tags with [name='IO']
const io = fC.IO // an array-like object of both inputs
const ioArray = [...io] // convert into an array
[for] attribute & .labels property association: Besides the [for] attribute & form control #id association, there's another type of association we can establish:
<label for='A'></label><input id='A'><label for='A'>I'm the 2nd label</label>
const IO = UI.elements; // collect all of #UI form controls
const a = IO.A; // reference the input
const Alabels = a.labels; // collect all label associated to input via [for] to #id
Alabels[1].textContent; // get the text of the 2nd label
// result: "I'm the 2nd label"
Here's a list of other properties used in the example below:
.checkValidity()
Event.target
.classList
The example has a step progression:
Pick a type
Pick a size
Choose how many layers
Step 2 is disabled until step 1 is completed.
Step 3 is disabled until the user enters valid data in step 2.
✻form controls: <button>, <fieldset>, <input>, <object>, <output>, <select>, <textarea>
const form = document.forms.cake;
form.onchange = cakeStep1;
form.addEventListener('input', cakeStep2);
function cakeStep1(e) {
const IO = this.elements;
const picked = e.target;
const radios = [...IO.type];
const l = IO.L;
const w = IO.W;
const d = IO.D;
const sSet = IO.sizeSet;
if (picked.name == 'type') {
radios.forEach(r => r.labels[0].classList.remove('active'));
picked.labels[0].classList.add('active')
sSet.disabled = false;
if (picked.id == 'sheet') {
d.disabled = true;
d.labels[0].classList.add('disabled');
l.disabled = false;
l.labels[0].classList.remove('disabled');
w.disabled = false;
w.labels[0].classList.remove('disabled');
} else {
d.disabled = false;
d.labels[0].classList.remove('disabled');
l.disabled = true;
l.labels[0].classList.add('disabled');
w.disabled = true;
w.labels[0].classList.add('disabled');
}
}
}
function cakeStep2(e) {
const IO = this.elements;
const origin = e.target;
const l = IO.L;
const w = IO.W;
const d = IO.D;
const lSet = IO.layerSet;
if (origin.name == 'size') {
if (IO.sheet.checked && l.checkValidity() == true && w.checkValidity() == true) {
lSet.disabled = false;
} else if (IO.round.checked && d.checkValidity() == true) {
lSet.disabled = false;
} else {
lSet.disabled = true;
}
}
}
html {
font: 2ch/1.2 'Segoe UI'
}
header {
margin-bottom: -12px;
padding: 0;
}
label {
display: block;
width: 18ch;
margin-bottom: 4px;
}
[type='radio'] {
display: inline-block;
vertical-align: baseline;
height: 1.5ex;
margin: 0;
}
[type='number'] {
display: :inline-block;
width: 10ch;
float: right;
text-align: center
}
.active {
font-weight: 900;
text-decoration: underline;
}
.disabled {
opacity: 0.4
}
<form id='cake'>
<header>
<h2>Cake Order</h2>
</header>
<fieldset name="typeSet">
<legend>Type</legend>
<label for='sheet'><input id="sheet" name="type" type="radio" value="sheet"> Sheet Cake</label>
<label for='round'><input id="round" name="type" value="round" type="radio"> Round Cake</label>
</fieldset>
<fieldset name="sizeSet" disabled>
<legend>Size (cm)</legend>
<label for='L' class='disabled'>Length: <input id="L" name='size' type="number" min="30" max="60" placeholder='30-60cm' required></label>
<label for='W' class='disabled'>Width: <input id="W" name='size' type="number" min="30" max="45" placeholder='30-45cm' required></label>
<label for='D' class='disabled'>Diameter: <input id="D" name='size' type="number" min="15" max="40" placeholder='15-40cm' required></label>
</fieldset>
<fieldset name="layerSet" disabled>
<legend>Layers</legend>
<select id='layers' name='layers'>
<option selected>Number of Layers</option>
<option value='1'>1 Layer</option>
<option value='2'>2 Layers</option>
<option value='3'>3 Layers</option>
</select>
</fieldset>
</form>

How to display form validation error messages accurately for more than two input fields using only JavaScript?

I have created a JavaScript function that checks a form during submitting the input and displays an error message if there's no input.
It works perfectly when none input is given. It displays all the error messages correctly.
The Problem: But if I leave just the first field blank i.e, the fullname; the if loop stops there and doesn't display the second or third error messages i.e, the streetaddr & quantity.
NOTE: This error happens only when one of streetaddr or quantity is not given with addition to the first field i.e, fullname.
What should I do to display the error messages correctly. According to the blank input regardless the input field comes first or second or third.
Also, I prefer to do this with just Vanilla JavaScript, no frameworks/libraries. I'm trying to learn!
Link(s): This is a challenge from Wikiversity
/* Checking form function */
function checkForm(){
window.alert("You clicked Submit!");
var fullNameCheck = document.getElementById("fullname");
var addressCheck = document.getElementById("streetaddr");
var quantityCheck = document.getElementById("quantity");
var is_valid = false;
/* If statements to check if text box is empty */
if (fullNameCheck.value=="" && addressCheck.value=="" && quantityCheck.value=="") {
document.getElementById("nameerrormsg").style.display="inline";
document.getElementById("addrerrormsg").style.display="inline";
document.getElementById("qtyerrormsg").style.display="inline";
is_valid = false;
} else if(fullNameCheck.value==""){
document.getElementById("nameerrormsg").style.display="inline";
document.getElementById("addrerrormsg").style.display="none";
document.getElementById("qtyerrormsg").style.display="none";
is_valid = false;
} else if (addressCheck.value==""){
document.getElementById("addrerrormsg").style.display="inline";
document.getElementById("nameerrormsg").style.display="none";
document.getElementById("qtyerrormsg").style.display="none";
is_valid = false;
} else if (quantityCheck.value==""){
document.getElementById("qtyerrormsg").style.display="inline";
document.getElementById("nameerrormsg").style.display="none";
document.getElementById("addrerrormsg").style.display="none";
is_valid = false;
} else {
document.getElementById("nameerrormsg").style.display="none";
document.getElementById("addrerrormsg").style.display="none";
document.getElementById("qtyerrormsg").style.display="none";
is_valid = true;
} return is_valid;
}
.errormsg{
color: red;
background-color: yellow;
display: none;
}
<form action="mailto:me#fakeemail.com" onsubmit="return checkForm();">
<fieldset>
<legend>Personal details</legend>
<p>
<label>
Full name:
<input type="text" name="fullname" id="fullname">
</label>
</p>
<p class="errormsg" id="nameerrormsg">Please enter your name above</p>
<p>
<label>
Street Address:
<input type="text" name="streetaddr" id="streetaddr">
</label>
</p>
<p class="errormsg" id="addrerrormsg">Please enter your street address</p>
<!-- Quantity input -->
<p>
<label>
Quantity:
<input type="text" name="quantity" id="quantity">
</label>
</p>
<p class="errormsg" id="qtyerrormsg">Please enter your quantity</p>
</fieldset>
<input type="submit" value="Submit it!">
</form>
I'd prefer to just make the fields required, no Javascript needed:
<form action="mailto:me#fakeemail.com" onsubmit="return checkForm();">
<fieldset>
<legend>Personal details</legend>
<p>
<label>
Full name:
<input type="text" name="fullname" id="fullname" required>
</label>
</p>
<p>
<label>
Street Address:
<input type="text" name="streetaddr" id="streetaddr" required>
</label>
</p>
<!-- Quantity input -->
<p>
<label>
Quantity:
<input type="text" name="quantity" id="quantity" required>
</label>
</p>
</fieldset>
<input type="submit" value="Submit it!">
</form>
Otherwise, you can first hide all the error messages. Iterate over all inputs in the form, and if invalid (missing), navigate to its ancestor p and then to the adjacent .errormsg and set its display.
It would also be a good idea to avoid inline handlers entirely, they have too many problems to be worth using. Attach listeners properly using addEventListener in Javascript instead.
document.querySelector('form').addEventListener('submit', () => {
for (const errormsg of document.querySelectorAll('.errormsg')) {
errormsg.style.display = 'none';
}
let valid = true;
for (const input of document.querySelectorAll('form input')) {
if (input.value) {
// valid
continue;
}
valid = false;
input.closest('p').nextElementSibling.style.display = 'inline';
}
return valid;
});
.errormsg{
color: red;
background-color: yellow;
display: none;
}
<form action="mailto:me#fakeemail.com">
<fieldset>
<legend>Personal details</legend>
<p>
<label>
Full name:
<input type="text" name="fullname" id="fullname">
</label>
</p>
<p class="errormsg" id="nameerrormsg">Please enter your name above</p>
<p>
<label>
Street Address:
<input type="text" name="streetaddr" id="streetaddr">
</label>
</p>
<p class="errormsg" id="addrerrormsg">Please enter your street address</p>
<!-- Quantity input -->
<p>
<label>
Quantity:
<input type="text" name="quantity" id="quantity">
</label>
</p>
<p class="errormsg" id="qtyerrormsg">Please enter your quantity</p>
</fieldset>
<input type="submit" value="Submit it!">
</form>
You could hide all the error text as initially. Then show the error text based on respected input failure
/* Checking form function */
function checkForm() {
window.alert("You clicked Submit!");
var fullNameCheck = document.getElementById("fullname");
var addressCheck = document.getElementById("streetaddr");
var quantityCheck = document.getElementById("quantity");
var is_valid = false;
/* If statements to check if text box is empty */
document.getElementById("nameerrormsg").style.display = "none";
document.getElementById("addrerrormsg").style.display = "none";
document.getElementById("qtyerrormsg").style.display = "none";
is_valid = true;
if (fullNameCheck.value == "") {
document.getElementById("nameerrormsg").style.display = "inline";
is_valid = false;
}
if (addressCheck.value == "") {
document.getElementById("addrerrormsg").style.display = "inline";
is_valid = false;
}
if (quantityCheck.value == "") {
document.getElementById("qtyerrormsg").style.display = "inline";
is_valid = false;
}
return is_valid;
}
.errormsg {
color: red;
background-color: yellow;
display: none;
}
<form action="mailto:me#fakeemail.com" onsubmit="return checkForm();">
<fieldset>
<legend>Personal details</legend>
<p>
<label>
Full name:
<input type="text" name="fullname" id="fullname">
</label>
</p>
<p class="errormsg" id="nameerrormsg">Please enter your name above</p>
<p>
<label>
Street Address:
<input type="text" name="streetaddr" id="streetaddr">
</label>
</p>
<p class="errormsg" id="addrerrormsg">Please enter your street address</p>
<!-- Quantity input -->
<p>
<label>
Quantity:
<input type="text" name="quantity" id="quantity">
</label>
</p>
<p class="errormsg" id="qtyerrormsg">Please enter your quantity</p>
</fieldset>
<input type="submit" value="Submit it!">
</form>

HTML Validation JS without using PHP

I made an application for people to fill out an application. I did some of the in form validation but now I want to ensure that when the user hits the submit button it checks to ensure that all field are filled out. I am stuck and cannot figure out the last part of this puzzle.
I believe all I need to make this work is a Application.js If someone could take a look at this and let me know what if anything I am missing. I did not include the CSS sheet or photos. Thank you for taking the time to help.
Here is the form. "Application.html"
<!DOCTYPE html>
<html>
<head>
<center><h1>AIFC Application Form</h1></center>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<title>AIFC Application</title>
<meta charset="utf-8">
<meta name="author" content="Paul Skinner">
<link rel="stylesheet" type="text/css" href="Application.css" />
<style type="text/css">
</style>
<script src="Application.js"></script>
<script src="Application_Library.js"></script>
<script type="text/javascript">
function updateTotal() {
var basePrice = 50;
var optionsPrice = 0;
var memberPrice = 0;
function checkPayment() {
if (document.getElementById('payment0').checked) {
optionsPrice += 1;
}
if (document.getElementById('payment1').checked) {
optionsPrice += 9.6;
}
} // end of checking for payment
function checkJumper() {
if (document.getElementById('jumper0').checked) {
optionsPrice += 0;
}
if (document.getElementById('jumper1').checked) {
optionsPrice += 4.4;
}
} // end of checking for Jumper
function checkMembership() {
if (document.getElementById('membership').value == 'Basic') {
memberPrice += 75;
}
if (document.getElementById('membership').value == 'Silver') {
memberPrice += 125;
}
if (document.getElementById('membership').value == 'Gold') {
memberPrice += 150;
}
} // end of check membership function
checkPayment();
checkJumper();
checkMembership();
var totalPrice = basePrice + (optionsPrice * memberPrice);
document.getElementById('optionsPrice').innerHTML = optionsPrice;
document.getElementById('memberPrice').innerHTML = "$ " + memberPrice;
document.getElementById('totalPrice').innerHTML = "$ " + totalPrice;
}
</script>
</head>
<body>
<div id="top">
<nav class="horizontalNav">
<ul>
<li>Home</li>
<li>Application</li>
<li>Who We Are</li>
<li>Our Packages</li>
</ul>
</nav></div>
<section>
<table>
<tr style="white-space:nowrap; clear:both">
<td><img src="Images/girl punching.jpg" alt="Girl Punching" style=" float:left; height:200px" /></td>
<td><img src="images/fitness.jpg" alt="Weights" style=" float:right; height:200px; width:900px" /></td>
</tr>
</table>
</section>
<form action="#" method="get" name="application" id="application" >
<div id="form">
<fieldset>
<legend>Payment Type</legend><br>
<input type="radio" name="payment" id="payment0" value="payment0" onchange="updateTotal()"> Monthly membership <br>
<input type="radio" name="payment" id="payment1" value="payment1" onchange="updateTotal()"> Yearly membership <b>Big Savings!</b> <br><br>
</fieldset>
<fieldset>
<legend>Choose a Location</legend><br>
<input type="radio" name="jumper" id="jumper0" value="jumper0" onchange="updateTotal()"> Single Gym location
<input type="radio" name="jumper" id="jumper1" value="jumper1" onchange="updateTotal()"> All Locations <br><br>
</fieldset>
<fieldset>
<legend>Membership Type</legend><br>
<select name="membership" id="membership" onchange="updateTotal()">
<option value="Basic">Basic Membership ($75)</option>
<option value="Silver">Silver Membership ($125)</option>
<option value="Gold">Gold Membership ($150)</option><br>
</select>
</fieldset>
<fieldset>
<legend>Sex</legend><br>
<input type="radio" name="sex" value="male">Male<br>
<input type="radio" name="sex" value="female">Female<br>
</fieldset>
</div>
<div id="prices">
<table>
<tr><td>Membership Application Fee</td><td id="basePrice">$50</td></tr>
<tr><td>Option factor</td><td id="optionsPrice"></td></tr>
<tr><td>Membership</td><td id="memberPrice"></td></tr>
<tr><td>Total</td><td id="totalPrice"></td></tr>
</table>
</div>
<div id="info">
<fieldset>
<legend>Personal Information</legend>
<label for="first_name">First Name:</label>
<input type="text" id="firstname" name="first" required autofocus title="First Name" placeholder="First Name" />
<span id="first_name_error"> </span><br>
<label for="last_name">Last Name:</label>
<input type="text" id="lastname" name="last" required title="Last Name" placeholder="Last Name"/>
<span id="last_name_error"> </span><br>
<label for="address">Address:</label>
<input type="text" id="address" name="address" required title="Address" placeholder="Address"/>
<span id="address_error"> </span><br>
<label for="city">City:</label>
<input type="text" id="city" name="city" required title="City" placeholder="City"/>
<span id="city_error"> </span><br>
<label for="state">State:</label>
<input type="text" id="state" maxlength="2" name="State" required title="State" placeholder="State"/>
<span id="state_error"> </span><br>
<label for="zip_code">Zip Code:</label>
<input type="text" id="zip" name="zip" required title="Zip Code" placeholder="Zip Code" pattern="\d{5}([\-]\d{4})?"/>
<span id="zip_error"> </span><br>
<label for="phone_number">Phone Number:</label>
<input type="text" id="phone" name="phone" required title="Optional Phone Number 999-999-9999" placeholder="999-999-9999" pattern="\d{3}[\-]\d{3}[\-]\d{4}"/>
<span id="phone_error"> </span><br>
<label for="date_of_birth">Date of Birth:</label>
<input type="date" name="date" required title="MM-DD-YYYY"/>
<span id="date_error"> </span><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required title="Email" placeholder="Email Address"/>
<span id="email_error"> </span>
<br>
</fieldset>
<br><br><center><input type="submit" id="submit" value="Become a Member"></center>
<br><center><input type="Reset" id="btn1" value="Reset Form"></center>
</div>
<br><br><div class="footer">
<address><center>
<b>American InterContinental Fitness Center</b> ☀
1578 Perseverance Lane ☀
Simple City, IL 60001
<br/> (630)432-1425
</address></center>
<br>
</div>
</form>
</body>
</html>
The next is the js: "Application_Library.js"
var $ = function (id) { return document.getElementById(id); }
var application = function () {
// All the different fields
this.field = [];
this.field["first_name"] = {};
this.field["last_name"] = {};
this.field["address"] = {};
this.field["city"] = {};
this.field["state"] = {};
this.field["zip"] = {};
this.field["phone"] = {};
this.field["date"] = {};
this.field["email"] = {};
// Field messages
this.field["state"].message = "Please use only a two letter State abbreviation.";
this.field["zip"].message = "Please use a 5 or 9 digit Zip Code";
this.field["phone"].message = "Please use 123-456-7890 format.";
this.field["email"].message = "Must be a vaild email address.";
// Error messages
this.field["email"].required = "Email is required";
this.field["confirmemail"].required = "Please confirm your email!";
this.field["confirmemail"].noMatch = "Emails do not Match!", "email";
this.field["first_name"].required = "First names are required.";
this.field["last_name"].required = "Last names are required.";
this.field["address"].required = "An Address is required";
this.field["city"].required = "A City is required";
this.field["state"].required = "A State is required";
this.field["state"].isState = "State invalid";
this.field["zip"].required = "A Zip code is required.";
this.field["zip"].isZip = "Zip code is invalid";
this.field["phone"].required = "A phone number is required";
this.field["phone"].isPhone = "The phone number is invalid";
this.field["date"].required = "Your date of birth is required";
}
Instead of writing your own javascript validation you can use the jQuery "form Validation Plug-in", which is an excellent tool for web pages to validate data entries at the client side using JavaScript. It's very simple to use.
Here is a sample tutorial
http://www.codeproject.com/Articles/213138/An-Example-to-Use-jQuery-Validation-Plugin
You should implement server side validation also for best security.
You can't just check data on JavaScript, you should also check it on server-side, because the client side is more accessible and user can change the JavaScript or even disable it, so the data would be invalidated.
You should write server-side validation too.
You forgot to show the Application.js file.
Also you can use HTML5 validation, without using any JavaScript:
http://www.sitepoint.com/html5-form-validation/

How to subtract two text box values and display in another text box using Javascript

I want to fins the range between two number entered in a textbox and display it in another text box.
I am using the event onBlur.
Initially i got NaN in the result textbox.
Later I used ParseInt now no value is getting displayed.
My code :
<script type="text/javascript">
function countRows(){
var rows=document.getElementById("rows");
var startMsisdn=parseInt(document.getElementByName("startmsisdn").value);
var endMsisdn=parseInt(document.getElementByName("endmsisdn").value);
rows.value=endMsisdn-startMsisdn;
}
</script>
HTML CODE :
<div class="col-md-4">
<label>MSISDN Start Range </label> <input class="form-control"
type="text" name="startmsisdn"
placeholder="MSISDN Starting Range" required>
</div>
<div class="col-md-4">
<label>MSISDN End Range </label> <input class="form-control"
type="text" name="endmsisdn" placeholder="MSISDN Ending Range"
required>
</div>
</div>
<br>
<div class="row">
<div class="col-md-4">
<label>IMSI Start Range </label> <input class="form-control"
type="text" name="startimsi" placeholder="IMSI Starting Range"
required>
</div>
<div class="col-md-4">
<label>IMSI End Range </label> <input class="form-control"
type="text" name="endimsi" placeholder="IMSI Ending Range"
required onblur="countRows()">
</div>
<div class="col-md-4">
<label>No of rows </label> <input class="form-control"
type="text" name="rows" id="rows"
required>
</div>
Add default value for empty field
Try to get element by id for input field;
like this
Html
div class="col-md-4">
<label>IMSI Start Range </label>
<input class="form-control"
type="text" id="startimsi" name="startimsi" placeholder="IMSI Starting Range"
required>
</div>
<div class="col-md-4">
<label>IMSI End Range </label>
<input class="form-control"
type="text" id="endimsi" name="endimsi" placeholder="IMSI Ending Range"
required onblur="countRows()">
</div>
Javascript
var startMsisdn=parseInt(document.getElementById("startmsisdn").value) || 0;
var endMsisdn=parseInt(document.getElementById("endmsisdn").value) || 0;
You have two issues here. parseInt may return NaN, so any value you add to it will also always return NaN. The second issue is there is no getElementByName method (singular). It's getElementsByName which returns an array-like object:
function countRows(){
var rows=document.getElementById("rows");
var startMsisdn=parseInt(document.getElementsByName("startmsisdn")[0].value, 10) || 0;
var endMsisdn=parseInt(document.getElementsByName("endmsisdn")[0].value, 10) || 0;
rows.value=endMsisdn-startMsisdn;
}
You may notice that I added an extra parameter to your parseInt too. This is to force non-ES5 compliant browsers to parse as decimal - they may default to using octal for parsing which will result in unexpected results if a zero-prefixed value is entered.
Working Example
function countRows(){
var rows=document.getElementById("rows");
var startMsisdn=parseInt(document.getElementsByName("startmsisdn")[0].value, 10) || 0;
var endMsisdn=parseInt(document.getElementsByName("endmsisdn")[0].value, 10) || 0;
rows.value=endMsisdn-startMsisdn;
}
<div class="col-md-4">
<label>MSISDN Start Range </label>
<input class="form-control" type="text" name="startmsisdn" placeholder="MSISDN Starting Range" required>
</div>
<div class="col-md-4">
<label>MSISDN End Range </label>
<input class="form-control" type="text" name="endmsisdn" placeholder="MSISDN Ending Range" required>
</div>
<br>
<div class="row">
<div class="col-md-4">
<label>IMSI Start Range </label>
<input class="form-control" type="text" name="startimsi" placeholder="IMSI Starting Range" required>
</div>
<div class="col-md-4">
<label>IMSI End Range </label>
<input class="form-control" type="text" name="endimsi" placeholder="IMSI Ending Range" required onblur="countRows()">
</div>
<div class="col-md-4">
<label>No of rows </label>
<input class="form-control" type="text" name="rows" id="rows" required>
</div>
</div>
try this by replacing NaN with 0 ..
function countRows(){
var rows = document.getElementById("rows");
var startMsisdn=document.getElementById("startmsisdn").value;
if(startMsisdn =='' ){ startMsisdn =0;}
var endMsisdn=document.getElementById("endmsisdn").value;
if(endMsisdn =='' ){ endMsisdn =0;}
rows.value= parseInt(endMsisdn) - parseInt(startMsisdn);
}
HERE is the FIDDLE
Add These line of code in script its will work fine.
function countRows() {
var rows = document.getElementById("rows");
var startMsisdn = parseInt(document.getElementsByName("startmsisdn")[0].value);
var endMsisdn = parseInt(document.getElementsByName("endmsisdn")[0].value);
rows.value = endMsisdn - startMsisdn;
}

Categories

Resources